From eb63f80a7e9d178d73c815cc2109d7a55953db91 Mon Sep 17 00:00:00 2001 From: Francis Russell Date: Tue, 7 Aug 2012 17:59:46 +0100 Subject: [PATCH] Add generated vector Laplacian headers. --- .../vector_laplacian_f1_p1_q1_excafe.h | 117 + .../vector_laplacian_f1_p1_q1_quadrature.h | 3258 +++ .../vector_laplacian_f1_p1_q1_tensor.h | 3230 ++ .../vector_laplacian_f1_p1_q2_excafe.h | 230 + .../vector_laplacian_f1_p1_q2_quadrature.h | 8464 ++++++ .../vector_laplacian_f1_p1_q2_tensor.h | 8518 ++++++ .../vector_laplacian_f1_p1_q3_excafe.h | 518 + .../vector_laplacian_f1_p1_q3_quadrature.h | 12069 ++++++++ .../vector_laplacian_f1_p1_q3_tensor.h | 12370 ++++++++ .../vector_laplacian_f1_p1_q4_excafe.h | 1108 + .../vector_laplacian_f1_p1_q4_quadrature.h | 17646 +++++++++++ .../vector_laplacian_f1_p1_q4_tensor.h | 18429 ++++++++++++ .../vector_laplacian_f1_p2_q1_excafe.h | 136 + .../vector_laplacian_f1_p2_q1_quadrature.h | 8453 ++++++ .../vector_laplacian_f1_p2_q1_tensor.h | 8442 ++++++ .../vector_laplacian_f1_p2_q2_excafe.h | 455 + .../vector_laplacian_f1_p2_q2_quadrature.h | 5541 ++++ .../vector_laplacian_f1_p2_q2_tensor.h | 5654 ++++ .../vector_laplacian_f1_p2_q3_excafe.h | 874 + .../vector_laplacian_f1_p2_q3_quadrature.h | 14349 +++++++++ .../vector_laplacian_f1_p2_q3_tensor.h | 14686 ++++++++++ .../vector_laplacian_f1_p2_q4_excafe.h | 1684 ++ .../vector_laplacian_f1_p2_q4_quadrature.h | 19944 +++++++++++++ .../vector_laplacian_f1_p2_q4_tensor.h | 20745 +++++++++++++ .../vector_laplacian_f1_p3_q1_excafe.h | 128 + .../vector_laplacian_f1_p3_q1_quadrature.h | 12060 ++++++++ .../vector_laplacian_f1_p3_q1_tensor.h | 12070 ++++++++ .../vector_laplacian_f1_p3_q2_excafe.h | 666 + .../vector_laplacian_f1_p3_q2_quadrature.h | 14345 +++++++++ .../vector_laplacian_f1_p3_q2_tensor.h | 14494 +++++++++ .../vector_laplacian_f1_p3_q3_excafe.h | 1505 + .../vector_laplacian_f1_p3_q3_quadrature.h | 9149 ++++++ .../vector_laplacian_f1_p3_q3_tensor.h | 9570 ++++++ .../vector_laplacian_f1_p3_q4_excafe.h | 2377 ++ .../vector_laplacian_f1_p3_q4_quadrature.h | 23576 +++++++++++++++ .../vector_laplacian_f1_p3_q4_tensor.h | 24405 ++++++++++++++++ .../vector_laplacian_f2_p1_q1_excafe.h | 184 + .../vector_laplacian_f2_p1_q1_quadrature.h | 3294 +++ .../vector_laplacian_f2_p1_q1_tensor.h | 3464 +++ .../vector_laplacian_f2_p1_q2_excafe.h | 315 + .../vector_laplacian_f2_p1_q2_quadrature.h | 8500 ++++++ .../vector_laplacian_f2_p1_q2_tensor.h | 8752 ++++++ .../vector_laplacian_f2_p1_q3_excafe.h | 572 + .../vector_laplacian_f2_p1_q3_quadrature.h | 12105 ++++++++ .../vector_laplacian_f2_p1_q3_tensor.h | 12604 ++++++++ .../vector_laplacian_f2_p1_q4_excafe.h | 1226 + .../vector_laplacian_f2_p1_q4_quadrature.h | 17682 +++++++++++ .../vector_laplacian_f2_p1_q4_tensor.h | 18663 ++++++++++++ .../vector_laplacian_f2_p2_q1_excafe.h | 309 + .../vector_laplacian_f2_p2_q1_quadrature.h | 8500 ++++++ .../vector_laplacian_f2_p2_q1_tensor.h | 9412 ++++++ 51 files changed, 416847 insertions(+) create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q1_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q1_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q1_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q2_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q2_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q2_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q3_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q3_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q3_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q4_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q4_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p1_q4_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q1_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q1_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q1_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q2_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q2_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q2_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q3_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q3_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q3_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q4_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q4_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p2_q4_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q1_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q1_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q1_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q2_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q2_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q2_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q3_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q3_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q3_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q4_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q4_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f1_p3_q4_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q1_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q1_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q1_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q2_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q2_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q2_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q3_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q3_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q3_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q4_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q4_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p1_q4_tensor.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p2_q1_excafe.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p2_q1_quadrature.h create mode 100644 vector_laplacian_2d/vector_laplacian_f2_p2_q1_tensor.h diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q1_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q1_excafe.h new file mode 100644 index 0000000..cdf40ce --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q1_excafe.h @@ -0,0 +1,117 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.69 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][0]; + const double var_1 = x[1][0] + var_0; + const double var_2 = x[2][0] + var_0; + const double var_3 = -x[0][1]; + const double var_4 = x[1][1] + var_3; + const double var_5 = var_2*w[0][4] + var_4*w[0][2]; + const double var_6 = x[2][1] + var_3; + const double var_7 = var_1*w[0][5] + var_6*w[0][1]; + const double var_8 = var_5 + -var_7; + const double var_9 = -var_4 + var_6; + const double var_10 = var_8 + var_9*w[0][0]; + const double var_11 = var_1*w[0][3] + var_10; + A[17] = 0.0000000000000000000000000; + const double var_12 = -var_2*var_4 + var_1*var_6; + const double var_13 = var_12; + const double var_14 = std::abs(var_13); + const double var_15 = -var_2 + var_1; + const double var_16 = var_15*w[0][3]; + const double var_17 = var_8 + var_16; + const double var_18 = var_12; + const double var_19 = var_4*var_6 + var_1*var_2; + const double var_20 = var_10 + var_16; + A[8] = 0.5000000000000000000000000*var_14*var_19*var_20/(var_18*var_18*var_18); + A[34] = A[8]; + A[24] = 0.0000000000000000000000000; + A[32] = 0.0000000000000000000000000; + const double var_21 = -var_5 + var_7; + const double var_22 = -var_6*w[0][0] + var_21; + const double var_23 = -var_1*w[0][3] + var_4*w[0][0]; + const double var_24 = var_2*w[0][3]; + const double var_25 = var_23 + var_24; + const double var_26 = var_25 + var_22; + const double var_27 = var_2*var_2; + const double var_28 = var_6*var_6 + var_27; + A[7] = 0.5000000000000000000000000*var_14*var_26*var_28/(var_18*var_18*var_18); + const double var_29 = var_1*var_1 + var_4*var_4; + A[14] = 0.5000000000000000000000000*var_14*var_26*var_29/(var_18*var_18*var_18); + const double var_30 = var_22 + var_24; + const double var_31 = var_22 + var_23; + A[4] = 0.0000000000000000000000000; + A[13] = A[8]; + A[28] = A[7]; + A[9] = 0.0000000000000000000000000; + const double var_32 = var_1*var_31; + const double var_33 = var_25 + var_21; + const double var_34 = var_33*var_4; + A[30] = 0.0000000000000000000000000; + const double var_35 = var_6*w[0][0] + var_17; + const double var_36 = var_35*var_6 + var_34; + const double var_37 = -var_2*w[0][3] + var_10; + const double var_38 = var_2*var_37 + var_32; + const double var_39 = var_36*var_6 + var_2*var_38; + const double var_40 = var_1*var_2*var_2*w[0][3] + 0.5000000000000000000000000*var_39 + -var_4*var_6*var_6*w[0][0]; + A[1] = var_14*var_40/(var_18*var_18*var_18); + A[27] = A[1]; + const double var_41 = -var_1*var_6*w[0][3]; + const double var_42 = -var_4*w[0][0] + var_17; + const double var_43 = var_41 + var_1*var_2*w[0][0] + var_4*var_42; + const double var_44 = var_4*var_43 + var_19*var_30 + var_1*var_1*var_11; + const double var_45 = -var_1*var_1*var_2*w[0][3] + var_4*var_4*var_6*w[0][0] + 0.5000000000000000000000000*var_44; + A[2] = var_14*var_45/(var_18*var_18*var_18); + A[12] = A[2]; + const double var_46 = 3.0000000000000000000000000*var_15*var_2*w[0][3] + var_32; + const double var_47 = 3.0000000000000000000000000*var_6*var_9 + var_27; + const double var_48 = var_47*w[0][0] + var_34; + const double var_49 = var_1*var_46 + var_28*var_30 + var_4*var_48 + var_41*var_6; + const double var_50 = var_1*var_10*var_2 + 0.5000000000000000000000000*var_49 + var_17*var_4*var_6; + A[0] = var_14*var_50/(var_18*var_18*var_18); + A[15] = 0.0000000000000000000000000; + A[22] = A[1]; + A[33] = A[2]; + A[6] = A[1]; + A[29] = A[8]; + A[20] = 0.0000000000000000000000000; + A[5] = 0.0000000000000000000000000; + A[26] = 0.0000000000000000000000000; + A[3] = 0.0000000000000000000000000; + A[16] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[11] = 0.0000000000000000000000000; + A[19] = 0.0000000000000000000000000; + A[10] = 0.0000000000000000000000000; + A[21] = A[0]; + A[35] = A[14]; + A[25] = 0.0000000000000000000000000; + A[23] = A[2]; + A[31] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q1_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q1_quadrature.h new file mode 100644 index 0000000..9aa25d9 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q1_quadrature.h @@ -0,0 +1,3258 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P1_Q1_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P1_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q1_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q1_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q1_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q1_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p1_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W1 = 0.5; + // Quadrature points on the UFC reference element: (0.333333333333333, 0.333333333333333) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[1][2] = \ + {{-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 72. + double G[12]; + G[0] = K_00*W1*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*W1*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*W1*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*W1*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*W1*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*W1*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*W1*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*W1*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*W1*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*W1*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*W1*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*W1*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 133 + // Only 1 integration point, omitting IP loop. + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 16 + for (unsigned int r = 0; r < 2; r++) + { + F0 += FE0_C0_D01[0][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[0][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D01[0][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[0][r]*w[0][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 21 + double I[3]; + // Number of operations: 7 + I[0] = (F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 7 + I[1] = (F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 7 + I[2] = (F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 96 + for (unsigned int j = 0; j < 2; j++) + { + for (unsigned int k = 0; k < 2; k++) + { + // Number of operations to compute entry: 3 + A[nzc1[j]*6 + nzc1[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc1[j]*6 + nzc2[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*6 + nzc1[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*6 + nzc2[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc4[j]*6 + nzc4[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc4[j]*6 + nzc5[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*6 + nzc4[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*6 + nzc5[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p1_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q1_quadrature_finite_element_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q1_quadrature_finite_element_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q1_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q1_quadrature_dofmap_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q1_quadrature_dofmap_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q1_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q1_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q1_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q1_tensor.h new file mode 100644 index 0000000..f4a9fe9 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q1_tensor.h @@ -0,0 +1,3230 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P1_Q1_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P1_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q1_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q1_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q1_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q1_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p1_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 96 + // Number of operations (multiply-add pairs) for tensor contraction: 78 + // Total number of operations (multiply-add pairs): 185 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0 = det*(w[0][3]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1 = det*(w[0][3]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0 = det*(w[0][4]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1 = det*(w[0][5]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0 = det*(w[0][3]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1 = det*(w[0][3]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0 = det*(w[0][4]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1 = det*(w[0][5]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0 = det*(w[0][3]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1 = det*(w[0][3]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0 = det*(w[0][4]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1 = det*(w[0][5]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0 = det*(w[0][3]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1 = det*(w[0][3]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0 = det*(w[0][4]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1 = det*(w[0][5]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[9] = 0.0; + A[18] = 0.0; + A[20] = 0.0; + A[31] = 0.0; + A[3] = 0.0; + A[17] = 0.0; + A[24] = 0.0; + A[8] = -0.5*G0_0_1_0_0_0 - 0.5*G0_0_1_0_0_1 + 0.5*G0_0_1_1_0_0 + 0.5*G0_0_1_2_0_1 - 0.5*G0_0_1_3_1_0 - 0.5*G0_0_1_3_1_1 + 0.5*G0_0_1_4_1_0 + 0.5*G0_0_1_5_1_1; + A[28] = -0.5*G0_0_0_0_0_0 - 0.5*G0_0_0_0_0_1 + 0.5*G0_0_0_1_0_0 + 0.5*G0_0_0_2_0_1 - 0.5*G0_0_0_3_1_0 - 0.5*G0_0_0_3_1_1 + 0.5*G0_0_0_4_1_0 + 0.5*G0_0_0_5_1_1; + A[11] = 0.0; + A[30] = 0.0; + A[4] = 0.0; + A[25] = 0.0; + A[7] = A[28]; + A[34] = -0.5*G0_1_0_0_0_0 - 0.5*G0_1_0_0_0_1 + 0.5*G0_1_0_1_0_0 + 0.5*G0_1_0_2_0_1 - 0.5*G0_1_0_3_1_0 - 0.5*G0_1_0_3_1_1 + 0.5*G0_1_0_4_1_0 + 0.5*G0_1_0_5_1_1; + A[13] = A[34]; + A[33] = -A[34] + 0.5*G0_1_1_0_0_0 + 0.5*G0_1_1_0_0_1 - 0.5*G0_1_1_1_0_0 - 0.5*G0_1_1_2_0_1 + 0.5*G0_1_1_3_1_0 + 0.5*G0_1_1_3_1_1 - 0.5*G0_1_1_4_1_0 - 0.5*G0_1_1_5_1_1; + A[1] = -A[34] + 0.5*G0_0_0_0_0_0 + 0.5*G0_0_0_0_0_1 - 0.5*G0_0_0_1_0_0 - 0.5*G0_0_0_2_0_1 + 0.5*G0_0_0_3_1_0 + 0.5*G0_0_0_3_1_1 - 0.5*G0_0_0_4_1_0 - 0.5*G0_0_0_5_1_1; + A[29] = A[8]; + A[14] = -0.5*G0_1_1_0_0_0 - 0.5*G0_1_1_0_0_1 + 0.5*G0_1_1_1_0_0 + 0.5*G0_1_1_2_0_1 - 0.5*G0_1_1_3_1_0 - 0.5*G0_1_1_3_1_1 + 0.5*G0_1_1_4_1_0 + 0.5*G0_1_1_5_1_1; + A[10] = 0.0; + A[5] = 0.0; + A[26] = 0.0; + A[6] = -A[8] + 0.5*G0_0_0_0_0_0 + 0.5*G0_0_0_0_0_1 - 0.5*G0_0_0_1_0_0 - 0.5*G0_0_0_2_0_1 + 0.5*G0_0_0_3_1_0 + 0.5*G0_0_0_3_1_1 - 0.5*G0_0_0_4_1_0 - 0.5*G0_0_0_5_1_1; + A[35] = A[14]; + A[23] = -A[8] + 0.5*G0_1_1_0_0_0 + 0.5*G0_1_1_0_0_1 - 0.5*G0_1_1_1_0_0 - 0.5*G0_1_1_2_0_1 + 0.5*G0_1_1_3_1_0 + 0.5*G0_1_1_3_1_1 - 0.5*G0_1_1_4_1_0 - 0.5*G0_1_1_5_1_1; + A[21] = -A[23] - 0.5*G0_0_0_0_0_0 - 0.5*G0_0_0_0_0_1 + 0.5*G0_0_0_1_0_0 + 0.5*G0_0_0_2_0_1 - 0.5*G0_0_0_3_1_0 - 0.5*G0_0_0_3_1_1 + 0.5*G0_0_0_4_1_0 + 0.5*G0_0_0_5_1_1 - 0.5*G0_1_0_0_0_0 - 0.5*G0_1_0_0_0_1 + 0.5*G0_1_0_1_0_0 + 0.5*G0_1_0_2_0_1 - 0.5*G0_1_0_3_1_0 - 0.5*G0_1_0_3_1_1 + 0.5*G0_1_0_4_1_0 + 0.5*G0_1_0_5_1_1; + A[0] = A[21]; + A[22] = A[1]; + A[19] = 0.0; + A[16] = 0.0; + A[12] = A[33]; + A[27] = A[6]; + A[15] = 0.0; + A[32] = 0.0; + A[2] = A[23]; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p1_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q1_tensor_finite_element_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q1_tensor_finite_element_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q1_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q1_tensor_dofmap_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q1_tensor_dofmap_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q1_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q1_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q2_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q2_excafe.h new file mode 100644 index 0000000..f593f9f --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q2_excafe.h @@ -0,0 +1,230 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 2.37 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + A[69] = 0.0000000000000000000000000; + const double var_0 = -x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -x[0][0]; + const double var_3 = x[1][0] + var_2; + const double var_4 = x[1][1] + var_0; + const double var_5 = x[2][0] + var_2; + const double var_6 = var_1*var_3 + -var_4*var_5; + const double var_7 = var_6; + const double var_8 = std::abs(var_7); + const double var_9 = var_6; + const double var_10 = var_3*var_5 + var_1*var_4; + const double var_11 = var_3*w[0][5] + var_1*w[0][1]; + const double var_12 = var_4*w[0][2] + var_5*w[0][4]; + const double var_13 = -var_11 + var_12; + const double var_14 = -var_5*w[0][3] + var_13; + const double var_15 = var_3*w[0][3] + var_14; + const double var_16 = -var_4; + const double var_17 = var_1 + var_16; + const double var_18 = var_17*w[0][0]; + const double var_19 = var_15 + var_18; + A[15] = 0.6666666666666666296592325*var_10*var_19*var_8/(var_9*var_9*var_9); + A[37] = A[15]; + A[46] = 0.0000000000000000000000000; + A[73] = 0.0000000000000000000000000; + const double var_20 = var_11 + -var_12; + const double var_21 = -var_3*w[0][3] + var_20; + const double var_22 = -var_1*w[0][0] + var_5*w[0][3]; + const double var_23 = var_21 + var_22; + const double var_24 = var_4*w[0][0]; + const double var_25 = var_23 + var_24; + const double var_26 = var_3*var_3 + var_4*var_4; + A[26] = 0.5000000000000000000000000*var_25*var_26*var_8/(var_9*var_9*var_9); + A[104] = A[26]; + A[14] = 0.1666666666666666574148081*var_10*var_25*var_8/(var_9*var_9*var_9); + A[25] = A[14]; + const double var_27 = var_13 + var_18; + const double var_28 = var_21 + var_24; + const double var_29 = -var_1*var_3*var_3*w[0][0] + var_26*var_28 + var_4*var_4*var_5*w[0][3]; + const double var_30 = var_22 + var_20 + var_24; + const double var_31 = -var_3*var_5*var_5*w[0][3]; + const double var_32 = var_3*var_3*var_5*w[0][3]; + const double var_33 = var_31 + var_1*var_17*var_4*w[0][0] + var_32; + const double var_34 = 3.0000000000000000000000000*var_33 + var_30*var_5*var_5 + var_29 + var_1*var_1*var_23; + const double var_35 = var_27*var_3*var_5 + var_1*var_15*var_4 + 0.5000000000000000000000000*var_34; + A[0] = var_35*var_8/(var_9*var_9*var_9); + A[78] = A[0]; + A[20] = 0.0000000000000000000000000; + A[100] = 0.0000000000000000000000000; + A[132] = 0.0000000000000000000000000; + A[81] = 0.0000000000000000000000000; + A[127] = 0.0000000000000000000000000; + const double var_36 = 2.0000000000000000000000000*var_3*w[0][3] + var_14 + var_18; + const double var_37 = var_1*var_15 + -var_3*var_5*w[0][0]; + const double var_38 = var_1 + -2.0000000000000000000000000*var_4; + const double var_39 = var_4*var_5*w[0][3] + var_37 + var_1*var_38*w[0][0]; + const double var_40 = var_10*var_28 + var_36*var_5*var_5 + var_1*var_39; + A[5] = 0.6666666666666666296592325*var_40*var_8/(var_9*var_9*var_9); + A[83] = A[5]; + const double var_41 = -var_1*var_4*var_4*w[0][0] + var_32; + const double var_42 = var_29 + var_1*var_10*w[0][0] + var_37*var_4 + var_14*var_3*var_5; + const double var_43 = var_41 + 0.5000000000000000000000000*var_42; + A[2] = 0.3333333333333333148296163*var_43*var_8/(var_9*var_9*var_9); + const double var_44 = 2.0000000000000000000000000*var_1 + var_16; + A[139] = A[5]; + A[55] = 0.0000000000000000000000000; + A[40] = 1.3333333333333332593184650*var_40*var_8/(var_9*var_9*var_9); + A[45] = 0.0000000000000000000000000; + A[61] = A[5]; + A[112] = 0.0000000000000000000000000; + A[136] = 0.0000000000000000000000000; + A[53] = 1.3333333333333332593184650*var_10*var_19*var_8/(var_9*var_9*var_9); + A[142] = A[53]; + A[124] = 0.0000000000000000000000000; + const double var_45 = var_15*var_4 + var_1*var_23; + const double var_46 = var_4*var_44*w[0][0] + var_45; + const double var_47 = var_3 + -2.0000000000000000000000000*var_5; + A[125] = 0.0000000000000000000000000; + const double var_48 = var_5*var_5 + var_1*var_1; + A[13] = 0.5000000000000000000000000*var_25*var_48*var_8/(var_9*var_9*var_9); + A[57] = 0.0000000000000000000000000; + A[129] = A[40]; + const double var_49 = var_30*var_5 + var_27*var_3; + const double var_50 = var_49 + var_3*var_47*w[0][3]; + const double var_51 = var_4*var_46 + var_3*var_50; + A[41] = 1.3333333333333332593184650*var_51*var_8/(var_9*var_9*var_9); + A[141] = A[41]; + const double var_52 = var_49*var_5 + var_1*var_45; + const double var_53 = var_41 + var_52; + A[49] = 0.0000000000000000000000000; + A[99] = 0.0000000000000000000000000; + A[138] = A[5]; + A[71] = 0.0000000000000000000000000; + const double var_54 = var_29 + var_52 + 2.0000000000000000000000000*var_33; + A[39] = 1.3333333333333332593184650*var_54*var_8/(var_9*var_9*var_9); + A[52] = A[39]; + A[34] = 0.0000000000000000000000000; + const double var_55 = var_31 + var_1*var_1*var_4*w[0][0] + 0.5000000000000000000000000*var_53; + A[96] = 0.0000000000000000000000000; + A[1] = 0.3333333333333333148296163*var_55*var_8/(var_9*var_9*var_9); + A[79] = A[1]; + A[103] = A[14]; + A[24] = A[2]; + A[113] = 0.0000000000000000000000000; + A[114] = 0.0000000000000000000000000; + A[75] = 0.0000000000000000000000000; + A[33] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[44] = 0.0000000000000000000000000; + A[4] = 0.6666666666666666296592325*var_51*var_8/(var_9*var_9*var_9); + A[48] = A[4]; + A[123] = 0.0000000000000000000000000; + A[43] = 0.0000000000000000000000000; + A[133] = 0.0000000000000000000000000; + A[23] = 0.0000000000000000000000000; + A[92] = A[14]; + A[19] = 0.0000000000000000000000000; + A[28] = A[4]; + A[116] = A[15]; + A[115] = A[15]; + A[101] = 0.0000000000000000000000000; + A[117] = A[39]; + A[8] = 0.0000000000000000000000000; + A[76] = 0.0000000000000000000000000; + A[30] = 0.0000000000000000000000000; + A[9] = 0.0000000000000000000000000; + A[66] = 0.0000000000000000000000000; + A[7] = 0.0000000000000000000000000; + A[122] = 0.0000000000000000000000000; + A[68] = 0.0000000000000000000000000; + A[31] = 0.0000000000000000000000000; + A[80] = A[2]; + A[58] = 0.0000000000000000000000000; + A[60] = A[5]; + A[77] = 0.0000000000000000000000000; + A[27] = A[15]; + A[120] = 0.0000000000000000000000000; + A[108] = 0.0000000000000000000000000; + A[50] = A[4]; + A[87] = 0.0000000000000000000000000; + A[105] = A[15]; + A[67] = 0.0000000000000000000000000; + A[12] = A[1]; + A[11] = 0.0000000000000000000000000; + A[32] = 0.0000000000000000000000000; + A[88] = 0.0000000000000000000000000; + A[126] = A[4]; + A[59] = 0.0000000000000000000000000; + A[106] = A[4]; + A[10] = 0.0000000000000000000000000; + A[140] = 0.0000000000000000000000000; + A[102] = A[2]; + A[130] = A[39]; + A[90] = A[1]; + A[119] = A[41]; + A[63] = A[41]; + A[135] = 0.0000000000000000000000000; + A[93] = A[15]; + A[91] = A[13]; + A[70] = 0.0000000000000000000000000; + A[22] = 0.0000000000000000000000000; + A[65] = A[39]; + A[143] = A[39]; + A[98] = 0.0000000000000000000000000; + A[107] = 0.0000000000000000000000000; + A[29] = 0.0000000000000000000000000; + A[89] = 0.0000000000000000000000000; + A[62] = 0.0000000000000000000000000; + A[42] = 0.0000000000000000000000000; + A[17] = A[5]; + A[85] = 0.0000000000000000000000000; + A[95] = A[5]; + A[47] = 0.0000000000000000000000000; + A[109] = 0.0000000000000000000000000; + A[6] = 0.0000000000000000000000000; + A[54] = 0.0000000000000000000000000; + A[118] = A[40]; + A[110] = 0.0000000000000000000000000; + A[16] = 0.0000000000000000000000000; + A[21] = 0.0000000000000000000000000; + A[86] = 0.0000000000000000000000000; + A[38] = A[15]; + A[3] = 0.0000000000000000000000000; + A[111] = 0.0000000000000000000000000; + A[35] = 0.0000000000000000000000000; + A[128] = A[4]; + A[82] = A[4]; + A[84] = 0.0000000000000000000000000; + A[137] = 0.0000000000000000000000000; + A[36] = 0.0000000000000000000000000; + A[56] = 0.0000000000000000000000000; + A[64] = A[53]; + A[97] = 0.0000000000000000000000000; + A[72] = 0.0000000000000000000000000; + A[134] = 0.0000000000000000000000000; + A[131] = A[53]; + A[121] = 0.0000000000000000000000000; + A[74] = 0.0000000000000000000000000; + A[94] = 0.0000000000000000000000000; + A[51] = A[40]; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q2_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q2_quadrature.h new file mode 100644 index 0000000..df35644 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q2_quadrature.h @@ -0,0 +1,8464 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P1_Q2_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P1_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q2_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q2_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q2_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q2_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q2_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q2_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q2_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q2_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q2_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p1_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W3[3] = {0.166666666666667, 0.166666666666667, 0.166666666666667}; + // Quadrature points on the UFC reference element: (0.166666666666667, 0.166666666666667), (0.166666666666667, 0.666666666666667), (0.666666666666667, 0.166666666666667) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[3][2] = \ + {{-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + static const double FE1_C0_D01[3][5] = \ + {{-1.66666666666667, -0.333333333333333, 0.666666666666666, 2.0, -0.666666666666666}, + {0.333333333333333, 1.66666666666667, 0.666666666666666, -2, -0.666666666666666}, + {0.333333333333333, -0.333333333333333, 2.66666666666666, 0.0, -2.66666666666667}}; + + // Array of non-zero columns + static const unsigned int nzc10[5] = {6, 8, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc7[5] = {0, 2, 3, 4, 5}; + + static const double FE1_C0_D10[3][5] = \ + {{-1.66666666666667, -0.333333333333334, 0.666666666666666, -0.666666666666666, 2.0}, + {0.333333333333334, -0.333333333333334, 2.66666666666667, -2.66666666666667, 0.0}, + {0.333333333333333, 1.66666666666667, 0.666666666666666, -0.666666666666666, -2.0}}; + + // Array of non-zero columns + static const unsigned int nzc11[5] = {6, 7, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc8[5] = {0, 1, 3, 4, 5}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 144; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 60. + double G[12]; + G[0] = K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 1920 + for (unsigned int ip = 0; ip < 3; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 16 + for (unsigned int r = 0; r < 2; r++) + { + F0 += FE0_C0_D01[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D01[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 24 + double I[3]; + // Number of operations: 8 + I[0] = W3[ip]*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 8 + I[1] = W3[ip]*(F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 8 + I[2] = W3[ip]*(F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 600 + for (unsigned int j = 0; j < 5; j++) + { + for (unsigned int k = 0; k < 5; k++) + { + // Number of operations to compute entry: 3 + A[nzc10[j]*12 + nzc10[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc10[j]*12 + nzc11[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*12 + nzc10[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*12 + nzc11[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc7[j]*12 + nzc7[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc7[j]*12 + nzc8[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*12 + nzc7[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*12 + nzc8[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p1_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q2_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q2_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q2_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q2_tensor.h new file mode 100644 index 0000000..ccef3ee --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q2_tensor.h @@ -0,0 +1,8518 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P1_Q2_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P1_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q2_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q2_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q2_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q2_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q2_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q2_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q2_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q2_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q2_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p1_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 96 + // Number of operations (multiply-add pairs) for tensor contraction: 121 + // Total number of operations (multiply-add pairs): 228 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0 = det*(w[0][3]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1 = det*(w[0][3]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0 = det*(w[0][4]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1 = det*(w[0][5]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0 = det*(w[0][3]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1 = det*(w[0][3]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0 = det*(w[0][4]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1 = det*(w[0][5]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0 = det*(w[0][3]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1 = det*(w[0][3]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0 = det*(w[0][4]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1 = det*(w[0][5]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0 = det*(w[0][3]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1 = det*(w[0][3]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0 = det*(w[0][4]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1 = det*(w[0][5]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[87] = 0.0; + A[81] = 0.0; + A[7] = 0.0; + A[18] = 0.0; + A[10] = 0.0; + A[43] = 0.0; + A[29] = 0.0; + A[23] = 0.0; + A[101] = 0.0; + A[68] = 0.0; + A[108] = 0.0; + A[137] = 0.0; + A[127] = 0.0; + A[13] = -0.5*G0_0_0_0_0_0 - 0.5*G0_0_0_0_0_1 + 0.5*G0_0_0_1_0_0 + 0.5*G0_0_0_2_0_1 - 0.5*G0_0_0_3_1_0 - 0.5*G0_0_0_3_1_1 + 0.5*G0_0_0_4_1_0 + 0.5*G0_0_0_5_1_1; + A[58] = 0.0; + A[38] = -0.666666666666666*G0_0_1_0_0_0 - 0.666666666666666*G0_0_1_0_0_1 + 0.666666666666666*G0_0_1_1_0_0 + 0.666666666666666*G0_0_1_2_0_1 - 0.666666666666666*G0_0_1_3_1_0 - 0.666666666666666*G0_0_1_3_1_1 + 0.666666666666666*G0_0_1_4_1_0 + 0.666666666666666*G0_0_1_5_1_1; + A[128] = -A[38] + 0.666666666666666*G0_1_1_0_0_0 + 0.666666666666666*G0_1_1_0_0_1 - 0.666666666666666*G0_1_1_1_0_0 - 0.666666666666666*G0_1_1_2_0_1 + 0.666666666666666*G0_1_1_3_1_0 + 0.666666666666666*G0_1_1_3_1_1 - 0.666666666666666*G0_1_1_4_1_0 - 0.666666666666666*G0_1_1_5_1_1; + A[82] = A[128]; + A[4] = A[128]; + A[30] = 0.0; + A[98] = 0.0; + A[71] = 0.0; + A[53] = A[38] - 0.666666666666667*G0_1_0_0_0_0 - 0.666666666666667*G0_1_0_0_0_1 + 0.666666666666667*G0_1_0_1_0_0 + 0.666666666666667*G0_1_0_2_0_1 - 0.666666666666667*G0_1_0_3_1_0 - 0.666666666666667*G0_1_0_3_1_1 + 0.666666666666667*G0_1_0_4_1_0 + 0.666666666666667*G0_1_0_5_1_1; + A[111] = 0.0; + A[72] = 0.0; + A[132] = 0.0; + A[89] = 0.0; + A[37] = -0.666666666666666*G0_1_0_0_0_0 - 0.666666666666666*G0_1_0_0_0_1 + 0.666666666666666*G0_1_0_1_0_0 + 0.666666666666666*G0_1_0_2_0_1 - 0.666666666666666*G0_1_0_3_1_0 - 0.666666666666666*G0_1_0_3_1_1 + 0.666666666666666*G0_1_0_4_1_0 + 0.666666666666666*G0_1_0_5_1_1; + A[48] = -A[37] + 0.666666666666667*G0_1_1_0_0_0 + 0.666666666666667*G0_1_1_0_0_1 - 0.666666666666667*G0_1_1_1_0_0 - 0.666666666666667*G0_1_1_2_0_1 + 0.666666666666667*G0_1_1_3_1_0 + 0.666666666666667*G0_1_1_3_1_1 - 0.666666666666667*G0_1_1_4_1_0 - 0.666666666666667*G0_1_1_5_1_1; + A[35] = 0.0; + A[92] = -0.25*A[38]; + A[90] = -A[92] - 0.166666666666667*G0_0_0_0_0_0 - 0.166666666666667*G0_0_0_0_0_1 + 0.166666666666667*G0_0_0_1_0_0 + 0.166666666666667*G0_0_0_2_0_1 - 0.166666666666667*G0_0_0_3_1_0 - 0.166666666666667*G0_0_0_3_1_1 + 0.166666666666667*G0_0_0_4_1_0 + 0.166666666666667*G0_0_0_5_1_1; + A[47] = 0.0; + A[25] = -0.25*A[37]; + A[79] = -A[25] - 0.166666666666667*G0_0_0_0_0_0 - 0.166666666666667*G0_0_0_0_0_1 + 0.166666666666667*G0_0_0_1_0_0 + 0.166666666666667*G0_0_0_2_0_1 - 0.166666666666667*G0_0_0_3_1_0 - 0.166666666666667*G0_0_0_3_1_1 + 0.166666666666667*G0_0_0_4_1_0 + 0.166666666666667*G0_0_0_5_1_1; + A[1] = A[79]; + A[105] = A[37]; + A[112] = 0.0; + A[61] = -4*A[79]; + A[123] = 0.0; + A[86] = 0.0; + A[142] = A[53]; + A[17] = -4.0*A[90]; + A[11] = 0.0; + A[42] = 0.0; + A[26] = -0.5*G0_1_1_0_0_0 - 0.5*G0_1_1_0_0_1 + 0.5*G0_1_1_1_0_0 + 0.5*G0_1_1_2_0_1 - 0.5*G0_1_1_3_1_0 - 0.5*G0_1_1_3_1_1 + 0.5*G0_1_1_4_1_0 + 0.5*G0_1_1_5_1_1; + A[22] = 0.0; + A[102] = -0.25*A[48]; + A[49] = 0.0; + A[129] = -A[53] + 1.33333333333333*G0_0_0_0_0_0 + 1.33333333333333*G0_0_0_0_0_1 - 1.33333333333333*G0_0_0_1_0_0 - 1.33333333333333*G0_0_0_2_0_1 + 1.33333333333333*G0_0_0_3_1_0 + 1.33333333333333*G0_0_0_3_1_1 - 1.33333333333333*G0_0_0_4_1_0 - 1.33333333333333*G0_0_0_5_1_1; + A[143] = -A[129] - 1.33333333333333*G0_1_1_0_0_0 - 1.33333333333333*G0_1_1_0_0_1 + 1.33333333333333*G0_1_1_1_0_0 + 1.33333333333333*G0_1_1_2_0_1 - 1.33333333333333*G0_1_1_3_1_0 - 1.33333333333333*G0_1_1_3_1_1 + 1.33333333333333*G0_1_1_4_1_0 + 1.33333333333333*G0_1_1_5_1_1; + A[65] = A[143]; + A[117] = A[143]; + A[115] = A[37]; + A[76] = 0.0; + A[64] = A[53]; + A[136] = 0.0; + A[124] = 0.0; + A[85] = 0.0; + A[83] = A[61]; + A[141] = -A[53] + 1.33333333333333*G0_1_1_0_0_0 + 1.33333333333333*G0_1_1_0_0_1 - 1.33333333333333*G0_1_1_1_0_0 - 1.33333333333333*G0_1_1_2_0_1 + 1.33333333333333*G0_1_1_3_1_0 + 1.33333333333333*G0_1_1_3_1_1 - 1.33333333333333*G0_1_1_4_1_0 - 1.33333333333333*G0_1_1_5_1_1; + A[5] = A[61]; + A[12] = A[90]; + A[8] = 0.0; + A[59] = 0.0; + A[41] = A[141]; + A[31] = 0.0; + A[99] = 0.0; + A[70] = 0.0; + A[54] = 0.0; + A[130] = A[143]; + A[110] = 0.0; + A[73] = 0.0; + A[67] = 0.0; + A[135] = 0.0; + A[88] = 0.0; + A[2] = -0.25*A[128]; + A[15] = A[38]; + A[56] = 0.0; + A[36] = 0.0; + A[32] = 0.0; + A[116] = A[38]; + A[96] = 0.0; + A[74] = 0.0; + A[95] = A[17]; + A[46] = 0.0; + A[106] = A[48]; + A[119] = A[141]; + A[60] = A[17]; + A[120] = 0.0; + A[16] = 0.0; + A[45] = 0.0; + A[27] = A[37]; + A[21] = 0.0; + A[103] = A[25]; + A[50] = A[128]; + A[114] = 0.0; + A[77] = 0.0; + A[63] = A[141]; + A[139] = A[61]; + A[125] = 0.0; + A[84] = 0.0; + A[80] = A[2]; + A[140] = 0.0; + A[6] = 0.0; + A[19] = 0.0; + A[9] = 0.0; + A[40] = A[129]; + A[28] = A[48]; + A[100] = 0.0; + A[69] = 0.0; + A[55] = 0.0; + A[131] = A[53]; + A[109] = 0.0; + A[78] = A[13] - 0.5*G0_0_1_0_0_0 - 0.5*G0_0_1_0_0_1 + 0.5*G0_0_1_1_0_0 + 0.5*G0_0_1_2_0_1 - 0.5*G0_0_1_3_1_0 - 0.5*G0_0_1_3_1_1 + 0.5*G0_0_1_4_1_0 + 0.5*G0_0_1_5_1_1 - 0.5*G0_1_0_0_0_0 - 0.5*G0_1_0_0_0_1 + 0.5*G0_1_0_1_0_0 + 0.5*G0_1_0_2_0_1 - 0.5*G0_1_0_3_1_0 - 0.5*G0_1_0_3_1_1 + 0.5*G0_1_0_4_1_0 + 0.5*G0_1_0_5_1_1 - 0.5*G0_1_1_0_0_0 - 0.5*G0_1_1_0_0_1 + 0.5*G0_1_1_1_0_0 + 0.5*G0_1_1_2_0_1 - 0.5*G0_1_1_3_1_0 - 0.5*G0_1_1_3_1_1 + 0.5*G0_1_1_4_1_0 + 0.5*G0_1_1_5_1_1; + A[66] = 0.0; + A[134] = 0.0; + A[126] = A[48]; + A[91] = A[13]; + A[3] = 0.0; + A[14] = A[92]; + A[57] = 0.0; + A[39] = A[143]; + A[33] = 0.0; + A[97] = 0.0; + A[52] = A[143]; + A[75] = 0.0; + A[133] = 0.0; + A[94] = 0.0; + A[0] = A[78]; + A[107] = 0.0; + A[34] = 0.0; + A[118] = A[129]; + A[121] = 0.0; + A[93] = A[38]; + A[44] = 0.0; + A[24] = A[102]; + A[20] = 0.0; + A[104] = A[26]; + A[51] = A[129]; + A[113] = 0.0; + A[62] = 0.0; + A[138] = A[17]; + A[122] = 0.0; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p1_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q2_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q2_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q2_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q3_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q3_excafe.h new file mode 100644 index 0000000..eeeeddb --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q3_excafe.h @@ -0,0 +1,518 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 13.61 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + A[199] = 0.0000000000000000000000000; + A[369] = 0.0000000000000000000000000; + A[13] = 0.0000000000000000000000000; + const double var_0 = -x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -x[0][0]; + const double var_3 = x[1][0] + var_2; + const double var_4 = x[1][1] + var_0; + const double var_5 = x[2][0] + var_2; + const double var_6 = var_5*w[0][4] + var_4*w[0][2]; + const double var_7 = var_3*w[0][5] + var_1*w[0][1]; + const double var_8 = var_6 + -var_7; + const double var_9 = -var_5*w[0][3]; + const double var_10 = var_3*w[0][3]; + const double var_11 = var_9 + var_10 + var_8; + const double var_12 = -var_4*w[0][0]; + const double var_13 = var_1*w[0][0]; + const double var_14 = var_12 + var_8 + var_13; + const double var_15 = var_1*var_11*var_4 + var_14*var_3*var_5; + const double var_16 = var_3*var_3*var_5*w[0][3] + -var_1*var_4*var_4*w[0][0]; + const double var_17 = var_1*var_1*var_4*w[0][0] + -var_3*var_5*var_5*w[0][3]; + const double var_18 = var_16 + var_17; + const double var_19 = var_9 + var_14; + const double var_20 = var_11 + var_13; + const double var_21 = var_19*var_5*var_5 + var_1*var_1*var_20; + const double var_22 = 0.5000000000000000000000000*var_21; + const double var_23 = var_11 + var_12; + const double var_24 = var_14 + var_10; + const double var_25 = var_23*var_4*var_4 + var_24*var_3*var_3; + const double var_26 = 0.5000000000000000000000000*var_25; + const double var_27 = var_22 + var_26; + const double var_28 = 0.5000000000000000000000000*var_18 + var_15 + var_27; + const double var_29 = var_1*var_3 + -var_4*var_5; + const double var_30 = var_29; + const double var_31 = std::abs(var_30); + const double var_32 = var_29; + const double var_33 = -var_6 + var_7; + const double var_34 = -var_1*w[0][0]; + const double var_35 = var_4*w[0][0]; + const double var_36 = var_34 + var_35 + var_33; + const double var_37 = -var_3*w[0][3]; + const double var_38 = var_36 + var_37; + const double var_39 = var_5*w[0][3]; + const double var_40 = var_37 + var_33 + var_39; + const double var_41 = var_40 + var_35; + const double var_42 = var_3*var_3*var_38 + var_4*var_4*var_41; + const double var_43 = -var_1*var_1*var_4*w[0][0] + var_3*var_5*var_5*w[0][3]; + const double var_44 = -var_3*var_3*var_5*w[0][3] + var_1*var_4*var_4*w[0][0]; + const double var_45 = var_1*var_4*var_40 + var_3*var_36*var_5; + const double var_46 = 0.2125000000000000222044605*var_45; + const double var_47 = 0.4375000000000000000000000*var_43 + 0.2250000000000000055511151*var_21 + 0.0125000000000000006938894*var_42 + 0.2000000000000000111022302*var_44 + var_46; + A[7] = 3.0000000000000000000000000*var_31*var_47/(var_32*var_32*var_32); + A[350] = A[7]; + const double var_48 = var_44 + var_26; + const double var_49 = 0.1000000000000000055511151*var_45; + const double var_50 = 0.1250000000000000000000000*var_43 + 0.2000000000000000111022302*var_48 + 0.0250000000000000013877788*var_21 + var_49; + A[106] = 13.5000000000000000000000000*var_31*var_50/(var_32*var_32*var_32); + const double var_51 = var_15 + var_17; + const double var_52 = var_51 + var_42; + const double var_53 = var_16 + 0.5000000000000000000000000*var_52; + A[67] = 0.6750000000000000444089210*var_31*var_53/(var_32*var_32*var_32); + const double var_54 = var_40 + var_34; + const double var_55 = var_36 + var_39; + const double var_56 = var_1*var_1*var_54 + var_5*var_5*var_55; + const double var_57 = var_16 + var_15; + const double var_58 = var_57 + var_56; + const double var_59 = var_17 + 0.5000000000000000000000000*var_58; + A[65] = 0.6750000000000000444089210*var_31*var_59/(var_32*var_32*var_32); + A[103] = A[65]; + A[361] = 0.0000000000000000000000000; + const double var_60 = var_42 + var_56; + const double var_61 = 0.5000000000000000000000000*var_60; + const double var_62 = var_18 + var_61 + 0.5000000000000000000000000*var_15; + A[189] = 8.0999999999999996447286321*var_31*var_62/(var_32*var_32*var_32); + const double var_63 = var_43 + var_22; + const double var_64 = 0.2000000000000000111022302*var_63 + 0.1250000000000000000000000*var_44 + 0.0250000000000000013877788*var_25 + var_49; + A[148] = 13.5000000000000000000000000*var_31*var_64/(var_32*var_32*var_32); + A[63] = 3.3750000000000000000000000*var_31*var_62/(var_32*var_32*var_32); + A[357] = A[63]; + A[135] = 0.0000000000000000000000000; + const double var_65 = var_45 + var_43; + const double var_66 = 0.5000000000000000000000000*var_65 + var_48; + A[89] = 4.0499999999999998223643161*var_31*var_66/(var_32*var_32*var_32); + A[359] = A[89]; + A[96] = 0.0000000000000000000000000; + const double var_67 = var_51 + 2.1250000000000000000000000*var_16 + 1.1250000000000000000000000*var_42; + A[45] = 0.3000000000000000444089210*var_31*var_67/(var_32*var_32*var_32); + A[102] = A[45]; + const double var_68 = var_44 + var_43; + const double var_69 = var_27 + var_45 + 1.5000000000000000000000000*var_68; + A[3] = 0.0750000000000000111022302*var_31*var_69/(var_32*var_32*var_32); + const double var_70 = var_45 + var_44; + const double var_71 = 0.5000000000000000000000000*var_70 + var_63; + A[86] = 3.3750000000000000000000000*var_31*var_71/(var_32*var_32*var_32); + A[296] = A[86]; + A[156] = 0.0000000000000000000000000; + A[2] = 0.1750000000000000166533454*var_31*var_66/(var_32*var_32*var_32); + A[212] = A[2]; + A[133] = 0.0000000000000000000000000; + A[306] = 0.0000000000000000000000000; + const double var_72 = var_17 + 0.0500000000000000027755576*var_56 + 0.9500000000000000666133815*var_57; + A[23] = 0.7500000000000000000000000*var_31*var_72/(var_32*var_32*var_32); + A[61] = A[23]; + A[244] = 0.0000000000000000000000000; + const double var_73 = 0.0500000000000000027755576*var_42 + 0.9500000000000000666133815*var_51 + var_16; + A[44] = 0.7500000000000000000000000*var_31*var_73/(var_32*var_32*var_32); + A[254] = A[44]; + A[206] = 0.0000000000000000000000000; + A[117] = 0.0000000000000000000000000; + A[152] = 0.0000000000000000000000000; + A[246] = 0.0000000000000000000000000; + const double var_74 = var_23 + var_13; + const double var_75 = var_1*var_4 + var_3*var_5; + A[129] = 2.0249999999999999111821580*var_31*var_74*var_75/(var_32*var_32*var_32); + A[169] = A[129]; + A[64] = 0.6750000000000000444089210*var_28*var_31/(var_32*var_32*var_32); + A[293] = A[64]; + A[116] = 0.0000000000000000000000000; + A[125] = A[106]; + A[285] = 0.0000000000000000000000000; + const double var_76 = 0.1250000000000000000000000*var_56 + 0.8750000000000000000000000*var_43 + var_70; + A[24] = 0.3000000000000000444089210*var_31*var_76/(var_32*var_32*var_32); + A[81] = A[24]; + A[173] = 0.0000000000000000000000000; + A[113] = 0.0000000000000000000000000; + A[303] = 0.0000000000000000000000000; + A[294] = A[63]; + A[297] = A[67]; + A[339] = A[129]; + A[299] = A[89]; + A[57] = 0.0000000000000000000000000; + A[368] = 0.0000000000000000000000000; + A[178] = 0.0000000000000000000000000; + A[292] = A[44]; + A[309] = 0.0000000000000000000000000; + A[9] = 0.0000000000000000000000000; + const double var_77 = 18.5000000000000000000000000*var_43 + 9.5000000000000000000000000*var_70 + 9.0000000000000000000000000*var_21; + A[28] = 0.0750000000000000111022302*var_31*var_77/(var_32*var_32*var_32); + A[371] = A[28]; + A[139] = 0.0000000000000000000000000; + A[390] = 0.0000000000000000000000000; + A[167] = A[148]; + const double var_78 = 0.9000000000000000222044605*var_56 + 1.9000000000000001332267630*var_17 + 1.1000000000000000888178420*var_16 + var_15 + 0.1000000000000000055511151*var_42; + A[8] = 0.3750000000000000000000000*var_31*var_78/(var_32*var_32*var_32); + A[218] = A[8]; + A[68] = 3.3750000000000000000000000*var_31*var_66/(var_32*var_32*var_32); + A[163] = A[68]; + A[176] = 0.0000000000000000000000000; + A[207] = 0.0000000000000000000000000; + const double var_79 = var_38 + var_39; + A[108] = 0.3375000000000000222044605*var_31*var_75*var_79/(var_32*var_32*var_32); + A[318] = A[108]; + A[10] = 0.0000000000000000000000000; + A[36] = 0.0000000000000000000000000; + A[234] = A[24]; + A[313] = A[65]; + A[80] = A[3]; + A[17] = 0.0000000000000000000000000; + A[105] = A[63]; + const double var_80 = 0.2000000000000000111022302*var_43 + 0.2250000000000000055511151*var_25 + 0.0125000000000000006938894*var_56 + 0.4375000000000000000000000*var_44 + var_46; + A[5] = 3.0000000000000000000000000*var_31*var_80/(var_32*var_32*var_32); + A[215] = A[5]; + A[77] = 0.0000000000000000000000000; + A[344] = 0.0000000000000000000000000; + const double var_81 = 9.0000000000000000000000000*var_25 + 18.5000000000000000000000000*var_44 + 9.5000000000000000000000000*var_65; + A[367] = 0.0000000000000000000000000; + A[168] = A[63]; + A[326] = 0.0000000000000000000000000; + const double var_82 = var_5*var_5 + var_1*var_1; + A[25] = 0.0375000000000000055511151*var_31*var_74*var_82/(var_32*var_32*var_32); + A[235] = A[25]; + A[138] = 0.0000000000000000000000000; + A[278] = A[68]; + A[73] = 0.0000000000000000000000000; + A[311] = A[25]; + A[221] = 0.0000000000000000000000000; + A[69] = 4.0499999999999998223643161*var_31*var_71/(var_32*var_32*var_32); + A[185] = A[69]; + A[187] = A[89]; + A[267] = 0.0000000000000000000000000; + A[40] = A[2]; + A[305] = 0.0000000000000000000000000; + A[280] = 0.0000000000000000000000000; + A[208] = 0.0000000000000000000000000; + A[21] = 0.4250000000000000444089210*var_31*var_79*var_82/(var_32*var_32*var_32); + A[231] = A[21]; + A[312] = A[45]; + A[321] = 0.0000000000000000000000000; + A[245] = 0.0000000000000000000000000; + A[291] = A[24]; + A[55] = 0.0000000000000000000000000; + A[266] = 0.0000000000000000000000000; + A[225] = 0.0000000000000000000000000; + A[340] = 0.0000000000000000000000000; + const double var_83 = var_4*var_4 + var_3*var_3; + A[47] = 0.0375000000000000055511151*var_31*var_74*var_83/(var_32*var_32*var_32); + A[257] = A[47]; + A[250] = A[2]; + A[248] = 0.0000000000000000000000000; + A[384] = 0.0000000000000000000000000; + const double var_84 = 0.1000000000000000055511151*var_56 + var_15 + 0.9000000000000000222044605*var_42 + 1.1000000000000000888178420*var_17 + 1.9000000000000001332267630*var_16; + A[6] = 0.3750000000000000000000000*var_31*var_84/(var_32*var_32*var_32); + A[330] = A[6]; + A[255] = A[45]; + const double var_85 = 1.1250000000000000000000000*var_56 + var_57 + 2.1250000000000000000000000*var_17; + A[27] = 0.3000000000000000444089210*var_31*var_85/(var_32*var_32*var_32); + A[283] = 0.0000000000000000000000000; + A[227] = 0.0000000000000000000000000; + A[327] = 0.0000000000000000000000000; + A[83] = A[64]; + A[110] = 0.0000000000000000000000000; + A[194] = 0.0000000000000000000000000; + A[380] = 0.0000000000000000000000000; + A[281] = 0.0000000000000000000000000; + A[76] = 0.0000000000000000000000000; + A[216] = A[6]; + A[115] = 0.0000000000000000000000000; + A[136] = 0.0000000000000000000000000; + A[14] = 0.0000000000000000000000000; + A[224] = 0.0000000000000000000000000; + A[100] = A[5]; + A[22] = 0.0875000000000000083266727*var_31*var_74*var_75/(var_32*var_32*var_32); + A[41] = A[22]; + A[258] = A[47]; + A[98] = 0.0000000000000000000000000; + A[302] = 0.0000000000000000000000000; + A[237] = A[27]; + A[322] = 0.0000000000000000000000000; + A[389] = 0.0000000000000000000000000; + A[366] = 0.0000000000000000000000000; + A[193] = 0.0000000000000000000000000; + A[120] = A[6]; + A[209] = 0.0000000000000000000000000; + A[66] = A[65]; + A[1] = 0.1750000000000000166533454*var_31*var_71/(var_32*var_32*var_32); + A[20] = A[1]; + A[183] = A[69]; + A[114] = 0.0000000000000000000000000; + A[279] = A[69]; + A[107] = 1.6875000000000000000000000*var_31*var_74*var_75/(var_32*var_32*var_32); + A[145] = A[107]; + A[157] = 0.0000000000000000000000000; + A[233] = A[23]; + A[370] = A[8]; + A[42] = 0.4250000000000000444089210*var_31*var_79*var_83/(var_32*var_32*var_32); + A[252] = A[42]; + A[375] = A[108]; + A[316] = A[106]; + A[239] = 0.0000000000000000000000000; + A[268] = 0.0000000000000000000000000; + A[362] = 0.0000000000000000000000000; + A[374] = A[67]; + A[288] = 0.0000000000000000000000000; + A[265] = 0.0000000000000000000000000; + A[214] = A[3]; + A[275] = A[65]; + A[270] = A[3]; + A[247] = 0.0000000000000000000000000; + A[351] = A[27]; + const double var_86 = 0.8750000000000000000000000*var_44 + 0.1250000000000000000000000*var_42 + var_65; + A[43] = 0.3000000000000000444089210*var_31*var_86/(var_32*var_32*var_32); + A[35] = 0.0000000000000000000000000; + A[34] = 0.0000000000000000000000000; + A[289] = 0.0000000000000000000000000; + A[32] = 0.0000000000000000000000000; + A[341] = 0.0000000000000000000000000; + A[149] = A[89]; + const double var_87 = 1.5000000000000000000000000*var_18 + var_61 + var_15; + A[0] = 0.8500000000000000888178420*var_31*var_87/(var_32*var_32*var_32); + A[352] = A[47]; + A[202] = 0.0000000000000000000000000; + A[236] = A[25]; + A[295] = A[65]; + A[276] = A[65]; + A[38] = 0.0000000000000000000000000; + A[132] = 0.0000000000000000000000000; + A[238] = A[28]; + A[166] = A[108]; + A[118] = 0.0000000000000000000000000; + A[364] = 0.0000000000000000000000000; + A[197] = 0.0000000000000000000000000; + A[301] = 0.0000000000000000000000000; + A[394] = A[89]; + A[355] = A[107]; + A[29] = 0.0000000000000000000000000; + A[30] = 0.0000000000000000000000000; + A[85] = A[65]; + A[328] = 0.0000000000000000000000000; + A[192] = 0.0000000000000000000000000; + A[271] = A[23]; + A[203] = 0.0000000000000000000000000; + A[72] = 0.0000000000000000000000000; + A[230] = A[1]; + A[60] = A[3]; + A[130] = 0.0000000000000000000000000; + A[26] = A[25]; + A[337] = A[108]; + A[84] = A[63]; + A[140] = A[7]; + A[153] = 0.0000000000000000000000000; + A[97] = 0.0000000000000000000000000; + A[141] = A[27]; + A[354] = A[67]; + A[94] = 0.0000000000000000000000000; + A[269] = 0.0000000000000000000000000; + A[109] = A[69]; + A[222] = 0.0000000000000000000000000; + A[388] = 0.0000000000000000000000000; + A[217] = A[7]; + A[284] = 0.0000000000000000000000000; + A[46] = 0.0750000000000000111022302*var_31*var_81/(var_32*var_32*var_32); + A[122] = A[46]; + A[177] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[188] = A[129]; + A[381] = 0.0000000000000000000000000; + A[50] = 0.0000000000000000000000000; + A[286] = 0.0000000000000000000000000; + A[335] = A[106]; + A[308] = 0.0000000000000000000000000; + A[241] = 0.0000000000000000000000000; + A[49] = 0.0000000000000000000000000; + A[205] = 0.0000000000000000000000000; + A[232] = A[22]; + A[287] = 0.0000000000000000000000000; + A[37] = 0.0000000000000000000000000; + A[319] = A[69]; + A[171] = 0.0000000000000000000000000; + A[338] = A[108]; + A[243] = 0.0000000000000000000000000; + A[273] = A[63]; + A[78] = 0.0000000000000000000000000; + A[277] = A[67]; + A[147] = A[63]; + A[90] = 0.0000000000000000000000000; + A[378] = A[63]; + A[358] = A[148]; + A[33] = 0.0000000000000000000000000; + A[121] = A[25]; + A[240] = 0.0000000000000000000000000; + A[365] = 0.0000000000000000000000000; + A[200] = 0.0000000000000000000000000; + A[99] = 0.0000000000000000000000000; + A[124] = A[86]; + A[150] = 0.0000000000000000000000000; + A[93] = 0.0000000000000000000000000; + A[373] = A[68]; + A[317] = A[107]; + A[88] = A[67]; + A[323] = 0.0000000000000000000000000; + A[75] = 0.0000000000000000000000000; + A[219] = 0.0000000000000000000000000; + A[159] = 0.0000000000000000000000000; + A[92] = 0.0000000000000000000000000; + A[154] = 0.0000000000000000000000000; + A[31] = 0.0000000000000000000000000; + A[261] = 0.0000000000000000000000000; + A[95] = 0.0000000000000000000000000; + A[101] = A[25]; + A[345] = 0.0000000000000000000000000; + A[51] = 0.0000000000000000000000000; + A[58] = 0.0000000000000000000000000; + A[264] = 0.0000000000000000000000000; + A[383] = 0.0000000000000000000000000; + A[196] = 0.0000000000000000000000000; + A[151] = 0.0000000000000000000000000; + A[360] = 0.0000000000000000000000000; + A[181] = 0.0000000000000000000000000; + A[71] = 0.0000000000000000000000000; + A[356] = A[108]; + A[186] = A[129]; + A[204] = 0.0000000000000000000000000; + A[201] = 0.0000000000000000000000000; + A[79] = 0.0000000000000000000000000; + A[391] = 0.0000000000000000000000000; + A[262] = 0.0000000000000000000000000; + A[332] = A[46]; + A[387] = 0.0000000000000000000000000; + A[347] = 0.0000000000000000000000000; + A[223] = 0.0000000000000000000000000; + A[377] = A[148]; + A[310] = A[5]; + A[48] = A[47]; + A[211] = A[1]; + A[379] = A[129]; + A[74] = 0.0000000000000000000000000; + A[19] = 0.0000000000000000000000000; + A[191] = 0.0000000000000000000000000; + A[324] = 0.0000000000000000000000000; + A[282] = 0.0000000000000000000000000; + A[259] = 0.0000000000000000000000000; + A[104] = A[65]; + A[260] = 0.0000000000000000000000000; + A[91] = 0.0000000000000000000000000; + A[146] = A[108]; + A[399] = A[189]; + A[325] = 0.0000000000000000000000000; + A[392] = 0.0000000000000000000000000; + A[162] = A[47]; + A[184] = A[89]; + A[290] = A[3]; + A[127] = A[108]; + A[16] = 0.0000000000000000000000000; + A[158] = 0.0000000000000000000000000; + A[123] = A[65]; + A[39] = 0.0000000000000000000000000; + A[119] = 0.0000000000000000000000000; + A[300] = 0.0000000000000000000000000; + A[226] = 0.0000000000000000000000000; + A[59] = 0.0000000000000000000000000; + A[170] = 0.0000000000000000000000000; + A[70] = 0.0000000000000000000000000; + A[372] = A[47]; + A[143] = A[67]; + A[363] = 0.0000000000000000000000000; + A[307] = 0.0000000000000000000000000; + A[11] = 0.0000000000000000000000000; + A[249] = 0.0000000000000000000000000; + A[382] = 0.0000000000000000000000000; + A[220] = 0.0000000000000000000000000; + A[342] = 0.0000000000000000000000000; + A[213] = A[3]; + A[274] = A[64]; + A[346] = 0.0000000000000000000000000; + A[144] = A[67]; + A[161] = A[28]; + A[251] = A[22]; + A[182] = 0.0000000000000000000000000; + A[87] = A[67]; + A[174] = 0.0000000000000000000000000; + A[397] = A[89]; + A[190] = 0.0000000000000000000000000; + A[396] = A[129]; + A[229] = 0.0000000000000000000000000; + A[12] = 0.0000000000000000000000000; + A[195] = 0.0000000000000000000000000; + A[272] = A[43]; + A[333] = A[65]; + A[165] = A[108]; + A[56] = 0.0000000000000000000000000; + A[331] = A[25]; + A[52] = 0.0000000000000000000000000; + A[126] = A[63]; + A[210] = A[0]; + A[142] = A[47]; + A[353] = A[67]; + A[343] = 0.0000000000000000000000000; + A[54] = 0.0000000000000000000000000; + A[376] = A[108]; + A[386] = 0.0000000000000000000000000; + A[198] = 0.0000000000000000000000000; + A[53] = 0.0000000000000000000000000; + A[82] = A[44]; + A[179] = 0.0000000000000000000000000; + A[348] = 0.0000000000000000000000000; + A[315] = A[63]; + A[128] = A[108]; + A[263] = 0.0000000000000000000000000; + A[175] = 0.0000000000000000000000000; + A[314] = A[65]; + A[298] = A[67]; + A[334] = A[86]; + A[304] = 0.0000000000000000000000000; + A[112] = 0.0000000000000000000000000; + A[256] = A[46]; + A[385] = 0.0000000000000000000000000; + A[155] = 0.0000000000000000000000000; + A[228] = 0.0000000000000000000000000; + A[172] = 0.0000000000000000000000000; + A[336] = A[63]; + A[395] = A[69]; + A[111] = 0.0000000000000000000000000; + A[160] = A[8]; + A[131] = 0.0000000000000000000000000; + A[137] = 0.0000000000000000000000000; + A[134] = 0.0000000000000000000000000; + A[4] = A[3]; + A[62] = A[43]; + A[349] = 0.0000000000000000000000000; + A[164] = A[67]; + A[15] = 0.0000000000000000000000000; + A[393] = A[69]; + A[398] = A[129]; + A[253] = A[43]; + A[180] = 0.0000000000000000000000000; + A[242] = 0.0000000000000000000000000; + A[329] = 0.0000000000000000000000000; + A[320] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q3_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q3_quadrature.h new file mode 100644 index 0000000..e3bf8f3 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q3_quadrature.h @@ -0,0 +1,12069 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P1_Q3_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P1_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q3_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q3_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q3_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q3_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q3_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q3_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p1_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W6[6] = {0.054975871827661, 0.054975871827661, 0.054975871827661, 0.111690794839005, 0.111690794839005, 0.111690794839005}; + // Quadrature points on the UFC reference element: (0.816847572980459, 0.091576213509771), (0.091576213509771, 0.816847572980459), (0.091576213509771, 0.091576213509771), (0.10810301816807, 0.445948490915965), (0.445948490915965, 0.10810301816807), (0.445948490915965, 0.445948490915965) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[6][2] = \ + {{-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + static const double FE1_C0_D01[6][9] = \ + {{-0.289027817302694, 0.289027817302687, 5.33192534762283, -1.65611126921075, -0.113213738890623, 0.113213738890629, 1.65611126921077, -5.33192534762283, -2.06501482580279e-14}, + {-0.289027817302695, 2.65611126921076, -0.298879221903342, 1.60760984840734, 1.35723204730744, -3.72431549921551, 0.185665483012719, 0.298879221903341, -1.79327533142006}, + {-2.65611126921075, 0.289027817302687, -0.298879221903341, -0.185665483012718, 3.72431549921547, -1.35723204730741, -1.60760984840734, 0.298879221903342, 1.79327533142006}, + {0.328790654815627, -0.328790654815627, -0.328699037506192, 0.815162619262507, -2.68474576342806, 2.68474576342806, -0.815162619262507, 0.328699037506193, 0.0}, + {0.328790654815627, 0.184837380737491, 0.677977554306217, -0.70514200810302, -0.137185064956293, -0.376442970596826, -3.36272331773427, -0.677977554306216, 4.06786532583729}, + {-0.184837380737492, -0.328790654815627, 0.677977554306215, 3.36272331773427, 0.376442970596826, 0.137185064956294, 0.70514200810302, -0.677977554306216, -4.06786532583729}}; + + // Array of non-zero columns + static const unsigned int nzc10[9] = {10, 12, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc7[9] = {0, 2, 3, 4, 5, 6, 7, 8, 9}; + + static const double FE1_C0_D10[6][9] = \ + {{-0.289027817302695, 2.65611126921076, 1.60760984840734, -0.298879221903343, 0.185665483012717, 0.298879221903344, 1.35723204730743, -3.7243154992155, -1.79327533142006}, + {-0.289027817302695, 0.289027817302689, -1.65611126921075, 5.33192534762283, 1.65611126921078, -5.33192534762283, -0.113213738890622, 0.113213738890627, -2.16402533218167e-14}, + {-2.65611126921075, 0.289027817302688, -0.185665483012718, -0.298879221903344, -1.60760984840734, 0.298879221903344, 3.72431549921547, -1.35723204730741, 1.79327533142006}, + {0.328790654815627, 0.184837380737492, -0.70514200810302, 0.677977554306215, -3.36272331773427, -0.677977554306215, -0.137185064956292, -0.376442970596827, 4.06786532583729}, + {0.328790654815627, -0.328790654815627, 0.815162619262508, -0.328699037506193, -0.815162619262508, 0.328699037506194, -2.68474576342806, 2.68474576342806, 0.0}, + {-0.184837380737492, -0.328790654815627, 3.36272331773427, 0.677977554306218, 0.705142008103019, -0.677977554306217, 0.376442970596827, 0.137185064956292, -4.06786532583729}}; + + // Array of non-zero columns + static const unsigned int nzc11[9] = {10, 11, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc8[9] = {0, 1, 3, 4, 5, 6, 7, 8, 9}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 400; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 60. + double G[12]; + G[0] = K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 11904 + for (unsigned int ip = 0; ip < 6; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 16 + for (unsigned int r = 0; r < 2; r++) + { + F0 += FE0_C0_D01[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D01[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 24 + double I[3]; + // Number of operations: 8 + I[0] = W6[ip]*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 8 + I[1] = W6[ip]*(F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 8 + I[2] = W6[ip]*(F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 1944 + for (unsigned int j = 0; j < 9; j++) + { + for (unsigned int k = 0; k < 9; k++) + { + // Number of operations to compute entry: 3 + A[nzc10[j]*20 + nzc10[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc10[j]*20 + nzc11[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*20 + nzc10[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*20 + nzc11[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc7[j]*20 + nzc7[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc7[j]*20 + nzc8[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*20 + nzc7[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*20 + nzc8[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p1_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q3_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q3_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q3_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q3_tensor.h new file mode 100644 index 0000000..5a7186b --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q3_tensor.h @@ -0,0 +1,12370 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P1_Q3_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P1_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q3_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q3_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q3_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q3_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q3_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q3_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p1_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 96 + // Number of operations (multiply-add pairs) for tensor contraction: 490 + // Total number of operations (multiply-add pairs): 597 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0 = det*(w[0][3]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1 = det*(w[0][3]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0 = det*(w[0][4]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1 = det*(w[0][5]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0 = det*(w[0][3]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1 = det*(w[0][3]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0 = det*(w[0][4]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1 = det*(w[0][5]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0 = det*(w[0][3]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1 = det*(w[0][3]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0 = det*(w[0][4]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1 = det*(w[0][5]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0 = det*(w[0][3]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1 = det*(w[0][3]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0 = det*(w[0][4]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1 = det*(w[0][5]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[143] = -0.168750000000007*G0_0_1_0_0_0 - 0.168750000000007*G0_0_1_0_0_1 + 0.168750000000007*G0_0_1_1_0_0 + 0.168750000000007*G0_0_1_2_0_1 - 0.168750000000007*G0_0_1_3_1_0 - 0.168750000000007*G0_0_1_3_1_1 + 0.168750000000007*G0_0_1_4_1_0 + 0.168750000000007*G0_0_1_5_1_1 - 0.168750000000004*G0_1_0_0_0_0 - 0.168750000000004*G0_1_0_0_0_1 + 0.168750000000004*G0_1_0_1_0_0 + 0.168750000000004*G0_1_0_2_0_1 - 0.168750000000004*G0_1_0_3_1_0 - 0.168750000000004*G0_1_0_3_1_1 + 0.168750000000004*G0_1_0_4_1_0 + 0.168750000000004*G0_1_0_5_1_1 - 0.337500000000006*G0_1_1_0_0_0 - 0.337500000000006*G0_1_1_0_0_1 + 0.337500000000006*G0_1_1_1_0_0 + 0.337500000000006*G0_1_1_2_0_1 - 0.337500000000006*G0_1_1_3_1_0 - 0.337500000000006*G0_1_1_3_1_1 + 0.337500000000006*G0_1_1_4_1_0 + 0.337500000000006*G0_1_1_5_1_1; + A[329] = 0.0; + A[384] = 0.0; + A[180] = 0.0; + A[207] = 0.0; + A[17] = 0.0; + A[281] = 0.0; + A[257] = 0.0374999999999996*G0_1_1_0_0_0 + 0.0374999999999996*G0_1_1_0_0_1 - 0.0374999999999996*G0_1_1_1_0_0 - 0.0374999999999996*G0_1_1_2_0_1 + 0.0374999999999996*G0_1_1_3_1_0 + 0.0374999999999996*G0_1_1_3_1_1 - 0.0374999999999996*G0_1_1_4_1_0 - 0.0374999999999996*G0_1_1_5_1_1; + A[304] = 0.0; + A[62] = -A[257] + 0.3*G0_0_1_0_0_0 + 0.3*G0_0_1_0_0_1 - 0.3*G0_0_1_1_0_0 - 0.3*G0_0_1_2_0_1 + 0.3*G0_0_1_3_1_0 + 0.3*G0_0_1_3_1_1 - 0.3*G0_0_1_4_1_0 - 0.3*G0_0_1_5_1_1; + A[320] = 0.0; + A[353] = A[143]; + A[172] = 0.0; + A[178] = 0.0; + A[235] = 0.0375*G0_0_0_0_0_0 + 0.0375*G0_0_0_0_0_1 - 0.0375*G0_0_0_1_0_0 - 0.0375*G0_0_0_2_0_1 + 0.0375*G0_0_0_3_1_0 + 0.0375*G0_0_0_3_1_1 - 0.0375*G0_0_0_4_1_0 - 0.0375*G0_0_0_5_1_1; + A[199] = 0.0; + A[288] = 0.0; + A[248] = 0.0; + A[58] = 0.0; + A[14] = 0.0; + A[71] = 0.0; + A[35] = 0.0; + A[92] = 0.0; + A[52] = 0.0; + A[101] = A[235]; + A[77] = 0.0; + A[327] = 0.0; + A[134] = 0.0; + A[346] = 0.0; + A[155] = 0.0; + A[365] = 0.0; + A[209] = 0.0; + A[224] = 0.0; + A[299] = -5.9999999999998*A[143]; + A[379] = -A[299] + 2.025*G0_1_1_0_0_0 + 2.025*G0_1_1_0_0_1 - 2.025*G0_1_1_1_0_0 - 2.025*G0_1_1_2_0_1 + 2.025*G0_1_1_3_1_0 + 2.025*G0_1_1_3_1_1 - 2.025*G0_1_1_4_1_0 - 2.025*G0_1_1_5_1_1; + A[165] = -0.166666666666662*A[379]; + A[85] = -A[165] - 0.337500000000009*G0_0_0_0_0_0 - 0.337500000000009*G0_0_0_0_0_1 + 0.337500000000009*G0_0_0_1_0_0 + 0.337500000000009*G0_0_0_2_0_1 - 0.337500000000009*G0_0_0_3_1_0 - 0.337500000000009*G0_0_0_3_1_1 + 0.337500000000009*G0_0_0_4_1_0 + 0.337500000000009*G0_0_0_5_1_1; + A[393] = -5.99999999999986*A[85]; + A[370] = A[85] - 0.168749999999992*G0_0_1_0_0_0 - 0.168749999999992*G0_0_1_0_0_1 + 0.168749999999992*G0_0_1_1_0_0 + 0.168749999999992*G0_0_1_2_0_1 - 0.168749999999992*G0_0_1_3_1_0 - 0.168749999999992*G0_0_1_3_1_1 + 0.168749999999992*G0_0_1_4_1_0 + 0.168749999999992*G0_0_1_5_1_1 + 0.131250000000003*G0_1_0_0_0_0 + 0.131250000000003*G0_1_0_0_0_1 - 0.131250000000003*G0_1_0_1_0_0 - 0.131250000000003*G0_1_0_2_0_1 + 0.131250000000003*G0_1_0_3_1_0 + 0.131250000000003*G0_1_0_3_1_1 - 0.131250000000003*G0_1_0_4_1_0 - 0.131250000000003*G0_1_0_5_1_1 - 0.0374999999999979*G0_1_1_0_0_0 - 0.0374999999999979*G0_1_1_0_0_1 + 0.0374999999999979*G0_1_1_1_0_0 + 0.0374999999999979*G0_1_1_2_0_1 - 0.0374999999999979*G0_1_1_3_1_0 - 0.0374999999999979*G0_1_1_3_1_1 + 0.0374999999999979*G0_1_1_4_1_0 + 0.0374999999999979*G0_1_1_5_1_1; + A[214] = -A[370] - 0.299999999999998*G0_0_0_0_0_0 - 0.299999999999998*G0_0_0_0_0_1 + 0.299999999999998*G0_0_0_1_0_0 + 0.299999999999998*G0_0_0_2_0_1 - 0.299999999999998*G0_0_0_3_1_0 - 0.299999999999998*G0_0_0_3_1_1 + 0.299999999999998*G0_0_0_4_1_0 + 0.299999999999998*G0_0_0_5_1_1 - 0.299999999999999*G0_0_1_0_0_0 - 0.299999999999999*G0_0_1_0_0_1 + 0.299999999999999*G0_0_1_1_0_0 + 0.299999999999999*G0_0_1_2_0_1 - 0.299999999999999*G0_0_1_3_1_0 - 0.299999999999999*G0_0_1_3_1_1 + 0.299999999999999*G0_0_1_4_1_0 + 0.299999999999999*G0_0_1_5_1_1; + A[313] = A[85]; + A[398] = A[379]; + A[247] = 0.0; + A[219] = 0.0; + A[310] = -A[214] + 0.7125*G0_1_0_0_0_0 + 0.7125*G0_1_0_0_0_1 - 0.7125*G0_1_0_1_0_0 - 0.7125*G0_1_0_2_0_1 + 0.7125*G0_1_0_3_1_0 + 0.7125*G0_1_0_3_1_1 - 0.7125*G0_1_0_4_1_0 - 0.7125*G0_1_0_5_1_1 + 0.712499999999999*G0_1_1_0_0_0 + 0.712499999999999*G0_1_1_0_0_1 - 0.712499999999999*G0_1_1_1_0_0 - 0.712499999999999*G0_1_1_2_0_1 + 0.712499999999999*G0_1_1_3_1_0 + 0.712499999999999*G0_1_1_3_1_1 - 0.712499999999999*G0_1_1_4_1_0 - 0.712499999999999*G0_1_1_5_1_1; + A[266] = 0.0; + A[5] = -A[214] + 0.712499999999999*G0_0_1_0_0_0 + 0.712499999999999*G0_0_1_0_0_1 - 0.712499999999999*G0_0_1_1_0_0 - 0.712499999999999*G0_0_1_2_0_1 + 0.712499999999999*G0_0_1_3_1_0 + 0.712499999999999*G0_0_1_3_1_1 - 0.712499999999999*G0_0_1_4_1_0 - 0.712499999999999*G0_0_1_5_1_1 + 0.712499999999999*G0_1_1_0_0_0 + 0.712499999999999*G0_1_1_0_0_1 - 0.712499999999999*G0_1_1_1_0_0 - 0.712499999999999*G0_1_1_2_0_1 + 0.712499999999999*G0_1_1_3_1_0 + 0.712499999999999*G0_1_1_3_1_1 - 0.712499999999999*G0_1_1_4_1_0 - 0.712499999999999*G0_1_1_5_1_1; + A[91] = 0.0; + A[47] = A[257]; + A[110] = 0.0; + A[121] = A[235]; + A[97] = 0.0; + A[144] = A[143]; + A[381] = 0.0; + A[160] = A[370]; + A[319] = A[393]; + A[239] = 0.0; + A[331] = A[235]; + A[138] = 0.0; + A[386] = 0.0; + A[350] = A[370] + 1.0125*G0_0_0_0_0_0 + 1.0125*G0_0_0_0_0_1 - 1.0125*G0_0_0_1_0_0 - 1.0125*G0_0_0_2_0_1 + 1.0125*G0_0_0_3_1_0 + 1.0125*G0_0_0_3_1_1 - 1.0125*G0_0_0_4_1_0 - 1.0125*G0_0_0_5_1_1 + 1.0125*G0_0_1_0_0_0 + 1.0125*G0_0_1_0_0_1 - 1.0125*G0_0_1_1_0_0 - 1.0125*G0_0_1_2_0_1 + 1.0125*G0_0_1_3_1_0 + 1.0125*G0_0_1_3_1_1 - 1.0125*G0_0_1_4_1_0 - 1.0125*G0_0_1_5_1_1; + A[377] = -A[143] + 1.35*G0_0_0_0_0_0 + 1.35*G0_0_0_0_0_1 - 1.35*G0_0_0_1_0_0 - 1.35*G0_0_0_2_0_1 + 1.35*G0_0_0_3_1_0 + 1.35*G0_0_0_3_1_1 - 1.35*G0_0_0_4_1_0 - 1.35*G0_0_0_5_1_1 + 1.0125*G0_0_1_0_0_0 + 1.0125*G0_0_1_0_0_1 - 1.0125*G0_0_1_1_0_0 - 1.0125*G0_0_1_2_0_1 + 1.0125*G0_0_1_3_1_0 + 1.0125*G0_0_1_3_1_1 - 1.0125*G0_0_1_4_1_0 - 1.0125*G0_0_1_5_1_1; + A[167] = A[377]; + A[186] = A[379]; + A[205] = 0.0; + A[228] = 0.0; + A[19] = 0.0; + A[287] = 0.0; + A[259] = 0.0; + A[38] = 0.0; + A[306] = 0.0; + A[278] = -4.99999999999982*A[143]; + A[273] = -A[278] - 1.68749999999999*G0_0_0_0_0_0 - 1.68749999999999*G0_0_0_0_0_1 + 1.68749999999999*G0_0_0_1_0_0 + 1.68749999999999*G0_0_0_2_0_1 - 1.68749999999999*G0_0_0_3_1_0 - 1.68749999999999*G0_0_0_3_1_1 + 1.68749999999999*G0_0_0_4_1_0 + 1.68749999999999*G0_0_0_5_1_1; + A[189] = 2.4*A[273]; + A[357] = A[273]; + A[9] = 0.0; + A[64] = -A[143] + 0.337499999999997*G0_0_0_0_0_0 + 0.337499999999997*G0_0_0_0_0_1 - 0.337499999999997*G0_0_0_1_0_0 - 0.337499999999997*G0_0_0_2_0_1 + 0.337499999999997*G0_0_0_3_1_0 + 0.337499999999997*G0_0_0_3_1_1 - 0.337499999999997*G0_0_0_4_1_0 - 0.337499999999997*G0_0_0_5_1_1 - 1.01250000000001*G0_0_1_0_0_0 - 1.01250000000001*G0_0_1_0_0_1 + 1.01250000000001*G0_0_1_1_0_0 + 1.01250000000001*G0_0_1_2_0_1 - 1.01250000000001*G0_0_1_3_1_0 - 1.01250000000001*G0_0_1_3_1_1 + 1.01250000000001*G0_0_1_4_1_0 + 1.01250000000001*G0_0_1_5_1_1; + A[87] = A[143]; + A[106] = -A[85] + 1.0125*G0_0_1_0_0_0 + 1.0125*G0_0_1_0_0_1 - 1.0125*G0_0_1_1_0_0 - 1.0125*G0_0_1_2_0_1 + 1.0125*G0_0_1_3_1_0 + 1.0125*G0_0_1_3_1_1 - 1.0125*G0_0_1_4_1_0 - 1.0125*G0_0_1_5_1_1 + 1.35*G0_1_1_0_0_0 + 1.35*G0_1_1_0_0_1 - 1.35*G0_1_1_1_0_0 - 1.35*G0_1_1_2_0_1 + 1.35*G0_1_1_3_1_0 + 1.35*G0_1_1_3_1_1 - 1.35*G0_1_1_4_1_0 - 1.35*G0_1_1_5_1_1; + A[322] = 0.0; + A[395] = A[393]; + A[343] = 0.0; + A[156] = 0.0; + A[368] = 0.0; + A[174] = 0.0; + A[195] = 0.0; + A[221] = 0.0; + A[197] = 0.0; + A[294] = A[273]; + A[315] = A[273]; + A[271] = -A[235] - 0.712500000000004*G0_1_0_0_0_0 - 0.712500000000004*G0_1_0_0_0_1 + 0.712500000000004*G0_1_0_1_0_0 + 0.712500000000004*G0_1_0_2_0_1 - 0.712500000000004*G0_1_0_3_1_0 - 0.712500000000004*G0_1_0_3_1_1 + 0.712500000000004*G0_1_0_4_1_0 + 0.712500000000004*G0_1_0_5_1_1; + A[56] = 0.0; + A[0] = -11.3333333333328*A[214]; + A[73] = 0.0; + A[33] = 0.0; + A[94] = 0.0; + A[50] = 0.0; + A[115] = 0.0; + A[79] = 0.0; + A[132] = 0.0; + A[344] = 0.0; + A[149] = A[299]; + A[363] = 0.0; + A[226] = 0.0; + A[297] = A[143]; + A[241] = 0.0; + A[217] = -A[214] + 0.7125*G0_0_0_0_0_0 + 0.7125*G0_0_0_0_0_1 - 0.7125*G0_0_0_1_0_0 - 0.7125*G0_0_0_2_0_1 + 0.7125*G0_0_0_3_1_0 + 0.7125*G0_0_0_3_1_1 - 0.7125*G0_0_0_4_1_0 - 0.7125*G0_0_0_5_1_1 + 0.7125*G0_1_0_0_0_0 + 0.7125*G0_1_0_0_0_1 - 0.7125*G0_1_0_1_0_0 - 0.7125*G0_1_0_2_0_1 + 0.7125*G0_1_0_3_1_0 + 0.7125*G0_1_0_3_1_1 - 0.7125*G0_1_0_4_1_0 - 0.7125*G0_1_0_5_1_1; + A[264] = 0.0; + A[7] = A[217]; + A[26] = A[235]; + A[108] = A[165]; + A[127] = A[165]; + A[99] = 0.0; + A[146] = A[165]; + A[118] = 0.0; + A[383] = 0.0; + A[162] = A[257]; + A[183] = A[393]; + A[282] = 0.0; + A[61] = A[271]; + A[333] = A[85]; + A[136] = 0.0; + A[388] = 0.0; + A[348] = 0.0; + A[375] = A[165]; + A[169] = A[379]; + A[184] = A[299]; + A[203] = 0.0; + A[285] = 0.0; + A[253] = -A[257] + 0.3*G0_1_0_0_0_0 + 0.3*G0_1_0_0_0_1 - 0.3*G0_1_0_1_0_0 - 0.3*G0_1_0_2_0_1 + 0.3*G0_1_0_3_1_0 + 0.3*G0_1_0_3_1_1 - 0.3*G0_1_0_4_1_0 - 0.3*G0_1_0_5_1_1; + A[45] = -A[253] - 0.375000000000002*G0_1_1_0_0_0 - 0.375000000000002*G0_1_1_0_0_1 + 0.375000000000002*G0_1_1_1_0_0 + 0.375000000000002*G0_1_1_2_0_1 - 0.375000000000002*G0_1_1_3_1_0 - 0.375000000000002*G0_1_1_3_1_1 + 0.375000000000002*G0_1_1_4_1_0 + 0.375000000000002*G0_1_1_5_1_1; + A[36] = 0.0; + A[300] = 0.0; + A[276] = A[85]; + A[11] = 0.0; + A[66] = A[85]; + A[30] = 0.0; + A[81] = -A[235] + 0.3*G0_1_0_0_0_0 + 0.3*G0_1_0_0_0_1 - 0.3*G0_1_0_1_0_0 - 0.3*G0_1_0_2_0_1 + 0.3*G0_1_0_3_1_0 + 0.3*G0_1_0_3_1_1 - 0.3*G0_1_0_4_1_0 - 0.3*G0_1_0_5_1_1; + A[104] = A[85]; + A[324] = 0.0; + A[131] = 0.0; + A[397] = A[299]; + A[341] = 0.0; + A[158] = 0.0; + A[366] = 0.0; + A[193] = 0.0; + A[210] = A[0]; + A[223] = 0.0; + A[292] = -A[257] - 0.712500000000005*G0_0_1_0_0_0 - 0.712500000000005*G0_0_1_0_0_1 + 0.712500000000005*G0_0_1_1_0_0 + 0.712500000000005*G0_0_1_2_0_1 - 0.712500000000005*G0_0_1_3_1_0 - 0.712500000000005*G0_0_1_3_1_1 + 0.712500000000005*G0_0_1_4_1_0 + 0.712500000000005*G0_0_1_5_1_1; + A[244] = 0.0; + A[309] = 0.0; + A[269] = 0.0; + A[75] = 0.0; + A[23] = -A[235] - 0.712500000000004*G0_0_1_0_0_0 - 0.712500000000004*G0_0_1_0_0_1 + 0.712500000000004*G0_0_1_1_0_0 + 0.712500000000004*G0_0_1_2_0_1 - 0.712500000000004*G0_0_1_3_1_0 - 0.712500000000004*G0_0_1_3_1_1 + 0.712500000000004*G0_0_1_4_1_0 + 0.712500000000004*G0_0_1_5_1_1; + A[88] = A[143]; + A[48] = A[257]; + A[113] = 0.0; + A[122] = -A[292] + 0.637500000000002*G0_1_1_0_0_0 + 0.637500000000002*G0_1_1_0_0_1 - 0.637500000000002*G0_1_1_1_0_0 - 0.637500000000002*G0_1_1_2_0_1 + 0.637500000000002*G0_1_1_3_1_0 + 0.637500000000002*G0_1_1_3_1_1 - 0.637500000000002*G0_1_1_4_1_0 - 0.637500000000002*G0_1_1_5_1_1; + A[151] = 0.0; + A[361] = 0.0; + A[337] = A[165]; + A[243] = 0.0; + A[262] = 0.0; + A[24] = -A[235] + 0.3*G0_0_1_0_0_0 + 0.3*G0_0_1_0_0_1 - 0.3*G0_0_1_1_0_0 - 0.3*G0_0_1_2_0_1 + 0.3*G0_0_1_3_1_0 + 0.3*G0_0_1_3_1_1 - 0.3*G0_0_1_4_1_0 - 0.3*G0_0_1_5_1_1; + A[43] = A[253]; + A[125] = -A[85] + 1.0125*G0_1_0_0_0_0 + 1.0125*G0_1_0_0_0_1 - 1.0125*G0_1_0_1_0_0 - 1.0125*G0_1_0_2_0_1 + 1.0125*G0_1_0_3_1_0 + 1.0125*G0_1_0_3_1_1 - 1.0125*G0_1_0_4_1_0 - 1.0125*G0_1_0_5_1_1 + 1.35*G0_1_1_0_0_0 + 1.35*G0_1_1_0_0_1 - 1.35*G0_1_1_1_0_0 - 1.35*G0_1_1_2_0_1 + 1.35*G0_1_1_3_1_0 + 1.35*G0_1_1_3_1_1 - 1.35*G0_1_1_4_1_0 - 1.35*G0_1_1_5_1_1; + A[140] = A[350]; + A[116] = 0.0; + A[328] = 0.0; + A[385] = 0.0; + A[378] = A[273]; + A[164] = A[143]; + A[181] = 0.0; + A[206] = 0.0; + A[16] = 0.0; + A[280] = 0.0; + A[305] = 0.0; + A[63] = A[273]; + A[84] = A[273]; + A[335] = A[125]; + A[390] = 0.0; + A[354] = A[143]; + A[373] = A[278]; + A[171] = 0.0; + A[190] = 0.0; + A[201] = 0.0; + A[177] = 0.0; + A[232] = -0.0874999999999997*G0_0_1_0_0_0 - 0.0874999999999997*G0_0_1_0_0_1 + 0.0874999999999997*G0_0_1_1_0_0 + 0.0874999999999997*G0_0_1_2_0_1 - 0.0874999999999997*G0_0_1_3_1_0 - 0.0874999999999997*G0_0_1_3_1_1 + 0.0874999999999997*G0_0_1_4_1_0 + 0.0874999999999997*G0_0_1_5_1_1; + A[20] = -A[232] + 0.0875000000000007*G0_0_0_0_0_0 + 0.0875000000000007*G0_0_0_0_0_1 - 0.0875000000000007*G0_0_0_1_0_0 - 0.0875000000000007*G0_0_0_2_0_1 + 0.0875000000000007*G0_0_0_3_1_0 + 0.0875000000000007*G0_0_0_3_1_1 - 0.0875000000000007*G0_0_0_4_1_0 - 0.0875000000000007*G0_0_0_5_1_1; + A[212] = -A[232] + 0.0875000000000007*G0_1_1_0_0_0 + 0.0875000000000007*G0_1_1_0_0_1 - 0.0875000000000007*G0_1_1_1_0_0 - 0.0875000000000007*G0_1_1_2_0_1 + 0.0875000000000007*G0_1_1_3_1_0 + 0.0875000000000007*G0_1_1_3_1_1 - 0.0875000000000007*G0_1_1_4_1_0 - 0.0875000000000007*G0_1_1_5_1_1; + A[230] = A[20]; + A[2] = A[212]; + A[291] = A[81]; + A[255] = A[45]; + A[302] = 0.0; + A[274] = A[64]; + A[13] = 0.0; + A[68] = A[278]; + A[28] = -A[23] + 0.637500000000002*G0_0_0_0_0_0 + 0.637500000000002*G0_0_0_0_0_1 - 0.637500000000002*G0_0_0_1_0_0 - 0.637500000000002*G0_0_0_2_0_1 + 0.637500000000002*G0_0_0_3_1_0 + 0.637500000000002*G0_0_0_3_1_1 - 0.637500000000002*G0_0_0_4_1_0 - 0.637500000000002*G0_0_0_5_1_1; + A[83] = -A[143] + 0.337499999999997*G0_0_0_0_0_0 + 0.337499999999997*G0_0_0_0_0_1 - 0.337499999999997*G0_0_0_1_0_0 - 0.337499999999997*G0_0_0_2_0_1 + 0.337499999999997*G0_0_0_3_1_0 + 0.337499999999997*G0_0_0_3_1_1 - 0.337499999999997*G0_0_0_4_1_0 - 0.337499999999997*G0_0_0_5_1_1 - 1.0125*G0_1_0_0_0_0 - 1.0125*G0_1_0_0_0_1 + 1.0125*G0_1_0_1_0_0 + 1.0125*G0_1_0_2_0_1 - 1.0125*G0_1_0_3_1_0 - 1.0125*G0_1_0_3_1_1 + 1.0125*G0_1_0_4_1_0 + 1.0125*G0_1_0_5_1_1; + A[55] = 0.0; + A[102] = -A[62] - 0.375000000000002*G0_1_1_0_0_0 - 0.375000000000002*G0_1_1_0_0_1 + 0.375000000000002*G0_1_1_1_0_0 + 0.375000000000002*G0_1_1_2_0_1 - 0.375000000000002*G0_1_1_3_1_0 - 0.375000000000002*G0_1_1_3_1_1 + 0.375000000000002*G0_1_1_4_1_0 + 0.375000000000002*G0_1_1_5_1_1; + A[326] = 0.0; + A[129] = A[379]; + A[399] = A[189]; + A[347] = 0.0; + A[152] = 0.0; + A[364] = 0.0; + A[208] = 0.0; + A[225] = 0.0; + A[298] = A[143]; + A[246] = 0.0; + A[218] = A[370] + 0.299999999999997*G0_0_1_0_0_0 + 0.299999999999997*G0_0_1_0_0_1 - 0.299999999999997*G0_0_1_1_0_0 - 0.299999999999997*G0_0_1_2_0_1 + 0.299999999999997*G0_0_1_3_1_0 + 0.299999999999997*G0_0_1_3_1_1 - 0.299999999999997*G0_0_1_4_1_0 - 0.299999999999997*G0_0_1_5_1_1 - 0.299999999999997*G0_1_0_0_0_0 - 0.299999999999997*G0_1_0_0_0_1 + 0.299999999999997*G0_1_0_1_0_0 + 0.299999999999997*G0_1_0_2_0_1 - 0.299999999999997*G0_1_0_3_1_0 - 0.299999999999997*G0_1_0_3_1_1 + 0.299999999999997*G0_1_0_4_1_0 + 0.299999999999997*G0_1_0_5_1_1; + A[311] = A[235]; + A[267] = 0.0; + A[4] = A[214]; + A[21] = -11.3333333333334*A[235]; + A[90] = 0.0; + A[111] = 0.0; + A[120] = -A[214] - 0.299999999999998*G0_1_0_0_0_0 - 0.299999999999998*G0_1_0_0_0_1 + 0.299999999999998*G0_1_0_1_0_0 + 0.299999999999998*G0_1_0_2_0_1 - 0.299999999999998*G0_1_0_3_1_0 - 0.299999999999998*G0_1_0_3_1_1 + 0.299999999999998*G0_1_0_4_1_0 + 0.299999999999998*G0_1_0_5_1_1 - 0.3*G0_1_1_0_0_0 - 0.3*G0_1_1_0_0_1 + 0.3*G0_1_1_1_0_0 + 0.3*G0_1_1_2_0_1 - 0.3*G0_1_1_3_1_0 - 0.3*G0_1_1_3_1_1 + 0.3*G0_1_1_4_1_0 + 0.3*G0_1_1_5_1_1; + A[96] = 0.0; + A[145] = 0.833333333333323*A[379]; + A[339] = A[379]; + A[358] = -A[143] + 1.35*G0_0_0_0_0_0 + 1.35*G0_0_0_0_0_1 - 1.35*G0_0_0_1_0_0 - 1.35*G0_0_0_2_0_1 + 1.35*G0_0_0_3_1_0 + 1.35*G0_0_0_3_1_1 - 1.35*G0_0_0_4_1_0 - 1.35*G0_0_0_5_1_1 + 1.0125*G0_1_0_0_0_0 + 1.0125*G0_1_0_0_0_1 - 1.0125*G0_1_0_1_0_0 - 1.0125*G0_1_0_2_0_1 + 1.0125*G0_1_0_3_1_0 + 1.0125*G0_1_0_3_1_1 - 1.0125*G0_1_0_4_1_0 - 1.0125*G0_1_0_5_1_1; + A[316] = A[106]; + A[260] = 0.0; + A[236] = A[235]; + A[41] = -0.0874999999999997*G0_1_0_0_0_0 - 0.0874999999999997*G0_1_0_0_0_1 + 0.0874999999999997*G0_1_0_1_0_0 + 0.0874999999999997*G0_1_0_2_0_1 - 0.0874999999999997*G0_1_0_3_1_0 - 0.0874999999999997*G0_1_0_3_1_1 + 0.0874999999999997*G0_1_0_4_1_0 + 0.0874999999999997*G0_1_0_5_1_1; + A[250] = -A[41] + 0.0875000000000007*G0_1_1_0_0_0 + 0.0875000000000007*G0_1_1_0_0_1 - 0.0875000000000007*G0_1_1_1_0_0 - 0.0875000000000007*G0_1_1_2_0_1 + 0.0875000000000007*G0_1_1_3_1_0 + 0.0875000000000007*G0_1_1_3_1_1 - 0.0875000000000007*G0_1_1_4_1_0 - 0.0875000000000007*G0_1_1_5_1_1; + A[142] = A[257]; + A[330] = A[120]; + A[387] = 0.0; + A[351] = -A[81] - 0.375000000000003*G0_0_0_0_0_0 - 0.375000000000003*G0_0_0_0_0_1 + 0.375000000000003*G0_0_0_1_0_0 + 0.375000000000003*G0_0_0_2_0_1 - 0.375000000000003*G0_0_0_3_1_0 - 0.375000000000003*G0_0_0_3_1_1 + 0.375000000000003*G0_0_0_4_1_0 + 0.375000000000003*G0_0_0_5_1_1; + A[376] = A[165]; + A[166] = A[165]; + A[187] = A[299]; + A[204] = 0.0; + A[229] = 0.0; + A[18] = 0.0; + A[286] = 0.0; + A[258] = A[257]; + A[39] = 0.0; + A[307] = 0.0; + A[279] = A[393]; + A[8] = A[218]; + A[65] = A[85]; + A[86] = -4.99999999999992*A[85]; + A[107] = A[145]; + A[321] = 0.0; + A[392] = 0.0; + A[352] = A[257]; + A[157] = 0.0; + A[371] = -A[271] + 0.637500000000002*G0_0_0_0_0_0 + 0.637500000000002*G0_0_0_0_0_1 - 0.637500000000002*G0_0_0_1_0_0 - 0.637500000000002*G0_0_0_2_0_1 + 0.637500000000002*G0_0_0_3_1_0 + 0.637500000000002*G0_0_0_3_1_1 - 0.637500000000002*G0_0_0_4_1_0 - 0.637500000000002*G0_0_0_5_1_1; + A[173] = 0.0; + A[188] = A[379]; + A[215] = A[5]; + A[179] = 0.0; + A[234] = A[24]; + A[198] = 0.0; + A[289] = 0.0; + A[249] = 0.0; + A[312] = A[102]; + A[272] = A[62]; + A[59] = 0.0; + A[15] = 0.0; + A[70] = 0.0; + A[34] = 0.0; + A[93] = 0.0; + A[53] = 0.0; + A[100] = A[310]; + A[76] = 0.0; + A[135] = 0.0; + A[345] = 0.0; + A[154] = 0.0; + A[362] = 0.0; + A[227] = 0.0; + A[296] = A[86]; + A[240] = 0.0; + A[216] = A[370] + 0.299999999999998*G0_0_0_0_0_0 + 0.299999999999998*G0_0_0_0_0_1 - 0.299999999999998*G0_0_0_1_0_0 - 0.299999999999998*G0_0_0_2_0_1 + 0.299999999999998*G0_0_0_3_1_0 + 0.299999999999998*G0_0_0_3_1_1 - 0.299999999999998*G0_0_0_4_1_0 - 0.299999999999998*G0_0_0_5_1_1 - 0.299999999999998*G0_1_1_0_0_0 - 0.299999999999998*G0_1_1_0_0_1 + 0.299999999999998*G0_1_1_1_0_0 + 0.299999999999998*G0_1_1_2_0_1 - 0.299999999999998*G0_1_1_3_1_0 - 0.299999999999998*G0_1_1_3_1_1 + 0.299999999999998*G0_1_1_4_1_0 + 0.299999999999998*G0_1_1_5_1_1; + A[265] = 0.0; + A[6] = A[216]; + A[27] = -A[24] - 0.375000000000003*G0_0_0_0_0_0 - 0.375000000000003*G0_0_0_0_0_1 + 0.375000000000003*G0_0_0_1_0_0 + 0.375000000000003*G0_0_0_2_0_1 - 0.375000000000003*G0_0_0_3_1_0 - 0.375000000000003*G0_0_0_3_1_1 + 0.375000000000003*G0_0_0_4_1_0 + 0.375000000000003*G0_0_0_5_1_1; + A[44] = -A[257] - 0.712500000000004*G0_1_0_0_0_0 - 0.712500000000004*G0_1_0_0_0_1 + 0.712500000000004*G0_1_0_1_0_0 + 0.712500000000004*G0_1_0_2_0_1 - 0.712500000000004*G0_1_0_3_1_0 - 0.712500000000004*G0_1_0_3_1_1 + 0.712500000000004*G0_1_0_4_1_0 + 0.712500000000004*G0_1_0_5_1_1; + A[256] = -A[44] + 0.637500000000002*G0_1_1_0_0_0 + 0.637500000000002*G0_1_1_0_0_1 - 0.637500000000002*G0_1_1_1_0_0 - 0.637500000000002*G0_1_1_2_0_1 + 0.637500000000002*G0_1_1_3_1_0 + 0.637500000000002*G0_1_1_3_1_1 - 0.637500000000002*G0_1_1_4_1_0 - 0.637500000000002*G0_1_1_5_1_1; + A[46] = A[256]; + A[109] = A[393]; + A[126] = A[273]; + A[98] = 0.0; + A[147] = A[273]; + A[119] = 0.0; + A[380] = 0.0; + A[356] = A[165]; + A[161] = A[371]; + A[318] = A[165]; + A[238] = A[28]; + A[332] = A[122]; + A[139] = 0.0; + A[389] = 0.0; + A[349] = 0.0; + A[374] = A[143]; + A[168] = A[273]; + A[185] = A[393]; + A[202] = 0.0; + A[231] = A[21]; + A[284] = 0.0; + A[252] = -11.3333333333335*A[257]; + A[37] = 0.0; + A[301] = 0.0; + A[277] = A[143]; + A[10] = 0.0; + A[67] = A[143]; + A[31] = 0.0; + A[80] = A[214]; + A[105] = A[273]; + A[323] = 0.0; + A[130] = 0.0; + A[394] = A[299]; + A[342] = 0.0; + A[159] = 0.0; + A[369] = 0.0; + A[175] = 0.0; + A[194] = 0.0; + A[213] = A[214]; + A[220] = 0.0; + A[196] = 0.0; + A[295] = A[85]; + A[251] = A[41]; + A[314] = A[85]; + A[270] = A[214]; + A[57] = 0.0; + A[1] = -A[41] + 0.0875000000000007*G0_0_0_0_0_0 + 0.0875000000000007*G0_0_0_0_0_1 - 0.0875000000000007*G0_0_0_1_0_0 - 0.0875000000000007*G0_0_0_2_0_1 + 0.0875000000000007*G0_0_0_3_1_0 + 0.0875000000000007*G0_0_0_3_1_1 - 0.0875000000000007*G0_0_0_4_1_0 - 0.0875000000000007*G0_0_0_5_1_1; + A[72] = 0.0; + A[32] = 0.0; + A[95] = 0.0; + A[51] = 0.0; + A[114] = 0.0; + A[78] = 0.0; + A[133] = 0.0; + A[148] = A[358]; + A[360] = 0.0; + A[336] = A[273]; + A[242] = 0.0; + A[263] = 0.0; + A[25] = A[235]; + A[42] = A[252]; + A[124] = A[86]; + A[141] = A[351]; + A[117] = 0.0; + A[382] = 0.0; + A[163] = A[278]; + A[182] = 0.0; + A[283] = 0.0; + A[60] = A[214]; + A[334] = A[86]; + A[137] = 0.0; + A[391] = 0.0; + A[355] = A[145]; + A[372] = A[257]; + A[170] = 0.0; + A[191] = 0.0; + A[200] = 0.0; + A[176] = 0.0; + A[233] = A[23]; + A[290] = A[214]; + A[254] = A[44]; + A[303] = 0.0; + A[275] = A[85]; + A[12] = 0.0; + A[69] = A[393]; + A[29] = 0.0; + A[82] = A[292]; + A[54] = 0.0; + A[103] = A[85]; + A[325] = 0.0; + A[128] = A[165]; + A[396] = A[379]; + A[340] = 0.0; + A[153] = 0.0; + A[367] = 0.0; + A[192] = 0.0; + A[211] = A[1]; + A[222] = 0.0; + A[293] = A[83]; + A[245] = 0.0; + A[308] = 0.0; + A[268] = 0.0; + A[3] = A[214]; + A[74] = 0.0; + A[22] = A[232]; + A[89] = A[299]; + A[49] = 0.0; + A[112] = 0.0; + A[123] = A[85]; + A[150] = 0.0; + A[338] = A[165]; + A[359] = A[299]; + A[317] = A[145]; + A[261] = 0.0; + A[237] = A[27]; + A[40] = A[250]; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p1_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q3_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q3_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q3_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q4_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q4_excafe.h new file mode 100644 index 0000000..ef49662 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q4_excafe.h @@ -0,0 +1,1108 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 48.95 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -x[0][0]; + const double var_3 = x[1][0] + var_2; + const double var_4 = x[1][1] + var_0; + const double var_5 = x[2][0] + var_2; + const double var_6 = -var_4*var_5 + var_1*var_3; + const double var_7 = var_6; + const double var_8 = std::abs(var_7); + const double var_9 = var_6; + const double var_10 = var_1*w[0][1] + var_3*w[0][5]; + const double var_11 = var_4*w[0][2] + var_5*w[0][4]; + const double var_12 = var_10 + -var_11; + const double var_13 = var_1*w[0][3] + var_3*w[0][0]; + const double var_14 = var_4*w[0][3] + var_5*w[0][0]; + const double var_15 = var_3*var_5 + var_1*var_4; + const double var_16 = -var_1*var_14*var_3 + var_13*var_4*var_5 + var_12*var_15; + const double var_17 = -var_10 + var_11; + const double var_18 = var_3*var_3 + var_4*var_4; + const double var_19 = var_1*var_3*w[0][0] + var_18*w[0][3]; + const double var_20 = var_4*var_5*w[0][3] + var_18*w[0][0]; + const double var_21 = var_19*var_3 + var_17*var_18 + -var_20*var_4; + const double var_22 = var_5*var_5 + var_1*var_1; + const double var_23 = var_1*var_3*w[0][3] + var_22*w[0][0]; + const double var_24 = var_4*var_5*w[0][0] + var_22*w[0][3]; + const double var_25 = var_1*var_23 + var_17*var_22 + -var_24*var_5; + const double var_26 = var_25 + var_21; + const double var_27 = 0.3333333333333333148296163*var_26; + const double var_28 = var_1*var_4*var_4*w[0][0] + -var_3*var_3*var_5*w[0][3]; + const double var_29 = -var_1*var_1*var_4*w[0][0] + var_3*var_5*var_5*w[0][3]; + const double var_30 = var_28 + var_29; + const double var_31 = var_27 + 0.6666666666666666296592325*var_16 + var_30; + A[12] = 0.2539682539682539541558981*var_31*var_8/(var_9*var_9*var_9); + A[825] = A[12]; + A[448] = 0.0000000000000000000000000; + A[477] = A[12]; + const double var_32 = -var_1*var_23 + var_12*var_22 + var_24*var_5; + const double var_33 = 0.1354497354497354588698244*var_32*var_8/(var_9*var_9*var_9); + const double var_34 = 0.0539682539682539708092435*var_16; + const double var_35 = 0.0571428571428571410728559*var_21 + 0.1111111111111111049432054*var_28 + 0.0507936507936507936067372*var_29 + var_34; + A[282] = var_33 + 42.6666666666666642981908808*var_35*var_8/(var_9*var_9*var_9); + const double var_36 = var_1*var_1*var_4*w[0][0] + -var_3*var_5*var_5*w[0][3]; + const double var_37 = var_36 + var_32; + A[36] = 0.0423280423280423256926497*var_37*var_8/(var_9*var_9*var_9); + A[37] = A[36]; + A[195] = 0.0000000000000000000000000; + A[634] = 0.0000000000000000000000000; + A[29] = 0.0000000000000000000000000; + A[380] = 0.0000000000000000000000000; + A[845] = 0.0000000000000000000000000; + const double var_38 = -var_19*var_3 + var_12*var_18 + var_20*var_4; + const double var_39 = var_3*var_3*var_5*w[0][3] + -var_1*var_4*var_4*w[0][0]; + const double var_40 = var_38 + var_39; + A[69] = 0.0423280423280423256926497*var_40*var_8/(var_9*var_9*var_9); + A[737] = A[69]; + const double var_41 = var_16 + var_29; + const double var_42 = 1.3333333333333332593184650*var_38; + const double var_43 = 12.0666666666666664298190881*var_28 + 13.4000000000000003552713679*var_41 + var_42; + const double var_44 = var_39 + 0.1142857142857142821457117*var_38; + const double var_45 = var_1*var_14*var_3 + -var_13*var_4*var_5 + var_15*var_17; + const double var_46 = 0.2952380952380952439106920*var_45; + const double var_47 = 0.3333333333333333148296163*var_44 + 0.0095238095238095246686250*var_25 + 0.2857142857142856984253854*var_36 + var_46; + A[312] = 10.6666666666666660745477202*var_47*var_8/(var_9*var_9*var_9); + A[835] = A[312]; + A[64] = 0.0317460317460317442694873*var_43*var_8/(var_9*var_9*var_9); + A[587] = A[64]; + A[53] = 0.0000000000000000000000000; + const double var_48 = var_45 + var_39; + const double var_49 = 73.6666666666666571927635232*var_32 + 140.6666666666666571927635232*var_36 + 67.0000000000000000000000000*var_48; + A[40] = 0.0063492063492063492008421*var_49*var_8/(var_9*var_9*var_9); + A[766] = A[40]; + const double var_50 = 1.3333333333333332593184650*var_25; + const double var_51 = 14.3333333333333321490954404*var_16; + const double var_52 = var_50 + 15.6666666666666660745477202*var_29 + var_51 + 12.3333333333333321490954404*var_28 + 2.0000000000000000000000000*var_38; + A[219] = 0.0507936507936507936067372*var_52*var_8/(var_9*var_9*var_9); + A[277] = A[219]; + A[208] = 0.0000000000000000000000000; + const double var_53 = var_45 + 2.0000000000000000000000000*var_39 + var_38; + const double var_54 = var_32 + 2.1481481481481479178796690*var_36 + 1.1481481481481481399242739*var_53; + A[93] = 1.8285714285714285143313873*var_54*var_8/(var_9*var_9*var_9); + A[341] = A[93]; + A[584] = 0.0000000000000000000000000; + const double var_55 = 3.8000000000000002664535259*var_48 + 4.0000000000000000000000000*var_36; + const double var_56 = 2.0000000000000000000000000*var_36 + var_32; + const double var_57 = var_45 + var_56; + const double var_58 = 0.8857142857142856762209249*var_57 + var_44; + A[490] = 0.0000000000000000000000000; + A[198] = 0.0000000000000000000000000; + const double var_59 = var_21 + 2.0000000000000000000000000*var_28; + const double var_60 = var_16 + var_59; + A[459] = 0.0000000000000000000000000; + const double var_61 = var_53 + var_56; + A[372] = 5.6888888888888891059991693*var_61*var_8/(var_9*var_9*var_9); + A[434] = A[372]; + A[142] = 0.0000000000000000000000000; + A[493] = 0.0000000000000000000000000; + A[847] = 0.0000000000000000000000000; + const double var_62 = var_38 + var_32; + const double var_63 = var_16 + var_62; + A[95] = 0.3386243386243386055411975*var_63*var_8/(var_9*var_9*var_9); + A[153] = A[95]; + A[258] = 0.0000000000000000000000000; + const double var_64 = 0.1354497354497354588698244*var_38*var_8/(var_9*var_9*var_9); + const double var_65 = 0.3333333333333333148296163*var_45; + const double var_66 = 0.6190476190476190687661529*var_36 + var_65 + 0.2857142857142856984253854*var_32 + 0.3809523809523809312338471*var_39; + A[193] = var_64 + 2.8444444444444445529995846*var_66*var_8/(var_9*var_9*var_9); + A[396] = A[193]; + A[443] = 0.0000000000000000000000000; + const double var_67 = 0.1428571428571428492126927*var_32; + const double var_68 = 0.5904761904761904878213841*var_16; + const double var_69 = var_67 + 0.7333333333333332815229255*var_21 + 0.4476190476190476386086914*var_29 + 1.3238095238095239913889145*var_28 + var_68; + const double var_70 = var_48 + 0.8000000000000000444089210*var_25 + 0.2000000000000000111022302*var_36; + A[221] = 0.0846560846560846513852994*var_70*var_8/(var_9*var_9*var_9); + A[686] = A[221]; + const double var_71 = 0.0158730158730158721347436*var_21; + const double var_72 = 0.0222222222222222230703093*var_16; + const double var_73 = var_71 + var_72 + 0.0380952380952380986744998*var_28 + 0.0285714285714285705364279*var_29; + const double var_74 = 0.3333333333333333148296163*var_60; + const double var_75 = 1.3333333333333332593184650*var_32; + const double var_76 = var_74 + var_36 + var_75; + A[223] = 0.3047619047619047893959987*var_76*var_8/(var_9*var_9*var_9); + const double var_77 = 0.0984126984126984100109681*var_45; + const double var_78 = 0.0444444444444444461406185*var_29; + const double var_79 = var_77 + 0.0253968253968253968033686*var_28 + 0.1238095238095238276310184*var_21 + 0.1428571428571428492126927*var_25 + var_78; + A[125] = 5.3333333333333330372738601*var_79*var_8/(var_9*var_9*var_9); + A[590] = A[125]; + const double var_80 = 0.3333333333333333148296163*var_38 + 1.3333333333333332593184650*var_39 + var_57; + A[281] = 1.0158730158730158166235924*var_8*var_80/(var_9*var_9*var_9); + A[339] = A[281]; + const double var_81 = 0.1428571428571428492126927*var_38; + const double var_82 = var_81 + 0.4476190476190476386086914*var_28 + 1.3238095238095239913889145*var_29 + 0.7333333333333332815229255*var_25 + var_68; + A[9] = 0.8888888888888888395456433*var_8*var_82/(var_9*var_9*var_9); + A[270] = A[9]; + A[644] = 0.0000000000000000000000000; + const double var_83 = var_45 + var_36; + const double var_84 = 0.4000000000000000222044605*var_38 + 0.3333333333333333148296163*var_83 + 0.7333333333333332815229255*var_39; + A[352] = 0.0000000000000000000000000; + A[23] = 0.0000000000000000000000000; + A[379] = 0.0000000000000000000000000; + A[662] = 0.0000000000000000000000000; + A[51] = 0.0000000000000000000000000; + A[873] = 0.0000000000000000000000000; + const double var_85 = var_36 + var_39; + const double var_86 = 0.2000000000000000111022302*var_62 + 0.1703703703703703664640301*var_45 + 0.3703703703703703498106847*var_85; + const double var_87 = 1.3333333333333332593184650*var_21; + const double var_88 = 1.0952380952380951217861593*var_16; + const double var_89 = var_88 + 2.4285714285714283811046243*var_28 + var_87 + 0.9047619047619047671915382*var_29 + 0.1428571428571428492126927*var_75; + A[133] = 2.1333333333333333037273860*var_8*var_89/(var_9*var_9*var_9); + A[859] = A[133]; + const double var_90 = 0.1354497354497354588698244*var_25*var_8/(var_9*var_9*var_9); + const double var_91 = 11.0000000000000000000000000*var_29 + 10.3333333333333321490954404*var_60; + A[101] = var_90 + 0.2031746031746031744269487*var_8*var_91/(var_9*var_9*var_9); + const double var_92 = 1.5714285714285713968507707*var_16; + const double var_93 = var_50 + 2.9047619047619046561692357*var_29 + 0.0476190476190476164042309*var_21 + 1.6190476190476190687661529*var_28 + var_92; + A[224] = 2.1333333333333333037273860*var_8*var_93/(var_9*var_9*var_9); + A[534] = A[69]; + A[502] = A[36]; + A[21] = 0.0000000000000000000000000; + A[701] = 0.0000000000000000000000000; + A[56] = 0.0000000000000000000000000; + const double var_94 = 1.2222222222222220988641084*var_45; + const double var_95 = 2.2222222222222223209087133*var_39 + var_94 + 0.1333333333333333314829616*var_32 + 1.3555555555555556246360993*var_36 + var_38; + A[100] = 0.7619047619047618624676943*var_8*var_95/(var_9*var_9*var_9); + const double var_96 = 0.1333333333333333314829616*var_38 + 2.2222222222222223209087133*var_36 + var_32 + 1.3555555555555556246360993*var_39 + var_94; + A[157] = 0.7619047619047618624676943*var_8*var_96/(var_9*var_9*var_9); + A[215] = A[157]; + A[464] = 0.0000000000000000000000000; + A[347] = 0.0000000000000000000000000; + A[255] = 0.0000000000000000000000000; + A[232] = 0.0000000000000000000000000; + const double var_97 = 0.6190476190476190687661529*var_39 + 0.3809523809523809312338471*var_36 + var_65 + 0.2857142857142856984253854*var_38; + A[283] = var_33 + 2.8444444444444445529995846*var_8*var_97/(var_9*var_9*var_9); + A[399] = A[283]; + const double var_98 = 73.6666666666666571927635232*var_38 + 67.0000000000000000000000000*var_83 + 140.6666666666666571927635232*var_39; + A[67] = 0.0063492063492063492008421*var_8*var_98/(var_9*var_9*var_9); + A[677] = A[67]; + A[346] = 0.0000000000000000000000000; + A[207] = 0.0000000000000000000000000; + A[864] = A[283]; + const double var_99 = var_28 + var_16; + const double var_100 = 0.2031746031746031744269487*var_8*var_99/(var_9*var_9*var_9); + const double var_101 = 0.5417989417989418354792974*var_29*var_8/(var_9*var_9*var_9); + A[98] = var_100 + 0.3386243386243386055411975*var_25*var_8/(var_9*var_9*var_9) + var_101; + A[243] = A[98]; + A[794] = 0.0000000000000000000000000; + const double var_102 = 0.1111111111111111049432054*var_29 + 0.0507936507936507936067372*var_28 + 0.0571428571428571410728559*var_25 + var_34; + A[192] = var_64 + 42.6666666666666642981908808*var_102*var_8/(var_9*var_9*var_9); + A[366] = A[192]; + A[871] = 0.0000000000000000000000000; + A[814] = 0.0000000000000000000000000; + const double var_103 = 1.0380952380952381819412267*var_16; + const double var_104 = 1.4095238095238096232009184*var_28 + 0.3714285714285714412596917*var_21 + 2.1333333333333333037273860*var_29 + 1.0952380952380951217861593*var_25 + var_103; + A[280] = 1.7777777777777776790912867*var_104*var_8/(var_9*var_9*var_9); + A[774] = A[280]; + A[747] = A[282]; + A[48] = 0.0000000000000000000000000; + const double var_105 = 0.3333333333333333148296163*var_25 + 1.2666666666666666074547720*var_36 + 1.6000000000000000888178420*var_48; + A[35] = 0.1269841269841269770779490*var_105*var_8/(var_9*var_9*var_9); + A[151] = A[35]; + const double var_106 = 17.0000000000000000000000000*var_45 + 21.4444444444444428654605872*var_62 + 38.4444444444444428654605872*var_85; + A[124] = 0.1142857142857142821457117*var_106*var_8/(var_9*var_9*var_9); + A[878] = 0.0000000000000000000000000; + A[235] = 0.0000000000000000000000000; + A[574] = 0.0000000000000000000000000; + const double var_107 = var_25 + var_29; + A[42] = 0.0846560846560846513852994*var_107*var_8/(var_9*var_9*var_9); + A[886] = A[42]; + const double var_108 = var_38 + 7.1333333333333328596381762*var_39 + 6.1333333333333328596381762*var_83; + A[65] = 0.1269841269841269770779490*var_108*var_8/(var_9*var_9*var_9); + A[617] = A[65]; + A[355] = 0.0000000000000000000000000; + A[389] = 0.0000000000000000000000000; + A[699] = 0.0000000000000000000000000; + A[420] = A[12]; + A[152] = A[65]; + A[639] = 0.0000000000000000000000000; + const double var_109 = var_28 + var_21; + A[72] = 0.0846560846560846513852994*var_109*var_8/(var_9*var_9*var_9); + A[362] = A[72]; + A[43] = A[42]; + const double var_110 = 2.0000000000000000000000000*var_29 + var_25; + A[96] = var_100 + 0.2031746031746031744269487*var_110*var_8/(var_9*var_9*var_9); + A[648] = A[96]; + A[536] = A[69]; + const double var_111 = 0.5417989417989418354792974*var_28*var_8/(var_9*var_9*var_9); + A[702] = 0.0000000000000000000000000; + A[342] = var_33 + 0.6772486772486772110823949*var_8*var_99/(var_9*var_9*var_9) + var_101; + A[836] = A[342]; + const double var_112 = 0.1111111111111111049432054*var_45; + const double var_113 = var_81 + 0.0126984126984126984016843*var_25 + 0.0984126984126984100109681*var_36 + 0.2539682539682539541558981*var_39 + var_112; + A[131] = 5.3333333333333330372738601*var_113*var_8/(var_9*var_9*var_9); + A[334] = A[131]; + A[28] = 0.0000000000000000000000000; + A[6] = 0.8888888888888888395456433*var_69*var_8/(var_9*var_9*var_9); + const double var_114 = 0.1079365079365079416184869*var_16; + const double var_115 = 0.2000000000000000111022302*var_39 + 0.8000000000000000444089210*var_21 + var_83; + A[250] = 0.0846560846560846513852994*var_115*var_8/(var_9*var_9*var_9); + A[308] = A[250]; + A[661] = 0.0000000000000000000000000; + A[874] = 0.0000000000000000000000000; + const double var_116 = 2.6888888888888891059991693*var_16; + const double var_117 = 3.6888888888888891059991693*var_28 + 2.5555555555555553581825734*var_25 + 5.2444444444444444641817427*var_29 + var_21 + var_116; + A[19] = 0.0000000000000000000000000; + A[186] = 9.1428571428571423496123316*var_8*var_86/(var_9*var_9*var_9); + A[744] = A[186]; + const double var_118 = 1.3333333333333332593184650*var_36 + 0.3333333333333333148296163*var_32 + var_53; + A[188] = 1.0158730158730158166235924*var_118*var_8/(var_9*var_9*var_9); + A[419] = 0.0000000000000000000000000; + A[337] = A[221]; + A[162] = 2.0317460317460316332471848*var_8*var_84/(var_9*var_9*var_9); + A[860] = A[162]; + const double var_119 = var_38 + 2.1481481481481479178796690*var_39 + 1.1481481481481481399242739*var_57; + A[155] = 1.8285714285714285143313873*var_119*var_8/(var_9*var_9*var_9); + A[713] = A[155]; + A[537] = A[72]; + const double var_120 = 0.7650793650793650257924128*var_45; + const double var_121 = 1.4666666666666665630458510*var_39 + 0.7015873015873015372534383*var_38 + 0.0634920634920634885389745*var_32 + 0.8285714285714285143313873*var_36 + var_120; + A[7] = 0.6666666666666666296592325*var_121*var_8/(var_9*var_9*var_9); + const double var_122 = 0.4444444444444444197728217*var_62 + 1.4444444444444444197728217*var_85 + var_45; + A[132] = 0.9142857142857142571656937*var_122*var_8/(var_9*var_9*var_9); + A[829] = A[132]; + A[822] = 0.0000000000000000000000000; + A[179] = 0.0000000000000000000000000; + A[820] = 0.0000000000000000000000000; + A[397] = A[223]; + const double var_123 = 0.0666666666666666657414808*var_25 + 0.4000000000000000222044605*var_29 + var_74; + A[374] = 12.1904761904761897994831088*var_123*var_8/(var_9*var_9*var_9); + A[432] = A[374]; + A[821] = 0.0000000000000000000000000; + A[487] = 0.0000000000000000000000000; + A[868] = A[372]; + A[598] = A[133]; + const double var_124 = 1.4444444444444444197728217*var_16; + A[601] = 0.0000000000000000000000000; + A[855] = A[12]; + A[659] = A[193]; + A[323] = 0.0000000000000000000000000; + A[846] = 0.0000000000000000000000000; + A[267] = 0.0000000000000000000000000; + A[293] = 0.0000000000000000000000000; + const double var_125 = 0.4000000000000000222044605*var_32 + 0.3333333333333333148296163*var_48 + 0.7333333333333332815229255*var_36; + A[102] = 2.0317460317460316332471848*var_125*var_8/(var_9*var_9*var_9); + A[828] = A[102]; + A[554] = 0.0000000000000000000000000; + A[45] = 0.0000000000000000000000000; + A[301] = A[40]; + A[237] = 0.0000000000000000000000000; + A[257] = 0.0000000000000000000000000; + A[381] = 0.0000000000000000000000000; + A[530] = A[65]; + A[272] = A[69]; + const double var_126 = 11.0000000000000000000000000*var_21 + 13.1428571428571423496123316*var_41 + 24.1428571428571423496123316*var_28; + A[68] = 0.0592592592592592615208247*var_126*var_8/(var_9*var_9*var_9); + A[533] = A[68]; + A[117] = 0.0000000000000000000000000; + A[138] = 0.0000000000000000000000000; + const double var_127 = 6.1333333333333328596381762*var_48 + 7.1333333333333328596381762*var_36 + var_32; + A[33] = 0.1269841269841269770779490*var_127*var_8/(var_9*var_9*var_9); + A[91] = A[33]; + A[266] = 0.0000000000000000000000000; + const double var_128 = 0.1142857142857142821457117*var_32 + var_36; + const double var_129 = 0.3333333333333333148296163*var_128 + 0.2857142857142856984253854*var_39 + var_46 + 0.0095238095238095246686250*var_21; + const double var_130 = 2.9047619047619046561692357*var_28 + var_92 + 0.0476190476190476164042309*var_25 + 1.6190476190476190687661529*var_29 + var_87; + A[313] = 2.1333333333333333037273860*var_130*var_8/(var_9*var_9*var_9); + const double var_131 = var_85 + 0.3333333333333333148296163*var_62; + const double var_132 = 0.6666666666666666296592325*var_45 + var_131; + A[3] = 0.1269841269841269770779490*var_132*var_8/(var_9*var_9*var_9); + A[5] = A[3]; + const double var_133 = 2.5555555555555553581825734*var_21 + var_25 + 3.6888888888888891059991693*var_29 + 5.2444444444444444641817427*var_28 + var_116; + A[218] = 0.7619047619047618624676943*var_133*var_8/(var_9*var_9*var_9); + A[712] = A[218]; + const double var_134 = 77.6666666666666571927635232*var_53 + 64.3333333333333285963817616*var_32 + 142.0000000000000000000000000*var_36; + A[217] = 0.0380952380952380986744998*var_134*var_8/(var_9*var_9*var_9); + A[883] = 0.0000000000000000000000000; + const double var_135 = var_21 + 2.4444444444444441977282167*var_28 + 1.8888888888888888395456433*var_29 + 0.4444444444444444197728217*var_25 + var_124; + A[129] = 0.1523809523809523946979994*var_135*var_8/(var_9*var_9*var_9); + A[594] = A[129]; + const double var_136 = 29.0000000000000000000000000*var_25 + 53.0000000000000000000000000*var_29; + A[39] = var_100 + 0.0084656084656084661793640*var_136*var_8/(var_9*var_9*var_9); + A[736] = A[39]; + A[177] = 0.0000000000000000000000000; + A[680] = A[157]; + A[670] = 0.0000000000000000000000000; + A[405] = 0.0000000000000000000000000; + const double var_137 = 0.0634920634920634885389745*var_38 + 1.4666666666666665630458510*var_36 + 0.7015873015873015372534383*var_32 + 0.8285714285714285143313873*var_39 + var_120; + A[10] = 0.6666666666666666296592325*var_137*var_8/(var_9*var_9*var_9); + A[475] = A[10]; + A[140] = 0.0000000000000000000000000; + const double var_138 = 0.0158730158730158721347436*var_25; + const double var_139 = var_138 + 0.0380952380952380986744998*var_29 + 0.0285714285714285705364279*var_28 + var_72; + A[175] = 0.0000000000000000000000000; + const double var_140 = var_16 + var_110; + const double var_141 = 0.3333333333333333148296163*var_140; + const double var_142 = var_141 + var_39 + var_42; + A[314] = 0.3047619047619047893959987*var_142*var_8/(var_9*var_9*var_9); + A[779] = A[314]; + const double var_143 = var_138 + 0.1238095238095238276310184*var_29 + 0.2000000000000000111022302*var_28 + 0.0920634920634920694837433*var_21 + var_114; + A[8] = 2.6666666666666665186369300*var_143*var_8/(var_9*var_9*var_9); + A[240] = A[8]; + A[494] = 0.0000000000000000000000000; + A[225] = 0.0000000000000000000000000; + A[665] = 0.0000000000000000000000000; + A[227] = 0.0000000000000000000000000; + A[535] = A[69]; + A[408] = 0.0000000000000000000000000; + const double var_144 = var_28 + var_41; + const double var_145 = 0.0444444444444444461406185*var_28; + const double var_146 = 0.0285714285714285705364279*var_21 + 0.0158730158730158721347436*var_41 + var_145; + A[414] = 0.0000000000000000000000000; + A[423] = A[102]; + A[768] = A[100]; + A[394] = A[133]; + A[802] = A[221]; + A[500] = A[35]; + A[149] = 0.0000000000000000000000000; + A[252] = var_64 + 0.6772486772486772110823949*var_41*var_8/(var_9*var_9*var_9) + var_111; + A[398] = A[252]; + A[264] = 0.0000000000000000000000000; + A[786] = 0.0000000000000000000000000; + A[582] = 0.0000000000000000000000000; + A[386] = 0.0000000000000000000000000; + A[26] = 0.0000000000000000000000000; + A[135] = 0.0000000000000000000000000; + const double var_147 = 4.1111111111111107163651468*var_29 + 2.1111111111111111604543567*var_99 + 2.0000000000000000000000000*var_25; + A[103] = 1.2190476190476191575839948*var_147*var_8/(var_9*var_9*var_9); + A[568] = A[103]; + A[628] = A[162]; + A[570] = 0.0000000000000000000000000; + A[618] = A[95]; + A[290] = 0.0000000000000000000000000; + A[524] = 0.0000000000000000000000000; + A[309] = A[280]; + A[596] = A[131]; + A[733] = 0.0000000000000000000000000; + const double var_148 = 12.3333333333333321490954404*var_29 + var_87 + var_51 + 2.0000000000000000000000000*var_32 + 15.6666666666666660745477202*var_28; + A[190] = 0.0507936507936507936067372*var_148*var_8/(var_9*var_9*var_9); + A[306] = A[190]; + A[875] = 0.0000000000000000000000000; + A[816] = 0.0000000000000000000000000; + A[144] = 0.0000000000000000000000000; + A[856] = A[42]; + const double var_149 = var_21 + 3.8000000000000002664535259*var_39; + const double var_150 = var_67 + 0.0126984126984126984016843*var_21 + 0.0984126984126984100109681*var_39 + var_112 + 0.2539682539682539541558981*var_36; + A[128] = 5.3333333333333330372738601*var_150*var_8/(var_9*var_9*var_9); + A[244] = A[128]; + const double var_151 = var_71 + var_114 + 0.0920634920634920694837433*var_25 + 0.2000000000000000111022302*var_29 + 0.1238095238095238276310184*var_28; + A[108] = 0.0000000000000000000000000; + A[150] = A[3]; + A[675] = A[7]; + A[777] = A[312]; + A[663] = 0.0000000000000000000000000; + A[274] = A[129]; + const double var_152 = var_77 + 0.1238095238095238276310184*var_25 + 0.0253968253968253968033686*var_29 + 0.1428571428571428492126927*var_21 + var_145; + A[94] = 5.3333333333333330372738601*var_152*var_8/(var_9*var_9*var_9); + A[123] = A[94]; + A[676] = A[36]; + A[110] = 0.0000000000000000000000000; + A[59] = 0.0000000000000000000000000; + A[764] = 0.0000000000000000000000000; + const double var_153 = var_48 + 0.3333333333333333148296163*var_36; + A[843] = 0.0000000000000000000000000; + A[603] = 0.0000000000000000000000000; + A[294] = 0.0000000000000000000000000; + A[268] = 0.0000000000000000000000000; + A[788] = 0.0000000000000000000000000; + A[558] = A[93]; + A[326] = 0.0000000000000000000000000; + A[765] = A[10]; + A[76] = 0.0000000000000000000000000; + A[70] = A[69]; + A[407] = 0.0000000000000000000000000; + A[669] = 0.0000000000000000000000000; + A[503] = A[36]; + A[635] = 0.0000000000000000000000000; + const double var_154 = 0.1354497354497354588698244*var_21*var_8/(var_9*var_9*var_9); + const double var_155 = 0.2000000000000000111022302*var_45 + 0.1851851851851851749053424*var_85; + A[189] = var_90 + var_154 + 9.1428571428571423496123316*var_155*var_8/(var_9*var_9*var_9); + A[276] = A[189]; + A[298] = 0.0000000000000000000000000; + A[31] = 0.3730158730158730229220510*var_37*var_8/(var_9*var_9*var_9); + A[496] = A[31]; + A[720] = 0.0000000000000000000000000; + A[857] = A[72]; + A[684] = A[219]; + A[471] = A[6]; + A[222] = 10.6666666666666660745477202*var_129*var_8/(var_9*var_9*var_9); + A[367] = A[222]; + A[191] = var_90 + 0.2031746031746031744269487*var_153*var_8/(var_9*var_9*var_9); + A[336] = A[191]; + A[742] = A[219]; + A[127] = 0.4444444444444444197728217*var_58*var_8/(var_9*var_9*var_9); + A[592] = A[127]; + A[872] = 0.0000000000000000000000000; + A[236] = 0.0000000000000000000000000; + A[515] = 0.0000000000000000000000000; + A[556] = A[33]; + const double var_156 = 4.1111111111111107163651468*var_28 + 2.0000000000000000000000000*var_21 + 2.1111111111111111604543567*var_41; + A[164] = 1.2190476190476191575839948*var_156*var_8/(var_9*var_9*var_9); + A[315] = 0.0000000000000000000000000; + A[725] = 0.0000000000000000000000000; + A[897] = A[374]; + A[715] = A[250]; + const double var_157 = 1.0952380952380951217861593*var_21 + 2.1333333333333333037273860*var_28 + 0.3714285714285714412596917*var_25 + 1.4095238095238096232009184*var_29 + var_103; + A[488] = 0.0000000000000000000000000; + A[514] = 0.0000000000000000000000000; + A[441] = 0.0000000000000000000000000; + A[435] = 0.0000000000000000000000000; + const double var_158 = 1.8888888888888888395456433*var_28 + var_25 + 2.4444444444444441977282167*var_29 + 0.4444444444444444197728217*var_21 + var_124; + A[126] = 0.1523809523809523946979994*var_158*var_8/(var_9*var_9*var_9); + A[241] = A[36]; + A[32] = 0.0566137566137566161650341*var_144*var_8/(var_9*var_9*var_9); + A[679] = A[127]; + const double var_159 = 0.0158730158730158721347436*var_99 + 0.0285714285714285705364279*var_25 + var_78; + A[97] = 5.3333333333333330372738601*var_159*var_8/(var_9*var_9*var_9); + A[213] = A[97]; + A[351] = 0.0000000000000000000000000; + const double var_160 = var_38 + var_83; + const double var_161 = var_39 + 0.5000000000000000000000000*var_160; + A[2] = 0.1132275132275132323300681*var_161*var_8/(var_9*var_9*var_9); + A[467] = A[2]; + A[606] = 0.0000000000000000000000000; + A[607] = 0.0000000000000000000000000; + A[279] = A[186]; + A[752] = 0.0000000000000000000000000; + A[449] = 0.0000000000000000000000000; + A[180] = A[6]; + A[194] = A[193]; + A[13] = A[12]; + A[761] = 0.0000000000000000000000000; + A[413] = 0.0000000000000000000000000; + A[834] = A[282]; + A[469] = A[3]; + A[425] = A[164]; + A[122] = A[64]; + A[602] = 0.0000000000000000000000000; + A[412] = 0.0000000000000000000000000; + A[85] = 0.0000000000000000000000000; + const double var_162 = 0.2031746031746031744269487*var_8*var_83/(var_9*var_9*var_9); + A[249] = var_154 + 0.0677248677248677294349122*var_39*var_8/(var_9*var_9*var_9) + var_162; + A[714] = A[249]; + A[484] = 0.0000000000000000000000000; + A[841] = 0.0000000000000000000000000; + A[746] = A[281]; + A[169] = 0.0000000000000000000000000; + A[771] = A[190]; + A[630] = 0.0000000000000000000000000; + A[384] = 0.0000000000000000000000000; + A[731] = 0.0000000000000000000000000; + const double var_163 = 11.0000000000000000000000000*var_28 + 10.3333333333333321490954404*var_140; + A[780] = 0.0000000000000000000000000; + A[810] = 0.0000000000000000000000000; + A[320] = 0.0000000000000000000000000; + A[311] = 0.7619047619047618624676943*var_117*var_8/(var_9*var_9*var_9); + A[776] = A[311]; + A[877] = 0.0000000000000000000000000; + A[364] = A[132]; + A[501] = A[36]; + A[363] = A[102]; + A[695] = 0.0000000000000000000000000; + A[271] = A[39]; + A[827] = A[72]; + A[756] = 0.0000000000000000000000000; + A[729] = 0.0000000000000000000000000; + A[522] = 0.0000000000000000000000000; + A[865] = A[313]; + A[734] = 0.0000000000000000000000000; + A[672] = 0.0000000000000000000000000; + A[760] = 0.0000000000000000000000000; + A[269] = 0.0000000000000000000000000; + A[87] = 0.0000000000000000000000000; + A[549] = 0.0000000000000000000000000; + A[360] = A[12]; + A[700] = 0.0000000000000000000000000; + A[826] = A[42]; + const double var_164 = 0.4000000000000000222044605*var_28 + 0.0666666666666666657414808*var_21 + var_141; + A[373] = 12.1904761904761897994831088*var_164*var_8/(var_9*var_9*var_9); + A[838] = A[373]; + A[289] = 0.0000000000000000000000000; + A[357] = 0.0000000000000000000000000; + const double var_165 = var_48 + var_32; + const double var_166 = var_36 + 0.5000000000000000000000000*var_165; + A[1] = 0.1132275132275132323300681*var_166*var_8/(var_9*var_9*var_9); + A[466] = A[1]; + A[588] = A[94]; + A[653] = A[188]; + A[158] = var_154 + 0.2031746031746031744269487*var_163*var_8/(var_9*var_9*var_9); + A[710] = A[158]; + A[851] = 0.0000000000000000000000000; + A[156] = var_154 + 21.3333333333333321490954404*var_139*var_8/(var_9*var_9*var_9); + A[621] = A[156]; + A[437] = 0.0000000000000000000000000; + const double var_167 = var_88 + 2.4285714285714283811046243*var_29 + var_50 + 0.9047619047619047671915382*var_28 + 0.1428571428571428492126927*var_42; + A[134] = 2.1333333333333333037273860*var_167*var_8/(var_9*var_9*var_9); + A[892] = A[224]; + A[787] = 0.0000000000000000000000000; + A[473] = A[8]; + A[16] = 0.0000000000000000000000000; + A[555] = A[3]; + A[612] = 0.0000000000000000000000000; + const double var_168 = 0.8857142857142856762209249*var_53 + var_128; + const double var_169 = var_45 + 0.6666666666666666296592325*var_85 + var_27; + A[404] = 2.4380952380952383151679896*var_169*var_8/(var_9*var_9*var_9); + A[869] = A[404]; + A[579] = 0.0000000000000000000000000; + A[54] = 0.0000000000000000000000000; + A[483] = 0.0000000000000000000000000; + const double var_170 = 0.2031746031746031744269487*var_41*var_8/(var_9*var_9*var_9); + A[159] = var_170 + 0.2031746031746031744269487*var_59*var_8/(var_9*var_9*var_9); + A[624] = A[159]; + A[813] = 0.0000000000000000000000000; + A[809] = A[342]; + A[130] = 0.4444444444444444197728217*var_168*var_8/(var_9*var_9*var_9); + A[595] = A[130]; + A[344] = A[342]; + A[185] = A[156]; + A[541] = 0.0000000000000000000000000; + A[538] = A[72]; + A[462] = 0.0000000000000000000000000; + A[623] = A[158]; + A[548] = 0.0000000000000000000000000; + A[656] = A[191]; + A[727] = 0.0000000000000000000000000; + A[517] = 0.0000000000000000000000000; + A[348] = 0.0000000000000000000000000; + A[593] = A[128]; + A[62] = 0.3730158730158730229220510*var_40*var_8/(var_9*var_9*var_9); + A[527] = A[62]; + const double var_171 = 3.8000000000000002664535259*var_83 + 4.0000000000000000000000000*var_39; + A[254] = var_64 + 0.6772486772486772110823949*var_171*var_8/(var_9*var_9*var_9); + A[200] = 0.0000000000000000000000000; + A[660] = 0.0000000000000000000000000; + A[63] = var_162 + 0.0423280423280423256926497*var_149*var_8/(var_9*var_9*var_9); + A[528] = A[63]; + const double var_172 = 64.3333333333333285963817616*var_38 + 77.6666666666666571927635232*var_57 + 142.0000000000000000000000000*var_39; + A[310] = 0.0380952380952380986744998*var_172*var_8/(var_9*var_9*var_9); + A[92] = A[63]; + A[365] = A[162]; + A[591] = A[126]; + A[176] = 0.0000000000000000000000000; + A[722] = 0.0000000000000000000000000; + A[654] = A[189]; + A[80] = 0.0000000000000000000000000; + A[691] = 0.0000000000000000000000000; + A[278] = A[249]; + A[717] = A[252]; + A[303] = A[100]; + const double var_173 = 11.0000000000000000000000000*var_25 + 24.1428571428571423496123316*var_29 + 13.1428571428571423496123316*var_99; + A[172] = 0.0000000000000000000000000; + A[705] = A[8]; + A[560] = A[95]; + A[597] = A[132]; + A[799] = A[131]; + A[446] = 0.0000000000000000000000000; + A[160] = 5.3333333333333330372738601*var_146*var_8/(var_9*var_9*var_9); + A[770] = A[160]; + A[146] = 0.0000000000000000000000000; + A[896] = A[342]; + A[817] = 0.0000000000000000000000000; + A[792] = 0.0000000000000000000000000; + A[451] = 0.0000000000000000000000000; + A[206] = 0.0000000000000000000000000; + A[4] = A[3]; + A[563] = A[98]; + A[478] = A[12]; + A[812] = 0.0000000000000000000000000; + A[519] = 0.0000000000000000000000000; + A[858] = A[103]; + A[882] = 0.0000000000000000000000000; + A[245] = A[158]; + const double var_174 = 29.0000000000000000000000000*var_21 + 53.0000000000000000000000000*var_28; + A[66] = var_170 + 0.0084656084656084661793640*var_174*var_8/(var_9*var_9*var_9); + A[182] = A[66]; + A[415] = 0.0000000000000000000000000; + A[377] = 0.0000000000000000000000000; + A[444] = 0.0000000000000000000000000; + A[657] = A[192]; + A[161] = var_170 + 0.3386243386243386055411975*var_21*var_8/(var_9*var_9*var_9) + var_111; + A[335] = A[161]; + const double var_175 = 23.0000000000000000000000000*var_16 + 4.0000000000000000000000000*var_62 + 19.0000000000000000000000000*var_30; + A[220] = 0.0126984126984126984016843*var_175*var_8/(var_9*var_9*var_9); + A[463] = 0.0000000000000000000000000; + A[696] = 0.0000000000000000000000000; + A[354] = 0.0000000000000000000000000; + A[112] = 0.0000000000000000000000000; + A[751] = 0.0000000000000000000000000; + A[460] = 0.0000000000000000000000000; + A[614] = 0.0000000000000000000000000; + A[697] = 0.0000000000000000000000000; + A[833] = A[252]; + A[848] = 0.0000000000000000000000000; + A[557] = A[63]; + A[693] = 0.0000000000000000000000000; + A[321] = 0.0000000000000000000000000; + A[168] = 0.0000000000000000000000000; + A[174] = 0.0000000000000000000000000; + A[229] = 0.0000000000000000000000000; + A[378] = 0.0000000000000000000000000; + A[511] = 0.0000000000000000000000000; + A[41] = 0.0592592592592592615208247*var_173*var_8/(var_9*var_9*var_9); + A[506] = A[41]; + A[577] = 0.0000000000000000000000000; + A[616] = A[35]; + A[74] = A[72]; + A[343] = var_33 + 0.6772486772486772110823949*var_55*var_8/(var_9*var_9*var_9); + A[251] = 0.2031746031746031744269487*var_39*var_8/(var_9*var_9*var_9) + var_162; + A[803] = A[251]; + A[52] = 0.0000000000000000000000000; + A[391] = A[42]; + A[636] = 0.0000000000000000000000000; + A[640] = 0.0000000000000000000000000; + const double var_176 = 12.0666666666666664298190881*var_29 + 13.4000000000000003552713679*var_99 + var_75; + A[34] = 0.0317460317460317442694873*var_176*var_8/(var_9*var_9*var_9); + A[586] = A[34]; + A[154] = A[125]; + A[292] = 0.0000000000000000000000000; + A[392] = A[72]; + A[452] = 0.0000000000000000000000000; + const double var_177 = 0.5000000000000000000000000*var_131 + var_65; + A[228] = 0.0000000000000000000000000; + A[879] = 0.0000000000000000000000000; + A[14] = A[12]; + A[510] = 0.0000000000000000000000000; + A[120] = A[3]; + A[611] = 0.0000000000000000000000000; + A[891] = A[193]; + A[369] = A[282]; + A[358] = 0.0000000000000000000000000; + A[544] = 0.0000000000000000000000000; + A[291] = 0.0000000000000000000000000; + A[728] = 0.0000000000000000000000000; + A[319] = 0.0000000000000000000000000; + A[440] = 0.0000000000000000000000000; + A[641] = 0.0000000000000000000000000; + A[807] = A[342]; + A[683] = A[218]; + A[409] = 0.0000000000000000000000000; + A[895] = A[314]; + A[410] = 0.0000000000000000000000000; + A[77] = 0.0000000000000000000000000; + A[542] = 0.0000000000000000000000000; + A[726] = 0.0000000000000000000000000; + A[431] = A[342]; + A[295] = 0.0000000000000000000000000; + A[850] = 0.0000000000000000000000000; + A[350] = 0.0000000000000000000000000; + A[531] = A[66]; + A[718] = A[252]; + A[287] = 0.0000000000000000000000000; + A[333] = A[101]; + A[719] = A[254]; + A[651] = A[186]; + A[261] = 0.0000000000000000000000000; + A[485] = 0.0000000000000000000000000; + A[187] = 1.7777777777777776790912867*var_157*var_8/(var_9*var_9*var_9); + A[137] = 0.0000000000000000000000000; + A[539] = A[72]; + A[430] = A[314]; + A[646] = A[36]; + A[681] = A[187]; + A[638] = 0.0000000000000000000000000; + A[265] = 0.0000000000000000000000000; + A[99] = var_90 + 21.3333333333333321490954404*var_73*var_8/(var_9*var_9*var_9); + A[564] = A[99]; + A[209] = 0.0000000000000000000000000; + A[706] = A[36]; + A[375] = 0.0000000000000000000000000; + A[89] = 0.0000000000000000000000000; + A[782] = 0.0000000000000000000000000; + A[461] = 0.0000000000000000000000000; + A[201] = 0.0000000000000000000000000; + A[24] = 0.0000000000000000000000000; + A[540] = 0.0000000000000000000000000; + A[44] = A[42]; + A[543] = 0.0000000000000000000000000; + A[322] = 0.0000000000000000000000000; + A[620] = A[155]; + A[862] = A[223]; + A[427] = A[224]; + A[105] = 0.0000000000000000000000000; + A[422] = A[72]; + A[724] = 0.0000000000000000000000000; + A[181] = A[36]; + A[55] = 0.0000000000000000000000000; + A[259] = 0.0000000000000000000000000; + A[690] = 0.0000000000000000000000000; + A[520] = 0.0000000000000000000000000; + A[523] = 0.0000000000000000000000000; + A[889] = A[134]; + A[566] = A[101]; + A[233] = 0.0000000000000000000000000; + A[772] = A[220]; + A[645] = A[6]; + A[248] = A[155]; + A[345] = 0.0000000000000000000000000; + A[887] = A[72]; + A[730] = 0.0000000000000000000000000; + A[832] = A[222]; + A[707] = A[68]; + A[167] = 0.0000000000000000000000000; + A[199] = 0.0000000000000000000000000; + A[740] = A[159]; + A[230] = 0.0000000000000000000000000; + A[572] = 0.0000000000000000000000000; + A[454] = 0.0000000000000000000000000; + A[890] = A[164]; + A[658] = A[193]; + A[767] = A[69]; + A[170] = 0.0000000000000000000000000; + A[239] = 0.0000000000000000000000000; + A[38] = A[36]; + A[575] = 0.0000000000000000000000000; + A[497] = A[32]; + A[806] = A[93]; + A[368] = A[252]; + A[798] = A[101]; + A[324] = 0.0000000000000000000000000; + A[171] = 0.0000000000000000000000000; + A[899] = A[372]; + A[842] = 0.0000000000000000000000000; + A[47] = 0.0000000000000000000000000; + A[518] = 0.0000000000000000000000000; + A[796] = A[41]; + A[118] = 0.0000000000000000000000000; + A[285] = 0.0000000000000000000000000; + A[472] = A[7]; + A[82] = 0.0000000000000000000000000; + A[433] = A[404]; + A[763] = 0.0000000000000000000000000; + A[376] = 0.0000000000000000000000000; + A[569] = A[102]; + A[884] = 0.0000000000000000000000000; + A[119] = 0.0000000000000000000000000; + A[576] = 0.0000000000000000000000000; + A[456] = 0.0000000000000000000000000; + A[831] = A[192]; + A[253] = A[252]; + A[447] = 0.0000000000000000000000000; + A[71] = A[69]; + A[288] = 0.0000000000000000000000000; + A[824] = 0.0000000000000000000000000; + A[359] = 0.0000000000000000000000000; + A[242] = A[68]; + A[429] = A[283]; + A[141] = 0.0000000000000000000000000; + A[529] = A[64]; + A[580] = 0.0000000000000000000000000; + A[783] = 0.0000000000000000000000000; + A[401] = A[343]; + A[667] = 0.0000000000000000000000000; + A[231] = 0.0000000000000000000000000; + A[551] = 0.0000000000000000000000000; + A[403] = A[372]; + A[552] = 0.0000000000000000000000000; + A[880] = 0.0000000000000000000000000; + A[800] = A[161]; + A[674] = 0.0000000000000000000000000; + A[305] = A[160]; + A[692] = 0.0000000000000000000000000; + A[17] = 0.0000000000000000000000000; + A[583] = 0.0000000000000000000000000; + A[145] = 0.0000000000000000000000000; + A[721] = 0.0000000000000000000000000; + A[417] = 0.0000000000000000000000000; + A[332] = A[69]; + A[480] = 0.0000000000000000000000000; + A[442] = 0.0000000000000000000000000; + A[629] = A[164]; + A[482] = 0.0000000000000000000000000; + A[668] = 0.0000000000000000000000000; + A[888] = A[102]; + A[416] = 0.0000000000000000000000000; + A[165] = 0.0000000000000000000000000; + A[608] = 0.0000000000000000000000000; + A[393] = A[103]; + A[136] = 0.0000000000000000000000000; + A[854] = 0.0000000000000000000000000; + A[58] = 0.0000000000000000000000000; + A[489] = 0.0000000000000000000000000; + A[90] = A[3]; + A[852] = 0.0000000000000000000000000; + A[652] = A[187]; + A[226] = 0.0000000000000000000000000; + A[561] = A[96]; + A[426] = A[193]; + A[60] = A[2]; + A[755] = 0.0000000000000000000000000; + A[328] = 0.0000000000000000000000000; + A[455] = 0.0000000000000000000000000; + A[811] = 0.0000000000000000000000000; + A[743] = A[249]; + A[870] = 0.0000000000000000000000000; + A[356] = 0.0000000000000000000000000; + A[370] = A[312]; + A[863] = A[252]; + A[214] = A[127]; + A[694] = 0.0000000000000000000000000; + A[11] = 2.6666666666666665186369300*var_151*var_8/(var_9*var_9*var_9); + A[795] = A[11]; + A[304] = A[130]; + A[338] = A[251]; + A[781] = 0.0000000000000000000000000; + A[559] = A[94]; + A[625] = A[160]; + A[732] = 0.0000000000000000000000000; + A[113] = 0.0000000000000000000000000; + A[704] = 0.0000000000000000000000000; + A[418] = 0.0000000000000000000000000; + A[445] = 0.0000000000000000000000000; + A[547] = 0.0000000000000000000000000; + A[605] = 0.0000000000000000000000000; + A[263] = 0.0000000000000000000000000; + A[107] = 0.0000000000000000000000000; + A[204] = 0.0000000000000000000000000; + A[476] = A[11]; + A[830] = A[162]; + A[296] = 0.0000000000000000000000000; + A[739] = A[129]; + A[385] = 0.0000000000000000000000000; + A[27] = 0.0000000000000000000000000; + A[849] = 0.0000000000000000000000000; + A[773] = A[250]; + A[262] = 0.0000000000000000000000000; + A[499] = A[34]; + A[600] = 0.0000000000000000000000000; + A[682] = A[217]; + A[647] = A[66]; + A[633] = 0.0000000000000000000000000; + A[411] = 0.0000000000000000000000000; + A[627] = A[162]; + A[387] = 0.0000000000000000000000000; + A[196] = 0.0000000000000000000000000; + A[599] = A[134]; + A[121] = A[34]; + A[819] = 0.0000000000000000000000000; + A[111] = 0.0000000000000000000000000; + A[458] = 0.0000000000000000000000000; + A[106] = 0.0000000000000000000000000; + A[553] = 0.0000000000000000000000000; + A[881] = 0.0000000000000000000000000; + A[297] = 0.0000000000000000000000000; + A[581] = 0.0000000000000000000000000; + A[567] = A[102]; + A[491] = 0.0000000000000000000000000; + A[550] = 0.0000000000000000000000000; + A[516] = 0.0000000000000000000000000; + A[698] = 0.0000000000000000000000000; + A[801] = A[191]; + A[741] = A[189]; + A[147] = 0.0000000000000000000000000; + A[81] = 0.0000000000000000000000000; + A[804] = A[281]; + A[436] = 0.0000000000000000000000000; + A[790] = 0.0000000000000000000000000; + A[256] = 0.0000000000000000000000000; + A[778] = A[313]; + A[203] = 0.0000000000000000000000000; + A[84] = 0.0000000000000000000000000; + A[49] = 0.0000000000000000000000000; + A[184] = A[126]; + A[210] = A[7]; + A[353] = 0.0000000000000000000000000; + A[273] = A[99]; + A[876] = 0.0000000000000000000000000; + A[163] = A[162]; + A[73] = A[72]; + A[867] = A[373]; + A[486] = 0.0000000000000000000000000; + A[109] = 0.0000000000000000000000000; + A[46] = 0.0000000000000000000000000; + A[114] = 0.0000000000000000000000000; + A[212] = A[67]; + A[678] = A[97]; + A[453] = 0.0000000000000000000000000; + A[166] = 0.0000000000000000000000000; + A[507] = A[42]; + A[546] = 0.0000000000000000000000000; + A[316] = 0.0000000000000000000000000; + A[78] = 0.0000000000000000000000000; + A[703] = 0.0000000000000000000000000; + A[823] = 0.0000000000000000000000000; + A[86] = 0.0000000000000000000000000; + A[211] = A[36]; + A[671] = 0.0000000000000000000000000; + A[246] = A[188]; + A[428] = A[254]; + A[75] = 0.0000000000000000000000000; + A[525] = A[2]; + A[318] = 0.0000000000000000000000000; + A[637] = 0.0000000000000000000000000; + A[238] = 0.0000000000000000000000000; + A[178] = 0.0000000000000000000000000; + A[325] = 0.0000000000000000000000000; + A[749] = A[283]; + A[775] = A[310]; + A[143] = 0.0000000000000000000000000; + A[247] = A[218]; + A[785] = 0.0000000000000000000000000; + A[361] = A[42]; + A[286] = 0.0000000000000000000000000; + A[0] = 2.2380952380952381375323057*var_177*var_8/(var_9*var_9*var_9); + A[495] = A[1]; + A[302] = A[69]; + A[861] = A[193]; + A[383] = 0.0000000000000000000000000; + A[745] = A[280]; + A[505] = A[40]; + A[465] = A[0]; + A[866] = A[343]; + A[839] = A[374]; + A[521] = 0.0000000000000000000000000; + A[610] = 0.0000000000000000000000000; + A[797] = A[69]; + A[808] = A[343]; + A[216] = A[187]; + A[758] = 0.0000000000000000000000000; + A[79] = 0.0000000000000000000000000; + A[88] = 0.0000000000000000000000000; + A[22] = 0.0000000000000000000000000; + A[395] = A[162]; + A[438] = 0.0000000000000000000000000; + A[509] = A[42]; + A[604] = 0.0000000000000000000000000; + A[750] = 0.0000000000000000000000000; + A[388] = 0.0000000000000000000000000; + A[424] = A[134]; + A[793] = 0.0000000000000000000000000; + A[664] = 0.0000000000000000000000000; + A[349] = 0.0000000000000000000000000; + A[512] = 0.0000000000000000000000000; + A[666] = 0.0000000000000000000000000; + A[626] = A[161]; + A[609] = 0.0000000000000000000000000; + A[844] = 0.0000000000000000000000000; + A[545] = 0.0000000000000000000000000; + A[526] = A[32]; + A[457] = 0.0000000000000000000000000; + A[400] = A[313]; + A[585] = A[3]; + A[784] = 0.0000000000000000000000000; + A[284] = A[283]; + A[673] = 0.0000000000000000000000000; + A[30] = A[1]; + A[450] = 0.0000000000000000000000000; + A[25] = 0.0000000000000000000000000; + A[735] = A[9]; + A[642] = 0.0000000000000000000000000; + A[716] = A[251]; + A[815] = 0.0000000000000000000000000; + A[402] = A[373]; + A[234] = 0.0000000000000000000000000; + A[762] = 0.0000000000000000000000000; + A[898] = A[404]; + A[818] = 0.0000000000000000000000000; + A[15] = 0.0000000000000000000000000; + A[789] = 0.0000000000000000000000000; + A[468] = A[3]; + A[649] = A[126]; + A[711] = A[188]; + A[615] = A[3]; + A[83] = 0.0000000000000000000000000; + A[769] = A[130]; + A[754] = 0.0000000000000000000000000; + A[382] = 0.0000000000000000000000000; + A[631] = 0.0000000000000000000000000; + A[643] = 0.0000000000000000000000000; + A[753] = 0.0000000000000000000000000; + A[885] = A[12]; + A[748] = A[283]; + A[622] = A[157]; + A[18] = 0.0000000000000000000000000; + A[619] = A[125]; + A[340] = A[311]; + A[894] = A[283]; + A[840] = 0.0000000000000000000000000; + A[329] = 0.0000000000000000000000000; + A[893] = A[254]; + A[613] = 0.0000000000000000000000000; + A[173] = 0.0000000000000000000000000; + A[805] = A[311]; + A[578] = 0.0000000000000000000000000; + A[508] = A[42]; + A[650] = A[156]; + A[853] = 0.0000000000000000000000000; + A[57] = 0.0000000000000000000000000; + A[104] = A[102]; + A[532] = A[67]; + A[330] = A[11]; + A[275] = A[159]; + A[571] = 0.0000000000000000000000000; + A[562] = A[97]; + A[757] = 0.0000000000000000000000000; + A[139] = 0.0000000000000000000000000; + A[498] = A[33]; + A[689] = A[224]; + A[205] = 0.0000000000000000000000000; + A[260] = 0.0000000000000000000000000; + A[299] = 0.0000000000000000000000000; + A[470] = A[3]; + A[202] = 0.0000000000000000000000000; + A[116] = 0.0000000000000000000000000; + A[709] = A[128]; + A[300] = A[10]; + A[481] = 0.0000000000000000000000000; + A[331] = A[41]; + A[183] = A[96]; + A[723] = 0.0000000000000000000000000; + A[50] = 0.0000000000000000000000000; + A[197] = 0.0000000000000000000000000; + A[632] = 0.0000000000000000000000000; + A[565] = A[100]; + A[688] = A[223]; + A[479] = A[12]; + A[390] = A[12]; + A[371] = A[342]; + A[791] = 0.0000000000000000000000000; + A[307] = A[220]; + A[406] = 0.0000000000000000000000000; + A[708] = A[98]; + A[738] = A[99]; + A[589] = A[124]; + A[759] = 0.0000000000000000000000000; + A[492] = 0.0000000000000000000000000; + A[504] = A[39]; + A[20] = 0.0000000000000000000000000; + A[685] = A[220]; + A[327] = 0.0000000000000000000000000; + A[837] = A[372]; + A[474] = A[9]; + A[148] = 0.0000000000000000000000000; + A[317] = 0.0000000000000000000000000; + A[687] = A[222]; + A[573] = 0.0000000000000000000000000; + A[655] = A[190]; + A[421] = A[42]; + A[439] = 0.0000000000000000000000000; + A[513] = 0.0000000000000000000000000; + A[61] = A[32]; + A[115] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q4_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q4_quadrature.h new file mode 100644 index 0000000..e20c3d0 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q4_quadrature.h @@ -0,0 +1,17646 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P1_Q4_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P1_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q4_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 15; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q4_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 30; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 15: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 20: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 21: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 22: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 23: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 24: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 25: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 26: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 27: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 28: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 29: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[20] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[21] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[22] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[23] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[24] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[25] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[26] = vals[1]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[27] = vals[1]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[28] = vals[1]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[29] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[15]; + vertex_values[3] = dof_values[16]; + vertex_values[5] = dof_values[17]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q4_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q4_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 3*m.num_entities[1] + 3*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 15; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 15; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 5; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 3; + break; + } + case 2: + { + return 3; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q4_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q4_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 6*m.num_entities[1] + 6*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 30; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 30; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 10; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 6; + break; + } + case 2: + { + return 6; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + dofs[15] = offset + c.entity_indices[0][0]; + dofs[16] = offset + c.entity_indices[0][1]; + dofs[17] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[18] = offset + 3*c.entity_indices[1][0]; + dofs[19] = offset + 3*c.entity_indices[1][0] + 1; + dofs[20] = offset + 3*c.entity_indices[1][0] + 2; + dofs[21] = offset + 3*c.entity_indices[1][1]; + dofs[22] = offset + 3*c.entity_indices[1][1] + 1; + dofs[23] = offset + 3*c.entity_indices[1][1] + 2; + dofs[24] = offset + 3*c.entity_indices[1][2]; + dofs[25] = offset + 3*c.entity_indices[1][2] + 1; + dofs[26] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[27] = offset + 3*c.entity_indices[2][0]; + dofs[28] = offset + 3*c.entity_indices[2][0] + 1; + dofs[29] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + dofs[5] = 16; + dofs[6] = 17; + dofs[7] = 18; + dofs[8] = 19; + dofs[9] = 20; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + dofs[5] = 15; + dofs[6] = 17; + dofs[7] = 21; + dofs[8] = 22; + dofs[9] = 23; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + dofs[5] = 15; + dofs[6] = 16; + dofs[7] = 24; + dofs[8] = 25; + dofs[9] = 26; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 15; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 16; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 17; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + dofs[3] = 18; + dofs[4] = 19; + dofs[5] = 20; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + dofs[3] = 21; + dofs[4] = 22; + dofs[5] = 23; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + dofs[3] = 24; + dofs[4] = 25; + dofs[5] = 26; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + dofs[3] = 27; + dofs[4] = 28; + dofs[5] = 29; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + coordinates[15][0] = x[0][0]; + coordinates[15][1] = x[0][1]; + coordinates[16][0] = x[1][0]; + coordinates[16][1] = x[1][1]; + coordinates[17][0] = x[2][0]; + coordinates[17][1] = x[2][1]; + coordinates[18][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[18][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[19][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[19][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[20][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[20][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[21][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[21][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[22][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[22][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[23][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[23][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[24][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[24][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[25][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[25][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[26][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[26][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[27][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[27][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[28][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[28][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[29][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[29][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p1_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W12[12] = {0.0254224531851035, 0.0254224531851035, 0.0254224531851035, 0.0583931378631895, 0.0583931378631895, 0.0583931378631895, 0.041425537809187, 0.041425537809187, 0.041425537809187, 0.041425537809187, 0.041425537809187, 0.041425537809187}; + // Quadrature points on the UFC reference element: (0.873821971016996, 0.063089014491502), (0.063089014491502, 0.873821971016996), (0.063089014491502, 0.063089014491502), (0.501426509658179, 0.24928674517091), (0.24928674517091, 0.501426509658179), (0.24928674517091, 0.24928674517091), (0.636502499121399, 0.310352451033785), (0.636502499121399, 0.053145049844816), (0.310352451033785, 0.636502499121399), (0.310352451033785, 0.053145049844816), (0.053145049844816, 0.636502499121399), (0.053145049844816, 0.310352451033785) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[12][2] = \ + {{-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + static const double FE1_C0_D01[12][14] = \ + {{0.25503123596508, -0.255031235965082, 8.69435091190193, -4.31977685940844, 1.57734044902622, 0.105939243712314, 0.0, -0.105939243712309, -1.57734044902622, 4.31977685940843, -8.69435091190193, -0.445184891121222, 0.0, 0.445184891121223}, + {0.255031235965082, 3.63298524888145, 0.219821542106375, -1.1302567746644, 2.97433324923121, -1.35751890691984, 3.18952008474403, -5.72001766267072, -0.113882298394064, -0.093447192397538, -0.219821542106377, 0.778519075940721, 1.22370396706193, -3.63897002677786}, + {-3.63298524888145, -0.25503123596508, 0.21982154210638, 0.0934471923975435, 0.113882298394063, 5.72001766267072, -3.18952008474403, 1.35751890691984, -2.97433324923121, 1.1302567746644, -0.21982154210638, 3.63897002677786, -1.22370396706193, -0.778519075940723}, + {-0.334276184571048, 0.334276184571049, 0.00767329311884973, 2.00564073509674, -1.33710470732049, 0.666650418191927, 0.0, -0.66665041819193, 1.3371047073205, -2.00564073509676, -0.00767329311884897, -3.98855545674879, 1.50990331349021e-14, 3.98855545674879}, + {-0.334276184571049, -0.335202663479222, 0.00190199739572172, -0.00856710477719524, 1.35235327632684, 1.33900670471621, -2.01420783987394, 1.344679983208, 0.664748420796208, 0.00282864660425459, -0.00190199739572122, -3.98281699857586, 0.00573845817294127, 1.96571530145281}, + {0.335202663479223, 0.334276184571049, 0.00190199739572106, -0.0028286466042553, -0.664748420796206, -1.344679983208, 2.01420783987395, -1.33900670471622, -1.35235327632686, 0.00856710477719541, -0.00190199739572086, -1.96571530145278, -0.00573845817293789, 3.98281699857584}, + {0.349705911290055, 0.203964070416353, 1.43278734550558, 5.83661064102859, -1.400583725025, -0.512351997979363, -0.0759361474850933, 0.0346181637580474, -1.45986486533339, 2.26265886610736, -1.43278734550558, 2.7813716060586, -8.09926950713595, 0.0790769842997865}, + {-0.203964070416352, -0.349705911290058, 1.43278734550558, -2.26265886610737, 1.45986486533339, -0.0346181637580476, 0.0759361474850917, 0.512351997979366, 1.40058372502499, -5.83661064102859, -1.43278734550559, -0.0790769842997787, 8.09926950713596, -2.78137160605861}, + {0.349705911290056, -0.108689564899274, -0.151560504096129, 1.22633132411976, 5.10669707680118, -1.2604009006736, 1.57769621968679, -0.558311665403964, -0.711815962639155, 0.17227281649596, 0.151560504096128, 3.21812528849814, -1.39860414061572, -7.61300640266017}, + {0.108689564899274, -0.349705911290057, -0.151560504096129, -0.172272816495958, 0.711815962639153, 0.558311665403965, -1.57769621968679, 1.26040090067361, -5.10669707680118, -1.22633132411976, 0.151560504096128, 7.61300640266016, 1.39860414061572, -3.21812528849814}, + {-0.203964070416353, -0.108689564899275, 0.199463964659789, -0.684962646420587, 0.874475680101626, 1.24902322092887, -4.61027931690884, 3.6739097312956, 0.116942340338078, 0.248208963981059, -0.199463964659787, -1.4776811249155, 0.436753682439524, 0.486263104475795}, + {0.108689564899276, 0.203964070416351, 0.199463964659789, -0.24820896398106, -0.116942340338075, -3.67390973129559, 4.61027931690883, -1.24902322092887, -0.874475680101624, 0.684962646420587, -0.199463964659788, -0.486263104475796, -0.43675368243953, 1.4776811249155}}; + + // Array of non-zero columns + static const unsigned int nzc10[14] = {15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; + + // Array of non-zero columns + static const unsigned int nzc7[14] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + + static const double FE1_C0_D10[12][14] = \ + {{0.255031235965081, 3.63298524888145, 2.9743332492312, -1.1302567746644, 0.219821542106376, -0.113882298394064, -0.0934471923975434, -0.219821542106376, -1.35751890691984, 3.18952008474404, -5.72001766267072, 0.778519075940721, -3.63897002677786, 1.22370396706194}, + {0.25503123596508, -0.25503123596508, 1.57734044902622, -4.31977685940843, 8.69435091190193, -1.57734044902622, 4.31977685940843, -8.69435091190193, 0.105939243712316, 0.0, -0.105939243712313, -0.445184891121218, 0.445184891121217, -1.3885718641932e-14}, + {-3.63298524888145, -0.25503123596508, 0.113882298394067, 0.0934471923975413, 0.219821542106378, -2.97433324923121, 1.13025677466441, -0.219821542106378, 5.72001766267072, -3.18952008474404, 1.35751890691984, 3.63897002677786, -0.778519075940718, -1.22370396706195}, + {-0.334276184571049, -0.335202663479221, 1.35235327632684, -0.00856710477719638, 0.00190199739572253, 0.664748420796207, 0.00282864660425311, -0.00190199739572225, 1.33900670471622, -2.01420783987394, 1.344679983208, -3.98281699857586, 1.96571530145281, 0.00573845817294158}, + {-0.334276184571049, 0.33427618457105, -1.3371047073205, 2.00564073509674, 0.00767329311885023, 1.3371047073205, -2.00564073509676, -0.00767329311884979, 0.666650418191928, 0.0, -0.666650418191932, -3.98855545674879, 3.9885554567488, 1.67572730715561e-14}, + {0.335202663479223, 0.33427618457105, -0.664748420796208, -0.00282864660425441, 0.00190199739572211, -1.35235327632686, 0.00856710477719472, -0.0019019973957225, -1.344679983208, 2.01420783987395, -1.33900670471622, -1.96571530145278, 3.98281699857584, -0.00573845817294052}, + {0.349705911290055, -0.108689564899275, 5.10669707680118, 1.22633132411975, -0.151560504096126, -0.711815962639155, 0.172272816495964, 0.151560504096127, -1.2604009006736, 1.57769621968678, -0.55831166540396, 3.21812528849813, -7.61300640266015, -1.39860414061572}, + {-0.203964070416353, -0.108689564899274, 0.874475680101621, -0.68496264642058, 0.199463964659786, 0.116942340338081, 0.248208963981053, -0.199463964659786, 1.24902322092887, -4.61027931690883, 3.67390973129559, -1.4776811249155, 0.486263104475798, 0.436753682439526}, + {0.349705911290056, 0.203964070416352, -1.40058372502499, 5.83661064102859, 1.43278734550559, -1.4598648653334, 2.26265886610737, -1.43278734550559, -0.512351997979363, -0.0759361474850956, 0.0346181637580502, 2.78137160605861, 0.0790769842997796, -8.09926950713596}, + {0.108689564899274, 0.203964070416352, -0.116942340338078, -0.248208963981051, 0.199463964659787, -0.87447568010162, 0.684962646420584, -0.199463964659787, -3.67390973129559, 4.61027931690883, -1.24902322092886, -0.486263104475797, 1.4776811249155, -0.436753682439534}, + {-0.203964070416352, -0.349705911290056, 1.45986486533339, -2.26265886610737, 1.43278734550559, 1.400583725025, -5.83661064102859, -1.43278734550559, -0.0346181637580502, 0.0759361474850956, 0.512351997979363, -0.0790769842997782, -2.78137160605861, 8.09926950713596}, + {0.108689564899276, -0.349705911290055, 0.711815962639149, -0.17227281649596, -0.151560504096129, -5.10669707680118, -1.22633132411976, 0.151560504096128, 0.558311665403961, -1.57769621968678, 1.2604009006736, 7.61300640266016, -3.21812528849813, 1.39860414061572}}; + + // Array of non-zero columns + static const unsigned int nzc11[14] = {15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; + + // Array of non-zero columns + static const unsigned int nzc8[14] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 900; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 60. + double G[12]; + G[0] = K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 56928 + for (unsigned int ip = 0; ip < 12; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 16 + for (unsigned int r = 0; r < 2; r++) + { + F0 += FE0_C0_D01[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D01[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 24 + double I[3]; + // Number of operations: 8 + I[0] = W12[ip]*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 8 + I[1] = W12[ip]*(F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 8 + I[2] = W12[ip]*(F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 4704 + for (unsigned int j = 0; j < 14; j++) + { + for (unsigned int k = 0; k < 14; k++) + { + // Number of operations to compute entry: 3 + A[nzc10[j]*30 + nzc10[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc10[j]*30 + nzc11[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*30 + nzc10[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*30 + nzc11[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc7[j]*30 + nzc7[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc7[j]*30 + nzc8[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*30 + nzc7[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*30 + nzc8[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p1_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q4_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q4_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p1_q4_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p1_q4_tensor.h new file mode 100644 index 0000000..623cbb1 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p1_q4_tensor.h @@ -0,0 +1,18429 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P1_Q4_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P1_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q4_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 15; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p1_q4_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 30; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 15: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 20: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 21: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 22: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 23: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 24: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 25: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 26: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 27: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 28: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 29: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[20] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[21] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[22] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[23] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[24] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[25] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[26] = vals[1]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[27] = vals[1]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[28] = vals[1]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[29] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[15]; + vertex_values[3] = dof_values[16]; + vertex_values[5] = dof_values[17]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q4_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q4_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 3*m.num_entities[1] + 3*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 15; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 15; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 5; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 3; + break; + } + case 2: + { + return 3; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p1_q4_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p1_q4_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 6*m.num_entities[1] + 6*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 30; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 30; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 10; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 6; + break; + } + case 2: + { + return 6; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + dofs[15] = offset + c.entity_indices[0][0]; + dofs[16] = offset + c.entity_indices[0][1]; + dofs[17] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[18] = offset + 3*c.entity_indices[1][0]; + dofs[19] = offset + 3*c.entity_indices[1][0] + 1; + dofs[20] = offset + 3*c.entity_indices[1][0] + 2; + dofs[21] = offset + 3*c.entity_indices[1][1]; + dofs[22] = offset + 3*c.entity_indices[1][1] + 1; + dofs[23] = offset + 3*c.entity_indices[1][1] + 2; + dofs[24] = offset + 3*c.entity_indices[1][2]; + dofs[25] = offset + 3*c.entity_indices[1][2] + 1; + dofs[26] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[27] = offset + 3*c.entity_indices[2][0]; + dofs[28] = offset + 3*c.entity_indices[2][0] + 1; + dofs[29] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + dofs[5] = 16; + dofs[6] = 17; + dofs[7] = 18; + dofs[8] = 19; + dofs[9] = 20; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + dofs[5] = 15; + dofs[6] = 17; + dofs[7] = 21; + dofs[8] = 22; + dofs[9] = 23; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + dofs[5] = 15; + dofs[6] = 16; + dofs[7] = 24; + dofs[8] = 25; + dofs[9] = 26; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 15; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 16; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 17; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + dofs[3] = 18; + dofs[4] = 19; + dofs[5] = 20; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + dofs[3] = 21; + dofs[4] = 22; + dofs[5] = 23; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + dofs[3] = 24; + dofs[4] = 25; + dofs[5] = 26; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + dofs[3] = 27; + dofs[4] = 28; + dofs[5] = 29; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + coordinates[15][0] = x[0][0]; + coordinates[15][1] = x[0][1]; + coordinates[16][0] = x[1][0]; + coordinates[16][1] = x[1][1]; + coordinates[17][0] = x[2][0]; + coordinates[17][1] = x[2][1]; + coordinates[18][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[18][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[19][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[19][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[20][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[20][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[21][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[21][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[22][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[22][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[23][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[23][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[24][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[24][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[25][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[25][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[26][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[26][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[27][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[27][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[28][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[28][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[29][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[29][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p1_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 96 + // Number of operations (multiply-add pairs) for tensor contraction: 1812 + // Total number of operations (multiply-add pairs): 1919 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0 = det*(w[0][3]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1 = det*(w[0][3]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0 = det*(w[0][4]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1 = det*(w[0][5]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0 = det*(w[0][3]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1 = det*(w[0][3]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0 = det*(w[0][4]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1 = det*(w[0][5]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0 = det*(w[0][3]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1 = det*(w[0][3]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0 = det*(w[0][4]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1 = det*(w[0][5]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0 = det*(w[0][3]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1 = det*(w[0][3]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0 = det*(w[0][4]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1 = det*(w[0][5]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[213] = 0.152380952380962*G0_0_0_0_0_0 + 0.152380952380962*G0_0_0_0_0_1 - 0.152380952380962*G0_0_0_1_0_0 - 0.152380952380962*G0_0_0_2_0_1 + 0.152380952380962*G0_0_0_3_1_0 + 0.152380952380962*G0_0_0_3_1_1 - 0.152380952380962*G0_0_0_4_1_0 - 0.152380952380962*G0_0_0_5_1_1 + 0.042328042328044*G0_0_1_0_0_0 + 0.042328042328044*G0_0_1_0_0_1 - 0.042328042328044*G0_0_1_1_0_0 - 0.042328042328044*G0_0_1_2_0_1 + 0.042328042328044*G0_0_1_3_1_0 + 0.042328042328044*G0_0_1_3_1_1 - 0.042328042328044*G0_0_1_4_1_0 - 0.042328042328044*G0_0_1_5_1_1 + 0.0423280423280468*G0_1_0_0_0_0 + 0.0423280423280468*G0_1_0_0_0_1 - 0.0423280423280468*G0_1_0_1_0_0 - 0.0423280423280468*G0_1_0_2_0_1 + 0.0423280423280468*G0_1_0_3_1_0 + 0.0423280423280468*G0_1_0_3_1_1 - 0.0423280423280468*G0_1_0_4_1_0 - 0.0423280423280468*G0_1_0_5_1_1; + A[625] = A[213] - 0.152380952380962*G0_0_0_0_0_0 - 0.152380952380962*G0_0_0_0_0_1 + 0.152380952380962*G0_0_0_1_0_0 + 0.152380952380962*G0_0_0_2_0_1 - 0.152380952380962*G0_0_0_3_1_0 - 0.152380952380962*G0_0_0_3_1_1 + 0.152380952380962*G0_0_0_4_1_0 + 0.152380952380962*G0_0_0_5_1_1 + 0.152380952380961*G0_1_1_0_0_0 + 0.152380952380961*G0_1_1_0_0_1 - 0.152380952380961*G0_1_1_1_0_0 - 0.152380952380961*G0_1_1_2_0_1 + 0.152380952380961*G0_1_1_3_1_0 + 0.152380952380961*G0_1_1_3_1_1 - 0.152380952380961*G0_1_1_4_1_0 - 0.152380952380961*G0_1_1_5_1_1; + A[489] = 0.0; + A[208] = 0.0; + A[574] = 0.0; + A[530] = -0.778835978835987*G0_1_0_0_0_0 - 0.778835978835987*G0_1_0_0_0_1 + 0.778835978835987*G0_1_0_1_0_0 + 0.778835978835987*G0_1_0_2_0_1 - 0.778835978835987*G0_1_0_3_1_0 - 0.778835978835987*G0_1_0_3_1_1 + 0.778835978835987*G0_1_0_4_1_0 + 0.778835978835987*G0_1_0_5_1_1 - 0.126984126984127*G0_1_1_0_0_0 - 0.126984126984127*G0_1_1_0_0_1 + 0.126984126984127*G0_1_1_1_0_0 + 0.126984126984127*G0_1_1_2_0_1 - 0.126984126984127*G0_1_1_3_1_0 - 0.126984126984127*G0_1_1_3_1_1 + 0.126984126984127*G0_1_1_4_1_0 + 0.126984126984127*G0_1_1_5_1_1; + A[235] = 0.0; + A[679] = -0.393650793650818*G0_0_0_0_0_0 - 0.393650793650818*G0_0_0_0_0_1 + 0.393650793650818*G0_0_0_1_0_0 + 0.393650793650818*G0_0_0_2_0_1 - 0.393650793650818*G0_0_0_3_1_0 - 0.393650793650818*G0_0_0_3_1_1 + 0.393650793650818*G0_0_0_4_1_0 + 0.393650793650818*G0_0_0_5_1_1 - 0.196825396825405*G0_0_1_0_0_0 - 0.196825396825405*G0_0_1_0_0_1 + 0.196825396825405*G0_0_1_1_0_0 + 0.196825396825405*G0_0_1_2_0_1 - 0.196825396825405*G0_0_1_3_1_0 - 0.196825396825405*G0_0_1_3_1_1 + 0.196825396825405*G0_0_1_4_1_0 + 0.196825396825405*G0_0_1_5_1_1 - 0.196825396825417*G0_1_0_0_0_0 - 0.196825396825417*G0_1_0_0_0_1 + 0.196825396825417*G0_1_0_1_0_0 + 0.196825396825417*G0_1_0_2_0_1 - 0.196825396825417*G0_1_0_3_1_0 - 0.196825396825417*G0_1_0_3_1_1 + 0.196825396825417*G0_1_0_4_1_0 + 0.196825396825417*G0_1_0_5_1_1 - 0.0507936507936571*G0_1_1_0_0_0 - 0.0507936507936571*G0_1_1_0_0_1 + 0.0507936507936571*G0_1_1_1_0_0 + 0.0507936507936571*G0_1_1_2_0_1 - 0.0507936507936571*G0_1_1_3_1_0 - 0.0507936507936571*G0_1_1_3_1_1 + 0.0507936507936571*G0_1_1_4_1_0 + 0.0507936507936571*G0_1_1_5_1_1; + A[607] = 0.0; + A[716] = -0.101587301587301*G0_0_1_0_0_0 - 0.101587301587301*G0_0_1_0_0_1 + 0.101587301587301*G0_0_1_1_0_0 + 0.101587301587301*G0_0_1_2_0_1 - 0.101587301587301*G0_0_1_3_1_0 - 0.101587301587301*G0_0_1_3_1_1 + 0.101587301587301*G0_0_1_4_1_0 + 0.101587301587301*G0_0_1_5_1_1 - 0.101587301587306*G0_1_0_0_0_0 - 0.101587301587306*G0_1_0_0_0_1 + 0.101587301587306*G0_1_0_1_0_0 + 0.101587301587306*G0_1_0_2_0_1 - 0.101587301587306*G0_1_0_3_1_0 - 0.101587301587306*G0_1_0_3_1_1 + 0.101587301587306*G0_1_0_4_1_0 + 0.101587301587306*G0_1_0_5_1_1; + A[636] = 0.0; + A[270] = A[530] + 0.651851851851859*G0_0_0_0_0_0 + 0.651851851851859*G0_0_0_0_0_1 - 0.651851851851859*G0_0_0_1_0_0 - 0.651851851851859*G0_0_0_2_0_1 + 0.651851851851859*G0_0_0_3_1_0 + 0.651851851851859*G0_0_0_3_1_1 - 0.651851851851859*G0_0_0_4_1_0 - 0.651851851851859*G0_0_0_5_1_1 + 0.651851851851859*G0_0_1_0_0_0 + 0.651851851851859*G0_0_1_0_0_1 - 0.651851851851859*G0_0_1_1_0_0 - 0.651851851851859*G0_0_1_2_0_1 + 0.651851851851859*G0_0_1_3_1_0 + 0.651851851851859*G0_0_1_3_1_1 - 0.651851851851859*G0_0_1_4_1_0 - 0.651851851851859*G0_0_1_5_1_1 + 0.65185185185186*G0_1_0_0_0_0 + 0.65185185185186*G0_1_0_0_0_1 - 0.65185185185186*G0_1_0_1_0_0 - 0.65185185185186*G0_1_0_2_0_1 + 0.65185185185186*G0_1_0_3_1_0 + 0.65185185185186*G0_1_0_3_1_1 - 0.65185185185186*G0_1_0_4_1_0 - 0.65185185185186*G0_1_0_5_1_1; + A[307] = A[679] + 0.342857142857164*G0_0_0_0_0_0 + 0.342857142857164*G0_0_0_0_0_1 - 0.342857142857164*G0_0_0_1_0_0 - 0.342857142857164*G0_0_0_2_0_1 + 0.342857142857164*G0_0_0_3_1_0 + 0.342857142857164*G0_0_0_3_1_1 - 0.342857142857164*G0_0_0_4_1_0 - 0.342857142857164*G0_0_0_5_1_1 + 0.342857142857163*G0_0_1_0_0_0 + 0.342857142857163*G0_0_1_0_0_1 - 0.342857142857163*G0_0_1_1_0_0 - 0.342857142857163*G0_0_1_2_0_1 + 0.342857142857163*G0_0_1_3_1_0 + 0.342857142857163*G0_0_1_3_1_1 - 0.342857142857163*G0_0_1_4_1_0 - 0.342857142857163*G0_0_1_5_1_1 + 0.342857142857163*G0_1_0_0_0_0 + 0.342857142857163*G0_1_0_0_0_1 - 0.342857142857163*G0_1_0_1_0_0 - 0.342857142857163*G0_1_0_2_0_1 + 0.342857142857163*G0_1_0_3_1_0 + 0.342857142857163*G0_1_0_3_1_1 - 0.342857142857163*G0_1_0_4_1_0 - 0.342857142857163*G0_1_0_5_1_1; + A[352] = 0.0; + A[17] = 0.0; + A[734] = 0.0; + A[421] = 0.0846560846560889*G0_0_0_0_0_0 + 0.0846560846560889*G0_0_0_0_0_1 - 0.0846560846560889*G0_0_0_1_0_0 - 0.0846560846560889*G0_0_0_2_0_1 + 0.0846560846560889*G0_0_0_3_1_0 + 0.0846560846560889*G0_0_0_3_1_1 - 0.0846560846560889*G0_0_0_4_1_0 - 0.0846560846560889*G0_0_0_5_1_1; + A[377] = 0.0; + A[58] = 0.0; + A[454] = 0.0; + A[410] = 0.0; + A[87] = 0.0; + A[792] = 0.0; + A[887] = 0.0846560846560837*G0_1_1_0_0_0 + 0.0846560846560837*G0_1_1_0_0_1 - 0.0846560846560837*G0_1_1_1_0_0 - 0.0846560846560837*G0_1_1_2_0_1 + 0.0846560846560837*G0_1_1_3_1_0 + 0.0846560846560837*G0_1_1_3_1_1 - 0.0846560846560837*G0_1_1_4_1_0 - 0.0846560846560837*G0_1_1_5_1_1; + A[811] = 0.0; + A[850] = 0.0; + A[174] = 0.0; + A[881] = 0.0; + A[480] = 0.0; + A[203] = 0.0; + A[583] = 0.0; + A[523] = 0.0; + A[232] = 0.0; + A[614] = 0.0; + A[550] = 0.0; + A[672] = 0.0; + A[279] = A[530] - 1.82857142857145*G0_0_0_0_0_0 - 1.82857142857145*G0_0_0_0_0_1 + 1.82857142857145*G0_0_0_1_0_0 + 1.82857142857145*G0_0_0_2_0_1 - 1.82857142857145*G0_0_0_3_1_0 - 1.82857142857145*G0_0_0_3_1_1 + 1.82857142857145*G0_0_0_4_1_0 + 1.82857142857145*G0_0_0_5_1_1 - 0.778835978835992*G0_0_1_0_0_0 - 0.778835978835992*G0_0_1_0_0_1 + 0.778835978835992*G0_0_1_1_0_0 + 0.778835978835992*G0_0_1_2_0_1 - 0.778835978835992*G0_0_1_3_1_0 - 0.778835978835992*G0_0_1_3_1_1 + 0.778835978835992*G0_0_1_4_1_0 + 0.778835978835992*G0_0_1_5_1_1 - 1.70158730158732*G0_1_1_0_0_0 - 1.70158730158732*G0_1_1_0_0_1 + 1.70158730158732*G0_1_1_1_0_0 + 1.70158730158732*G0_1_1_2_0_1 - 1.70158730158732*G0_1_1_3_1_0 - 1.70158730158732*G0_1_1_3_1_1 + 1.70158730158732*G0_1_1_4_1_0 + 1.70158730158732*G0_1_1_5_1_1; + A[699] = 0.0; + A[258] = 0.0; + A[345] = 0.0; + A[289] = 0.0; + A[51] = 0.0; + A[463] = 0.0; + A[403] = -5.68888888888896*G0_0_0_0_0_0 - 5.68888888888896*G0_0_0_0_0_1 + 5.68888888888896*G0_0_0_1_0_0 + 5.68888888888896*G0_0_0_2_0_1 - 5.68888888888896*G0_0_0_3_1_0 - 5.68888888888896*G0_0_0_3_1_1 + 5.68888888888896*G0_0_0_4_1_0 + 5.68888888888896*G0_0_0_5_1_1 - 2.8444444444445*G0_0_1_0_0_0 - 2.8444444444445*G0_0_1_0_0_1 + 2.8444444444445*G0_0_1_1_0_0 + 2.8444444444445*G0_0_1_2_0_1 - 2.8444444444445*G0_0_1_3_1_0 - 2.8444444444445*G0_0_1_3_1_1 + 2.8444444444445*G0_0_1_4_1_0 + 2.8444444444445*G0_0_1_5_1_1 - 2.8444444444445*G0_1_0_0_0_0 - 2.8444444444445*G0_1_0_0_0_1 + 2.8444444444445*G0_1_0_1_0_0 + 2.8444444444445*G0_1_0_2_0_1 - 2.8444444444445*G0_1_0_3_1_0 - 2.8444444444445*G0_1_0_3_1_1 + 2.8444444444445*G0_1_0_4_1_0 + 2.8444444444445*G0_1_0_5_1_1 - 5.688888888889*G0_1_1_0_0_0 - 5.688888888889*G0_1_1_0_0_1 + 5.688888888889*G0_1_1_1_0_0 + 5.688888888889*G0_1_1_2_0_1 - 5.688888888889*G0_1_1_3_1_0 - 5.688888888889*G0_1_1_3_1_1 + 5.688888888889*G0_1_1_4_1_0 + 5.688888888889*G0_1_1_5_1_1; + A[78] = 0.0; + A[803] = A[716]; + A[816] = 0.0; + A[45] = 0.0; + A[841] = 0.0; + A[72] = A[887]; + A[874] = 0.0; + A[107] = 0.0; + A[487] = 0.0; + A[516] = 0.0; + A[225] = 0.0; + A[545] = 0.0; + A[509] = A[421]; + A[638] = 0.0; + A[534] = -0.500000000000032*A[887]; + A[92] = -A[534] - 0.203174603174604*G0_0_1_0_0_0 - 0.203174603174604*G0_0_1_0_0_1 + 0.203174603174604*G0_0_1_1_0_0 + 0.203174603174604*G0_0_1_2_0_1 - 0.203174603174604*G0_0_1_3_1_0 - 0.203174603174604*G0_0_1_3_1_1 + 0.203174603174604*G0_0_1_4_1_0 + 0.203174603174604*G0_0_1_5_1_1; + A[667] = 0.0; + A[696] = 0.0; + A[265] = 0.0; + A[290] = 0.0; + A[439] = 0.0; + A[319] = 0.0; + A[775] = -2.9587301587302*G0_0_0_0_0_0 - 2.9587301587302*G0_0_0_0_0_1 + 2.9587301587302*G0_0_0_1_0_0 + 2.9587301587302*G0_0_0_2_0_1 - 2.9587301587302*G0_0_0_3_1_0 - 2.9587301587302*G0_0_0_3_1_1 + 2.9587301587302*G0_0_0_4_1_0 + 2.9587301587302*G0_0_0_5_1_1 - 1.4793650793651*G0_0_1_0_0_0 - 1.4793650793651*G0_0_1_0_0_1 + 1.4793650793651*G0_0_1_1_0_0 + 1.4793650793651*G0_0_1_2_0_1 - 1.4793650793651*G0_0_1_3_1_0 - 1.4793650793651*G0_0_1_3_1_1 + 1.4793650793651*G0_0_1_4_1_0 + 1.4793650793651*G0_0_1_5_1_1 - 1.4793650793651*G0_1_0_0_0_0 - 1.4793650793651*G0_1_0_0_0_1 + 1.4793650793651*G0_1_0_1_0_0 + 1.4793650793651*G0_1_0_2_0_1 - 1.4793650793651*G0_1_0_3_1_0 - 1.4793650793651*G0_1_0_3_1_1 + 1.4793650793651*G0_1_0_4_1_0 + 1.4793650793651*G0_1_0_5_1_1 - 2.45079365079369*G0_1_1_0_0_0 - 2.45079365079369*G0_1_1_0_0_1 + 2.45079365079369*G0_1_1_1_0_0 + 2.45079365079369*G0_1_1_2_0_1 - 2.45079365079369*G0_1_1_3_1_0 - 2.45079365079369*G0_1_1_3_1_1 + 2.45079365079369*G0_1_1_4_1_0 + 2.45079365079369*G0_1_1_5_1_1; + A[460] = 0.0; + A[356] = 0.0; + A[5] = -A[213] + 0.110052910052919*G0_0_0_0_0_0 + 0.110052910052919*G0_0_0_0_0_1 - 0.110052910052919*G0_0_0_1_0_0 - 0.110052910052919*G0_0_0_2_0_1 + 0.110052910052919*G0_0_0_3_1_0 + 0.110052910052919*G0_0_0_3_1_1 - 0.110052910052919*G0_0_0_4_1_0 - 0.110052910052919*G0_0_0_5_1_1 - 0.0423280423280432*G0_1_1_0_0_0 - 0.0423280423280432*G0_1_1_0_0_1 + 0.0423280423280432*G0_1_1_1_0_0 + 0.0423280423280432*G0_1_1_2_0_1 - 0.0423280423280432*G0_1_1_3_1_0 - 0.0423280423280432*G0_1_1_3_1_1 + 0.0423280423280432*G0_1_1_4_1_0 + 0.0423280423280432*G0_1_1_5_1_1; + A[765] = A[5] - 0.42539682539683*G0_0_0_0_0_0 - 0.42539682539683*G0_0_0_0_0_1 + 0.42539682539683*G0_0_0_1_0_0 + 0.42539682539683*G0_0_0_2_0_1 - 0.42539682539683*G0_0_0_3_1_0 - 0.42539682539683*G0_0_0_3_1_1 + 0.42539682539683*G0_0_0_4_1_0 + 0.42539682539683*G0_0_0_5_1_1 - 0.425396825396828*G0_0_1_0_0_0 - 0.425396825396828*G0_0_1_0_0_1 + 0.425396825396828*G0_0_1_1_0_0 + 0.425396825396828*G0_0_1_2_0_1 - 0.425396825396828*G0_0_1_3_1_0 - 0.425396825396828*G0_0_1_3_1_1 + 0.425396825396828*G0_0_1_4_1_0 + 0.425396825396828*G0_0_1_5_1_1; + A[14] = -2.00000000000004*A[5]; + A[722] = 0.0; + A[389] = 0.0; + A[753] = 0.0; + A[160] = A[625]; + A[899] = A[403]; + A[112] = 0.0; + A[181] = -0.499999999999998*A[421]; + A[151] = -A[181] - 0.203174603174606*G0_1_0_0_0_0 - 0.203174603174606*G0_1_0_0_0_1 + 0.203174603174606*G0_1_0_1_0_0 + 0.203174603174606*G0_1_0_2_0_1 - 0.203174603174606*G0_1_0_3_1_0 - 0.203174603174606*G0_1_0_3_1_1 + 0.203174603174606*G0_1_0_4_1_0 + 0.203174603174606*G0_1_0_5_1_1; + A[137] = 0.0; + A[214] = A[679]; + A[170] = 0.0; + A[500] = -A[181] - 0.203174603174605*G0_0_1_0_0_0 - 0.203174603174605*G0_0_1_0_0_1 + 0.203174603174605*G0_0_1_1_0_0 + 0.203174603174605*G0_0_1_2_0_1 - 0.203174603174605*G0_0_1_3_1_0 - 0.203174603174605*G0_0_1_3_1_1 + 0.203174603174605*G0_0_1_4_1_0 + 0.203174603174605*G0_0_1_5_1_1; + A[207] = 0.0; + A[647] = -A[92] + 0.287830687830693*G0_1_1_0_0_0 + 0.287830687830693*G0_1_1_0_0_1 - 0.287830687830693*G0_1_1_1_0_0 - 0.287830687830693*G0_1_1_2_0_1 + 0.287830687830693*G0_1_1_3_1_0 + 0.287830687830693*G0_1_1_3_1_1 - 0.287830687830693*G0_1_1_4_1_0 - 0.287830687830693*G0_1_1_5_1_1; + A[571] = 0.0; + A[527] = -4.4062500000001*A[887]; + A[562] = A[213]; + A[240] = -A[5] + 0.203174603174604*G0_1_0_0_0_0 + 0.203174603174604*G0_1_0_0_0_1 - 0.203174603174604*G0_1_0_1_0_0 - 0.203174603174604*G0_1_0_2_0_1 + 0.203174603174604*G0_1_0_3_1_0 + 0.203174603174604*G0_1_0_3_1_1 - 0.203174603174604*G0_1_0_4_1_0 - 0.203174603174604*G0_1_0_5_1_1 + 0.203174603174604*G0_1_1_0_0_0 + 0.203174603174604*G0_1_1_0_0_1 - 0.203174603174604*G0_1_1_1_0_0 - 0.203174603174604*G0_1_1_2_0_1 + 0.203174603174604*G0_1_1_3_1_0 + 0.203174603174604*G0_1_1_3_1_1 - 0.203174603174604*G0_1_1_4_1_0 - 0.203174603174604*G0_1_1_5_1_1; + A[299] = 0.0; + A[446] = 0.0; + A[326] = 0.0; + A[469] = A[5]; + A[349] = 0.0; + A[28] = 0.0; + A[729] = 0.0; + A[380] = 0.0; + A[55] = 0.0; + A[754] = 0.0; + A[415] = 0.0; + A[783] = 0.0; + A[820] = 0.0; + A[144] = 0.0; + A[853] = 0.0; + A[179] = 0.0; + A[491] = 0.0; + A[198] = 0.0; + A[656] = A[716] + 0.135449735449742*G0_0_0_0_0_0 + 0.135449735449742*G0_0_0_0_0_1 - 0.135449735449742*G0_0_0_1_0_0 - 0.135449735449742*G0_0_0_2_0_1 + 0.135449735449742*G0_0_0_3_1_0 + 0.135449735449742*G0_0_0_3_1_1 - 0.135449735449742*G0_0_0_4_1_0 - 0.135449735449742*G0_0_0_5_1_1; + A[741] = A[656] - 0.812698412698418*G0_0_1_0_0_0 - 0.812698412698418*G0_0_1_0_0_1 + 0.812698412698418*G0_0_1_1_0_0 + 0.812698412698418*G0_0_1_2_0_1 - 0.812698412698418*G0_0_1_3_1_0 - 0.812698412698418*G0_0_1_3_1_1 + 0.812698412698418*G0_0_1_4_1_0 + 0.812698412698418*G0_0_1_5_1_1 - 0.812698412698418*G0_1_0_0_0_0 - 0.812698412698418*G0_1_0_0_0_1 + 0.812698412698418*G0_1_0_1_0_0 + 0.812698412698418*G0_1_0_2_0_1 - 0.812698412698418*G0_1_0_3_1_0 - 0.812698412698418*G0_1_0_3_1_1 + 0.812698412698418*G0_1_0_4_1_0 + 0.812698412698418*G0_1_0_5_1_1 + 0.13544973544974*G0_1_1_0_0_0 + 0.13544973544974*G0_1_1_0_0_1 - 0.13544973544974*G0_1_1_1_0_0 - 0.13544973544974*G0_1_1_2_0_1 + 0.13544973544974*G0_1_1_3_1_0 + 0.13544973544974*G0_1_1_3_1_1 - 0.13544973544974*G0_1_1_4_1_0 - 0.13544973544974*G0_1_1_5_1_1; + A[576] = 0.0; + A[520] = 0.0; + A[237] = 0.0; + A[601] = 0.0; + A[557] = A[92]; + A[634] = 0.0; + A[671] = 0.0; + A[276] = A[741]; + A[449] = 0.0; + A[305] = A[625]; + A[474] = A[270] - 0.778835978835986*G0_0_1_0_0_0 - 0.778835978835986*G0_0_1_0_0_1 + 0.778835978835986*G0_0_1_1_0_0 + 0.778835978835986*G0_0_1_2_0_1 - 0.778835978835986*G0_0_1_3_1_0 - 0.778835978835986*G0_0_1_3_1_1 + 0.778835978835986*G0_0_1_4_1_0 + 0.778835978835986*G0_0_1_5_1_1 + 0.778835978835986*G0_1_0_0_0_0 + 0.778835978835986*G0_1_0_0_0_1 - 0.778835978835986*G0_1_0_1_0_0 - 0.778835978835986*G0_1_0_2_0_1 + 0.778835978835986*G0_1_0_3_1_0 + 0.778835978835986*G0_1_0_3_1_1 - 0.778835978835986*G0_1_0_4_1_0 - 0.778835978835986*G0_1_0_5_1_1; + A[645] = A[474] - 0.778835978835986*G0_0_0_0_0_0 - 0.778835978835986*G0_0_0_0_0_1 + 0.778835978835986*G0_0_0_1_0_0 + 0.778835978835986*G0_0_0_2_0_1 - 0.778835978835986*G0_0_0_3_1_0 - 0.778835978835986*G0_0_0_3_1_1 + 0.778835978835986*G0_0_0_4_1_0 + 0.778835978835986*G0_0_0_5_1_1 + 0.778835978835986*G0_1_1_0_0_0 + 0.778835978835986*G0_1_1_0_0_1 - 0.778835978835986*G0_1_1_1_0_0 - 0.778835978835986*G0_1_1_2_0_1 + 0.778835978835986*G0_1_1_3_1_0 + 0.778835978835986*G0_1_1_3_1_1 - 0.778835978835986*G0_1_1_4_1_0 - 0.778835978835986*G0_1_1_5_1_1; + A[338] = A[716]; + A[19] = 0.0; + A[736] = -A[151] + 0.287830687830692*G0_0_0_0_0_0 + 0.287830687830692*G0_0_0_0_0_1 - 0.287830687830692*G0_0_0_1_0_0 - 0.287830687830692*G0_0_0_2_0_1 + 0.287830687830692*G0_0_0_3_1_0 + 0.287830687830692*G0_0_0_3_1_1 - 0.287830687830692*G0_0_0_4_1_0 - 0.287830687830692*G0_0_0_5_1_1; + A[379] = 0.0; + A[48] = 0.0; + A[763] = 0.0; + A[456] = 0.0; + A[408] = 0.0; + A[85] = 0.0; + A[790] = 0.0; + A[9] = A[474]; + A[813] = 0.0; + A[127] = A[679]; + A[844] = 0.0; + A[879] = 0.0; + A[482] = 0.0; + A[201] = 0.0; + A[585] = A[5]; + A[513] = 0.0; + A[226] = 0.0; + A[608] = 0.0; + A[548] = 0.0; + A[504] = -A[500] + 0.287830687830692*G0_0_0_0_0_0 + 0.287830687830692*G0_0_0_0_0_1 - 0.287830687830692*G0_0_0_1_0_0 - 0.287830687830692*G0_0_0_2_0_1 + 0.287830687830692*G0_0_0_3_1_0 + 0.287830687830692*G0_0_0_3_1_1 - 0.287830687830692*G0_0_0_4_1_0 - 0.287830687830692*G0_0_0_5_1_1; + A[643] = 0.0; + A[662] = 0.0; + A[285] = 0.0; + A[701] = 0.0; + A[260] = 0.0; + A[331] = 0.651851851851859*G0_0_0_0_0_0 + 0.651851851851859*G0_0_0_0_0_1 - 0.651851851851859*G0_0_0_1_0_0 - 0.651851851851859*G0_0_0_2_0_1 + 0.651851851851859*G0_0_0_3_1_0 + 0.651851851851859*G0_0_0_3_1_1 - 0.651851851851859*G0_0_0_4_1_0 - 0.651851851851859*G0_0_0_5_1_1 + 0.778835978835987*G0_1_0_0_0_0 + 0.778835978835987*G0_1_0_0_0_1 - 0.778835978835987*G0_1_0_1_0_0 - 0.778835978835987*G0_1_0_2_0_1 + 0.778835978835987*G0_1_0_3_1_0 + 0.778835978835987*G0_1_0_3_1_1 - 0.778835978835987*G0_1_0_4_1_0 - 0.778835978835987*G0_1_0_5_1_1; + A[287] = 0.0; + A[743] = A[716] + 0.135449735449742*G0_1_1_0_0_0 + 0.135449735449742*G0_1_1_0_0_1 - 0.135449735449742*G0_1_1_1_0_0 - 0.135449735449742*G0_1_1_2_0_1 + 0.135449735449742*G0_1_1_3_1_0 + 0.135449735449742*G0_1_1_3_1_1 - 0.135449735449742*G0_1_1_4_1_0 - 0.135449735449742*G0_1_1_5_1_1; + A[658] = -A[743] - 0.812698412698439*G0_0_0_0_0_0 - 0.812698412698439*G0_0_0_0_0_1 + 0.812698412698439*G0_0_0_1_0_0 + 0.812698412698439*G0_0_0_2_0_1 - 0.812698412698439*G0_0_0_3_1_0 - 0.812698412698439*G0_0_0_3_1_1 + 0.812698412698439*G0_0_0_4_1_0 + 0.812698412698439*G0_0_0_5_1_1 - 0.575661375661385*G0_0_1_0_0_0 - 0.575661375661385*G0_0_1_0_0_1 + 0.575661375661385*G0_0_1_1_0_0 + 0.575661375661385*G0_0_1_2_0_1 - 0.575661375661385*G0_0_1_3_1_0 - 0.575661375661385*G0_0_1_3_1_1 + 0.575661375661385*G0_0_1_4_1_0 + 0.575661375661385*G0_0_1_5_1_1 - 0.575661375661395*G0_1_0_0_0_0 - 0.575661375661395*G0_1_0_0_0_1 + 0.575661375661395*G0_1_0_1_0_0 + 0.575661375661395*G0_1_0_2_0_1 - 0.575661375661395*G0_1_0_3_1_0 - 0.575661375661395*G0_1_0_3_1_1 + 0.575661375661395*G0_1_0_4_1_0 + 0.575661375661395*G0_1_0_5_1_1; + A[245] = A[743] + 2.09947089947092*G0_0_0_0_0_0 + 2.09947089947092*G0_0_0_0_0_1 - 2.09947089947092*G0_0_0_1_0_0 - 2.09947089947092*G0_0_0_2_0_1 + 2.09947089947092*G0_0_0_3_1_0 + 2.09947089947092*G0_0_0_3_1_1 - 2.09947089947092*G0_0_0_4_1_0 - 2.09947089947092*G0_0_0_5_1_1 + 1.15132275132275*G0_0_1_0_0_0 + 1.15132275132275*G0_0_1_0_0_1 - 1.15132275132275*G0_0_1_1_0_0 - 1.15132275132275*G0_0_1_2_0_1 + 1.15132275132275*G0_0_1_3_1_0 + 1.15132275132275*G0_0_1_3_1_1 - 1.15132275132275*G0_0_1_4_1_0 - 1.15132275132275*G0_0_1_5_1_1 + 1.15132275132276*G0_1_0_0_0_0 + 1.15132275132276*G0_1_0_0_0_1 - 1.15132275132276*G0_1_0_1_0_0 - 1.15132275132276*G0_1_0_2_0_1 + 1.15132275132276*G0_1_0_3_1_0 + 1.15132275132276*G0_1_0_3_1_1 - 1.15132275132276*G0_1_0_4_1_0 - 1.15132275132276*G0_1_0_5_1_1; + A[252] = -A[743] + 0.23703703703705*G0_0_1_0_0_0 + 0.23703703703705*G0_0_1_0_0_1 - 0.23703703703705*G0_0_1_1_0_0 - 0.23703703703705*G0_0_1_2_0_1 + 0.23703703703705*G0_0_1_3_1_0 + 0.23703703703705*G0_0_1_3_1_1 - 0.23703703703705*G0_0_1_4_1_0 - 0.23703703703705*G0_0_1_5_1_1 + 0.237037037037039*G0_1_0_0_0_0 + 0.237037037037039*G0_1_0_0_0_1 - 0.237037037037039*G0_1_0_1_0_0 - 0.237037037037039*G0_1_0_2_0_1 + 0.237037037037039*G0_1_0_3_1_0 + 0.237037037037039*G0_1_0_3_1_1 - 0.237037037037039*G0_1_0_4_1_0 - 0.237037037037039*G0_1_0_5_1_1; + A[428] = -A[743] - 1.38835978835982*G0_0_1_0_0_0 - 1.38835978835982*G0_0_1_0_0_1 + 1.38835978835982*G0_0_1_1_0_0 + 1.38835978835982*G0_0_1_2_0_1 - 1.38835978835982*G0_0_1_3_1_0 - 1.38835978835982*G0_0_1_3_1_1 + 1.38835978835982*G0_0_1_4_1_0 + 1.38835978835982*G0_0_1_5_1_1 - 1.3883597883598*G0_1_0_0_0_0 - 1.3883597883598*G0_1_0_0_0_1 + 1.3883597883598*G0_1_0_1_0_0 + 1.3883597883598*G0_1_0_2_0_1 - 1.3883597883598*G0_1_0_3_1_0 - 1.3883597883598*G0_1_0_3_1_1 + 1.3883597883598*G0_1_0_4_1_0 + 1.3883597883598*G0_1_0_5_1_1; + A[368] = A[252]; + A[101] = A[245] - 1.96402116402118*G0_0_0_0_0_0 - 1.96402116402118*G0_0_0_0_0_1 + 1.96402116402118*G0_0_0_1_0_0 + 1.96402116402118*G0_0_0_2_0_1 - 1.96402116402118*G0_0_0_3_1_0 - 1.96402116402118*G0_0_0_3_1_1 + 1.96402116402118*G0_0_0_4_1_0 + 1.96402116402118*G0_0_0_5_1_1 + 1.96402116402118*G0_1_1_0_0_0 + 1.96402116402118*G0_1_1_0_0_1 - 1.96402116402118*G0_1_1_1_0_0 - 1.96402116402118*G0_1_1_2_0_1 + 1.96402116402118*G0_1_1_3_1_0 + 1.96402116402118*G0_1_1_3_1_1 - 1.96402116402118*G0_1_1_4_1_0 - 1.96402116402118*G0_1_1_5_1_1; + A[194] = A[658]; + A[621] = A[743] + 0.338624338624344*G0_0_0_0_0_0 + 0.338624338624344*G0_0_0_0_0_1 - 0.338624338624344*G0_0_0_1_0_0 - 0.338624338624344*G0_0_0_2_0_1 + 0.338624338624344*G0_0_0_3_1_0 + 0.338624338624344*G0_0_0_3_1_1 - 0.338624338624344*G0_0_0_4_1_0 - 0.338624338624344*G0_0_0_5_1_1 + 0.33862433862434*G0_0_1_0_0_0 + 0.33862433862434*G0_0_1_0_0_1 - 0.33862433862434*G0_0_1_1_0_0 - 0.33862433862434*G0_0_1_2_0_1 + 0.33862433862434*G0_0_1_3_1_0 + 0.33862433862434*G0_0_1_3_1_1 - 0.33862433862434*G0_0_1_4_1_0 - 0.33862433862434*G0_0_1_5_1_1 + 0.33862433862435*G0_1_0_0_0_0 + 0.33862433862435*G0_1_0_0_0_1 - 0.33862433862435*G0_1_0_1_0_0 - 0.33862433862435*G0_1_0_2_0_1 + 0.33862433862435*G0_1_0_3_1_0 + 0.33862433862435*G0_1_0_3_1_1 - 0.33862433862435*G0_1_0_4_1_0 - 0.33862433862435*G0_1_0_5_1_1; + A[748] = A[658] + 0.67724867724869*G0_0_0_0_0_0 + 0.67724867724869*G0_0_0_0_0_1 - 0.67724867724869*G0_0_0_1_0_0 - 0.67724867724869*G0_0_0_2_0_1 + 0.67724867724869*G0_0_0_3_1_0 + 0.67724867724869*G0_0_0_3_1_1 - 0.67724867724869*G0_0_0_4_1_0 - 0.67724867724869*G0_0_0_5_1_1 - 0.677248677248681*G0_1_1_0_0_0 - 0.677248677248681*G0_1_1_0_0_1 + 0.677248677248681*G0_1_1_1_0_0 + 0.677248677248681*G0_1_1_2_0_1 - 0.677248677248681*G0_1_1_3_1_0 - 0.677248677248681*G0_1_1_3_1_1 + 0.677248677248681*G0_1_1_4_1_0 + 0.677248677248681*G0_1_1_5_1_1; + A[396] = A[658]; + A[864] = A[748]; + A[628] = -A[252] - 0.948148148148172*G0_1_1_0_0_0 - 0.948148148148172*G0_1_1_0_0_1 + 0.948148148148172*G0_1_1_1_0_0 + 0.948148148148172*G0_1_1_2_0_1 - 0.948148148148172*G0_1_1_3_1_0 - 0.948148148148172*G0_1_1_3_1_1 + 0.948148148148172*G0_1_1_4_1_0 + 0.948148148148172*G0_1_1_5_1_1; + A[830] = A[628]; + A[863] = A[252]; + A[627] = A[628]; + A[710] = A[245]; + A[156] = A[621]; + A[254] = A[428]; + A[434] = A[403]; + A[322] = 0.0; + A[772] = A[307]; + A[465] = 8.81249999999981*A[5]; + A[401] = -A[656] - 1.3883597883598*G0_0_1_0_0_0 - 1.3883597883598*G0_0_1_0_0_1 + 1.3883597883598*G0_0_1_1_0_0 + 1.3883597883598*G0_0_1_2_0_1 - 1.3883597883598*G0_0_1_3_1_0 - 1.3883597883598*G0_0_1_3_1_1 + 1.3883597883598*G0_0_1_4_1_0 + 1.3883597883598*G0_0_1_5_1_1 - 1.38835978835981*G0_1_0_0_0_0 - 1.38835978835981*G0_1_0_0_0_1 + 1.38835978835981*G0_1_0_1_0_0 + 1.38835978835981*G0_1_0_2_0_1 - 1.38835978835981*G0_1_0_3_1_0 - 1.38835978835981*G0_1_0_3_1_1 + 1.38835978835981*G0_1_0_4_1_0 + 1.38835978835981*G0_1_0_5_1_1; + A[76] = 0.0; + A[801] = A[656]; + A[0] = A[465]; + A[103] = -A[401] + 2.30264550264554*G0_0_0_0_0_0 + 2.30264550264554*G0_0_0_0_0_1 - 2.30264550264554*G0_0_0_1_0_0 - 2.30264550264554*G0_0_0_2_0_1 + 2.30264550264554*G0_0_0_3_1_0 + 2.30264550264554*G0_0_0_3_1_1 - 2.30264550264554*G0_0_0_4_1_0 - 2.30264550264554*G0_0_0_5_1_1; + A[834] = -A[656] + 1.04973544973546*G0_0_1_0_0_0 + 1.04973544973546*G0_0_1_0_0_1 - 1.04973544973546*G0_0_1_1_0_0 - 1.04973544973546*G0_0_1_2_0_1 + 1.04973544973546*G0_0_1_3_1_0 + 1.04973544973546*G0_0_1_3_1_1 - 1.04973544973546*G0_0_1_4_1_0 - 1.04973544973546*G0_0_1_5_1_1 + 1.04973544973548*G0_1_0_0_0_0 + 1.04973544973548*G0_1_0_0_0_1 - 1.04973544973548*G0_1_0_1_0_0 - 1.04973544973548*G0_1_0_2_0_1 + 1.04973544973548*G0_1_0_3_1_0 + 1.04973544973548*G0_1_0_3_1_1 - 1.04973544973548*G0_1_0_4_1_0 - 1.04973544973548*G0_1_0_5_1_1 + 2.43809523809528*G0_1_1_0_0_0 + 2.43809523809528*G0_1_1_0_0_1 - 2.43809523809528*G0_1_1_1_0_0 - 2.43809523809528*G0_1_1_2_0_1 + 2.43809523809528*G0_1_1_3_1_0 + 2.43809523809528*G0_1_1_3_1_1 - 2.43809523809528*G0_1_1_4_1_0 - 2.43809523809528*G0_1_1_5_1_1; + A[43] = A[421]; + A[843] = 0.0; + A[70] = A[534]; + A[165] = 0.0; + A[872] = 0.0; + A[109] = 0.0; + A[192] = A[834] + 2.57354497354501*G0_0_0_0_0_0 + 2.57354497354501*G0_0_0_0_0_1 - 2.57354497354501*G0_0_0_1_0_0 - 2.57354497354501*G0_0_0_2_0_1 + 2.57354497354501*G0_0_0_3_1_0 + 2.57354497354501*G0_0_0_3_1_1 - 2.57354497354501*G0_0_0_4_1_0 - 2.57354497354501*G0_0_0_5_1_1 - 2.57354497354501*G0_1_1_0_0_0 - 2.57354497354501*G0_1_1_0_0_1 + 2.57354497354501*G0_1_1_1_0_0 + 2.57354497354501*G0_1_1_2_0_1 - 2.57354497354501*G0_1_1_3_1_0 - 2.57354497354501*G0_1_1_3_1_1 + 2.57354497354501*G0_1_1_4_1_0 + 2.57354497354501*G0_1_1_5_1_1; + A[140] = 0.0; + A[514] = 0.0; + A[623] = A[245]; + A[543] = 0.0; + A[665] = 0.0; + A[569] = -A[252] - 0.812698412698417*G0_0_0_0_0_0 - 0.812698412698417*G0_0_0_0_0_1 + 0.812698412698417*G0_0_0_1_0_0 + 0.812698412698417*G0_0_0_2_0_1 - 0.812698412698417*G0_0_0_3_1_0 - 0.812698412698417*G0_0_0_3_1_1 + 0.812698412698417*G0_0_0_4_1_0 + 0.812698412698417*G0_0_0_5_1_1 - 0.13544973544974*G0_1_1_0_0_0 - 0.13544973544974*G0_1_1_0_0_1 + 0.13544973544974*G0_1_1_1_0_0 + 0.13544973544974*G0_1_1_2_0_1 - 0.13544973544974*G0_1_1_3_1_0 - 0.13544973544974*G0_1_1_3_1_1 + 0.13544973544974*G0_1_1_4_1_0 + 0.13544973544974*G0_1_1_5_1_1; + A[690] = 0.0; + A[267] = 0.0; + A[336] = A[656]; + A[296] = 0.0; + A[437] = 0.0; + A[361] = A[421]; + A[317] = 0.0; + A[470] = A[5]; + A[358] = 0.0; + A[808] = A[401]; + A[7] = A[5] - 0.425396825396828*G0_0_1_0_0_0 - 0.425396825396828*G0_0_1_0_0_1 + 0.425396825396828*G0_0_1_1_0_0 + 0.425396825396828*G0_0_1_2_0_1 - 0.425396825396828*G0_0_1_3_1_0 - 0.425396825396828*G0_0_1_3_1_1 + 0.425396825396828*G0_0_1_4_1_0 + 0.425396825396828*G0_0_1_5_1_1 - 0.425396825396829*G0_1_1_0_0_0 - 0.425396825396829*G0_1_1_0_0_1 + 0.425396825396829*G0_1_1_1_0_0 + 0.425396825396829*G0_1_1_2_0_1 - 0.425396825396829*G0_1_1_3_1_0 - 0.425396825396829*G0_1_1_3_1_1 + 0.425396825396829*G0_1_1_4_1_0 + 0.425396825396829*G0_1_1_5_1_1; + A[724] = 0.0; + A[827] = A[887]; + A[36] = A[181]; + A[751] = 0.0; + A[866] = A[401]; + A[65] = A[530]; + A[786] = 0.0; + A[158] = A[245]; + A[897] = -A[569] + 1.69312169312175*G0_0_1_0_0_0 + 1.69312169312175*G0_0_1_0_0_1 - 1.69312169312175*G0_0_1_1_0_0 - 1.69312169312175*G0_0_1_2_0_1 + 1.69312169312175*G0_0_1_3_1_0 + 1.69312169312175*G0_0_1_3_1_1 - 1.69312169312175*G0_0_1_4_1_0 - 1.69312169312175*G0_0_1_5_1_1 + 1.69312169312172*G0_1_0_0_0_0 + 1.69312169312172*G0_1_0_0_0_1 - 1.69312169312172*G0_1_0_1_0_0 - 1.69312169312172*G0_1_0_2_0_1 + 1.69312169312172*G0_1_0_3_1_0 + 1.69312169312172*G0_1_0_3_1_1 - 1.69312169312172*G0_1_0_4_1_0 - 1.69312169312172*G0_1_0_5_1_1 + 4.06349206349214*G0_1_1_0_0_0 + 4.06349206349214*G0_1_1_0_0_1 - 4.06349206349214*G0_1_1_1_0_0 - 4.06349206349214*G0_1_1_2_0_1 + 4.06349206349214*G0_1_1_3_1_0 + 4.06349206349214*G0_1_1_3_1_1 - 4.06349206349214*G0_1_1_4_1_0 - 4.06349206349214*G0_1_1_5_1_1; + A[114] = 0.0; + A[139] = 0.0; + A[168] = 0.0; + A[502] = A[181]; + A[205] = 0.0; + A[573] = 0.0; + A[533] = -A[530] + 0.524867724867732*G0_1_1_0_0_0 + 0.524867724867732*G0_1_1_0_0_1 - 0.524867724867732*G0_1_1_1_0_0 - 0.524867724867732*G0_1_1_2_0_1 + 0.524867724867732*G0_1_1_3_1_0 + 0.524867724867732*G0_1_1_3_1_1 - 0.524867724867732*G0_1_1_4_1_0 - 0.524867724867732*G0_1_1_5_1_1; + A[238] = 0.0; + A[604] = 0.0; + A[715] = -A[625] + 0.220105820105839*G0_1_1_0_0_0 + 0.220105820105839*G0_1_1_0_0_1 - 0.220105820105839*G0_1_1_1_0_0 - 0.220105820105839*G0_1_1_2_0_1 + 0.220105820105839*G0_1_1_3_1_0 + 0.220105820105839*G0_1_1_3_1_1 - 0.220105820105839*G0_1_1_4_1_0 - 0.220105820105839*G0_1_1_5_1_1; + A[709] = A[715] - 0.761904761904767*G0_0_0_0_0_0 - 0.761904761904767*G0_0_0_0_0_1 + 0.761904761904767*G0_0_0_1_0_0 + 0.761904761904767*G0_0_0_2_0_1 - 0.761904761904767*G0_0_0_3_1_0 - 0.761904761904767*G0_0_0_3_1_1 + 0.761904761904767*G0_0_0_4_1_0 + 0.761904761904767*G0_0_0_5_1_1 - 0.253968253968253*G0_0_1_0_0_0 - 0.253968253968253*G0_0_1_0_0_1 + 0.253968253968253*G0_0_1_1_0_0 + 0.253968253968253*G0_0_1_2_0_1 - 0.253968253968253*G0_0_1_3_1_0 - 0.253968253968253*G0_0_1_3_1_1 + 0.253968253968253*G0_0_1_4_1_0 + 0.253968253968253*G0_0_1_5_1_1 - 0.253968253968242*G0_1_0_0_0_0 - 0.253968253968242*G0_1_0_0_0_1 + 0.253968253968242*G0_1_0_1_0_0 + 0.253968253968242*G0_1_0_2_0_1 - 0.253968253968242*G0_1_0_3_1_0 - 0.253968253968242*G0_1_0_3_1_1 + 0.253968253968242*G0_1_0_4_1_0 + 0.253968253968242*G0_1_0_5_1_1; + A[125] = -A[709] - 1.11746031746033*G0_0_1_0_0_0 - 1.11746031746033*G0_0_1_0_0_1 + 1.11746031746033*G0_0_1_1_0_0 + 1.11746031746033*G0_0_1_2_0_1 - 1.11746031746033*G0_0_1_3_1_0 - 1.11746031746033*G0_0_1_3_1_1 + 1.11746031746033*G0_0_1_4_1_0 + 1.11746031746033*G0_0_1_5_1_1 + 0.728042328042336*G0_1_1_0_0_0 + 0.728042328042336*G0_1_1_0_0_1 - 0.728042328042336*G0_1_1_1_0_0 - 0.728042328042336*G0_1_1_2_0_1 + 0.728042328042336*G0_1_1_3_1_0 + 0.728042328042336*G0_1_1_3_1_1 - 0.728042328042336*G0_1_1_4_1_0 - 0.728042328042336*G0_1_1_5_1_1; + A[559] = A[125] - 0.101587301587305*G0_0_0_0_0_0 - 0.101587301587305*G0_0_0_0_0_1 + 0.101587301587305*G0_0_0_1_0_0 + 0.101587301587305*G0_0_0_2_0_1 - 0.101587301587305*G0_0_0_3_1_0 - 0.101587301587305*G0_0_0_3_1_1 + 0.101587301587305*G0_0_0_4_1_0 + 0.101587301587305*G0_0_0_5_1_1 + 0.101587301587309*G0_1_1_0_0_0 + 0.101587301587309*G0_1_1_0_0_1 - 0.101587301587309*G0_1_1_1_0_0 - 0.101587301587309*G0_1_1_2_0_1 + 0.101587301587309*G0_1_1_3_1_0 + 0.101587301587309*G0_1_1_3_1_1 - 0.101587301587309*G0_1_1_4_1_0 - 0.101587301587309*G0_1_1_5_1_1; + A[588] = A[559] + 1.11746031746033*G0_0_1_0_0_0 + 1.11746031746033*G0_0_1_0_0_1 - 1.11746031746033*G0_0_1_1_0_0 - 1.11746031746033*G0_0_1_2_0_1 + 1.11746031746033*G0_0_1_3_1_0 + 1.11746031746033*G0_0_1_3_1_1 - 1.11746031746033*G0_0_1_4_1_0 - 1.11746031746033*G0_0_1_5_1_1 - 1.11746031746033*G0_1_0_0_0_0 - 1.11746031746033*G0_1_0_0_0_1 + 1.11746031746033*G0_1_0_1_0_0 + 1.11746031746033*G0_1_0_2_0_1 - 1.11746031746033*G0_1_0_3_1_0 - 1.11746031746033*G0_1_0_3_1_1 + 1.11746031746033*G0_1_0_4_1_0 + 1.11746031746033*G0_1_0_5_1_1; + A[309] = A[125] + 1.1851851851852*G0_0_0_0_0_0 + 1.1851851851852*G0_0_0_0_0_1 - 1.1851851851852*G0_0_0_1_0_0 - 1.1851851851852*G0_0_0_2_0_1 + 1.1851851851852*G0_0_0_3_1_0 + 1.1851851851852*G0_0_0_3_1_1 - 1.1851851851852*G0_0_0_4_1_0 - 1.1851851851852*G0_0_0_5_1_1 + 2.30264550264553*G0_0_1_0_0_0 + 2.30264550264553*G0_0_1_0_0_1 - 2.30264550264553*G0_0_1_1_0_0 - 2.30264550264553*G0_0_1_2_0_1 + 2.30264550264553*G0_0_1_3_1_0 + 2.30264550264553*G0_0_1_3_1_1 - 2.30264550264553*G0_0_1_4_1_0 - 2.30264550264553*G0_0_1_5_1_1 + 0.0677248677248741*G0_1_0_0_0_0 + 0.0677248677248741*G0_1_0_0_0_1 - 0.0677248677248741*G0_1_0_1_0_0 - 0.0677248677248741*G0_1_0_2_0_1 + 0.0677248677248741*G0_1_0_3_1_0 + 0.0677248677248741*G0_1_0_3_1_1 - 0.0677248677248741*G0_1_0_4_1_0 - 0.0677248677248741*G0_1_0_5_1_1; + A[334] = A[709] + 0.829629629629638*G0_0_0_0_0_0 + 0.829629629629638*G0_0_0_0_0_1 - 0.829629629629638*G0_0_0_1_0_0 - 0.829629629629638*G0_0_0_2_0_1 + 0.829629629629638*G0_0_0_3_1_0 + 0.829629629629638*G0_0_0_3_1_1 - 0.829629629629638*G0_0_0_4_1_0 - 0.829629629629638*G0_0_0_5_1_1 - 0.829629629629645*G0_1_1_0_0_0 - 0.829629629629645*G0_1_1_0_0_1 + 0.829629629629645*G0_1_1_1_0_0 + 0.829629629629645*G0_1_1_2_0_1 - 0.829629629629645*G0_1_1_3_1_0 - 0.829629629629645*G0_1_1_3_1_1 + 0.829629629629645*G0_1_1_4_1_0 + 0.829629629629645*G0_1_1_5_1_1; + A[131] = A[334]; + A[805] = A[559] + 1.28677248677251*G0_0_0_0_0_0 + 1.28677248677251*G0_0_0_0_0_1 - 1.28677248677251*G0_0_0_1_0_0 - 1.28677248677251*G0_0_0_2_0_1 + 1.28677248677251*G0_0_0_3_1_0 + 1.28677248677251*G0_0_0_3_1_1 - 1.28677248677251*G0_0_0_4_1_0 - 1.28677248677251*G0_0_0_5_1_1 + 2.40423280423284*G0_0_1_0_0_0 + 2.40423280423284*G0_0_1_0_0_1 - 2.40423280423284*G0_0_1_1_0_0 - 2.40423280423284*G0_0_1_2_0_1 + 2.40423280423284*G0_0_1_3_1_0 + 2.40423280423284*G0_0_1_3_1_1 - 2.40423280423284*G0_0_1_4_1_0 - 2.40423280423284*G0_0_1_5_1_1 + 0.169312169312178*G0_1_0_0_0_0 + 0.169312169312178*G0_1_0_0_0_1 - 0.169312169312178*G0_1_0_1_0_0 - 0.169312169312178*G0_1_0_2_0_1 + 0.169312169312178*G0_1_0_3_1_0 + 0.169312169312178*G0_1_0_3_1_1 - 0.169312169312178*G0_1_0_4_1_0 - 0.169312169312178*G0_1_0_5_1_1; + A[94] = A[559]; + A[590] = A[125]; + A[652] = A[309] - 1.28677248677251*G0_0_0_0_0_0 - 1.28677248677251*G0_0_0_0_0_1 + 1.28677248677251*G0_0_0_1_0_0 + 1.28677248677251*G0_0_0_2_0_1 - 1.28677248677251*G0_0_0_3_1_0 - 1.28677248677251*G0_0_0_3_1_1 + 1.28677248677251*G0_0_0_4_1_0 + 1.28677248677251*G0_0_0_5_1_1 + 1.28677248677251*G0_1_1_0_0_0 + 1.28677248677251*G0_1_1_0_0_1 - 1.28677248677251*G0_1_1_1_0_0 - 1.28677248677251*G0_1_1_2_0_1 + 1.28677248677251*G0_1_1_3_1_0 + 1.28677248677251*G0_1_1_3_1_1 - 1.28677248677251*G0_1_1_4_1_0 - 1.28677248677251*G0_1_1_5_1_1; + A[187] = A[652]; + A[216] = A[652] - 1.11746031746033*G0_0_1_0_0_0 - 1.11746031746033*G0_0_1_0_0_1 + 1.11746031746033*G0_0_1_1_0_0 + 1.11746031746033*G0_0_1_2_0_1 - 1.11746031746033*G0_0_1_3_1_0 - 1.11746031746033*G0_0_1_3_1_1 + 1.11746031746033*G0_0_1_4_1_0 + 1.11746031746033*G0_0_1_5_1_1 + 1.11746031746033*G0_1_0_0_0_0 + 1.11746031746033*G0_1_0_0_0_1 - 1.11746031746033*G0_1_0_1_0_0 - 1.11746031746033*G0_1_0_2_0_1 + 1.11746031746033*G0_1_0_3_1_0 + 1.11746031746033*G0_1_0_3_1_1 - 1.11746031746033*G0_1_0_4_1_0 - 1.11746031746033*G0_1_0_5_1_1; + A[242] = 0.778835978835986*G0_0_1_0_0_0 + 0.778835978835986*G0_0_1_0_0_1 - 0.778835978835986*G0_0_1_1_0_0 - 0.778835978835986*G0_0_1_2_0_1 + 0.778835978835986*G0_0_1_3_1_0 + 0.778835978835986*G0_0_1_3_1_1 - 0.778835978835986*G0_0_1_4_1_0 - 0.778835978835986*G0_0_1_5_1_1 + 0.65185185185186*G0_1_1_0_0_0 + 0.65185185185186*G0_1_1_0_0_1 - 0.65185185185186*G0_1_1_1_0_0 - 0.65185185185186*G0_1_1_2_0_1 + 0.65185185185186*G0_1_1_3_1_0 + 0.65185185185186*G0_1_1_3_1_1 - 0.65185185185186*G0_1_1_4_1_0 - 0.65185185185186*G0_1_1_5_1_1; + A[273] = A[621] - 0.203174603174598*G0_0_0_0_0_0 - 0.203174603174598*G0_0_0_0_0_1 + 0.203174603174598*G0_0_0_1_0_0 + 0.203174603174598*G0_0_0_2_0_1 - 0.203174603174598*G0_0_0_3_1_0 - 0.203174603174598*G0_0_0_3_1_1 + 0.203174603174598*G0_0_0_4_1_0 + 0.203174603174598*G0_0_0_5_1_1 + 0.203174603174598*G0_1_1_0_0_0 + 0.203174603174598*G0_1_1_0_0_1 - 0.203174603174598*G0_1_1_1_0_0 - 0.203174603174598*G0_1_1_2_0_1 + 0.203174603174598*G0_1_1_3_1_0 + 0.203174603174598*G0_1_1_3_1_1 - 0.203174603174598*G0_1_1_4_1_0 - 0.203174603174598*G0_1_1_5_1_1; + A[444] = 0.0; + A[324] = 0.0; + A[479] = A[14]; + A[351] = 0.0; + A[731] = 0.0; + A[422] = A[887]; + A[382] = 0.0; + A[760] = 0.0; + A[413] = 0.0; + A[857] = A[887]; + A[88] = 0.0; + A[781] = 0.0; + A[890] = -A[428] + 2.30264550264554*G0_1_1_0_0_0 + 2.30264550264554*G0_1_1_0_0_1 - 2.30264550264554*G0_1_1_1_0_0 - 2.30264550264554*G0_1_1_2_0_1 + 2.30264550264554*G0_1_1_3_1_0 + 2.30264550264554*G0_1_1_3_1_1 - 2.30264550264554*G0_1_1_4_1_0 - 2.30264550264554*G0_1_1_5_1_1; + A[91] = -A[331] + 0.524867724867733*G0_0_0_0_0_0 + 0.524867724867733*G0_0_0_0_0_1 - 0.524867724867733*G0_0_0_1_0_0 - 0.524867724867733*G0_0_0_2_0_1 + 0.524867724867733*G0_0_0_3_1_0 + 0.524867724867733*G0_0_0_3_1_1 - 0.524867724867733*G0_0_0_4_1_0 - 0.524867724867733*G0_0_0_5_1_1; + A[822] = 0.0; + A[146] = 0.0; + A[855] = A[14]; + A[177] = 0.0; + A[884] = 0.0; + A[493] = 0.0; + A[196] = 0.0; + A[654] = A[741]; + A[578] = 0.0; + A[518] = 0.0; + A[231] = 0.0; + A[683] = A[805] - 1.1851851851852*G0_0_0_0_0_0 - 1.1851851851852*G0_0_0_0_0_1 + 1.1851851851852*G0_0_0_1_0_0 + 1.1851851851852*G0_0_0_2_0_1 - 1.1851851851852*G0_0_0_3_1_0 - 1.1851851851852*G0_0_0_3_1_1 + 1.1851851851852*G0_0_0_4_1_0 + 1.1851851851852*G0_0_0_5_1_1 + 1.1851851851852*G0_1_1_0_0_0 + 1.1851851851852*G0_1_1_0_0_1 - 1.1851851851852*G0_1_1_1_0_0 - 1.1851851851852*G0_1_1_2_0_1 + 1.1851851851852*G0_1_1_3_1_0 + 1.1851851851852*G0_1_1_3_1_1 - 1.1851851851852*G0_1_1_4_1_0 - 1.1851851851852*G0_1_1_5_1_1; + A[247] = A[683] - 1.11746031746033*G0_0_1_0_0_0 - 1.11746031746033*G0_0_1_0_0_1 + 1.11746031746033*G0_0_1_1_0_0 + 1.11746031746033*G0_0_1_2_0_1 - 1.11746031746033*G0_0_1_3_1_0 - 1.11746031746033*G0_0_1_3_1_1 + 1.11746031746033*G0_0_1_4_1_0 + 1.11746031746033*G0_0_1_5_1_1 + 1.11746031746033*G0_1_0_0_0_0 + 1.11746031746033*G0_1_0_0_0_1 - 1.11746031746033*G0_1_0_1_0_0 - 1.11746031746033*G0_1_0_2_0_1 + 1.11746031746033*G0_1_0_3_1_0 + 1.11746031746033*G0_1_0_3_1_1 - 1.11746031746033*G0_1_0_4_1_0 - 1.11746031746033*G0_1_0_5_1_1; + A[603] = 0.0; + A[555] = A[5]; + A[712] = A[247]; + A[632] = 0.0; + A[249] = A[743]; + A[669] = 0.0; + A[702] = 0.0; + A[303] = -A[805] + 1.84550264550266*G0_0_0_0_0_0 + 1.84550264550266*G0_0_0_0_0_1 - 1.84550264550266*G0_0_0_1_0_0 - 1.84550264550266*G0_0_0_2_0_1 + 1.84550264550266*G0_0_0_3_1_0 + 1.84550264550266*G0_0_0_3_1_1 - 1.84550264550266*G0_0_0_4_1_0 - 1.84550264550266*G0_0_0_5_1_1 + 1.11746031746033*G0_0_1_0_0_0 + 1.11746031746033*G0_0_1_0_0_1 - 1.11746031746033*G0_0_1_1_0_0 - 1.11746031746033*G0_0_1_2_0_1 + 1.11746031746033*G0_0_1_3_1_0 + 1.11746031746033*G0_0_1_3_1_1 - 1.11746031746033*G0_0_1_4_1_0 - 1.11746031746033*G0_0_1_5_1_1; + A[314] = -A[303] - 0.414814814814821*G0_0_1_0_0_0 - 0.414814814814821*G0_0_1_0_0_1 + 0.414814814814821*G0_0_1_1_0_0 + 0.414814814814821*G0_0_1_2_0_1 - 0.414814814814821*G0_0_1_3_1_0 - 0.414814814814821*G0_0_1_3_1_1 + 0.414814814814821*G0_0_1_4_1_0 + 0.414814814814821*G0_0_1_5_1_1 - 0.414814814814826*G0_1_0_0_0_0 - 0.414814814814826*G0_1_0_0_0_1 + 0.414814814814826*G0_1_0_1_0_0 + 0.414814814814826*G0_1_0_2_0_1 - 0.414814814814826*G0_1_0_3_1_0 - 0.414814814814826*G0_1_0_3_1_1 + 0.414814814814826*G0_1_0_4_1_0 + 0.414814814814826*G0_1_0_5_1_1 - 1.168253968254*G0_1_1_0_0_0 - 1.168253968254*G0_1_1_0_0_1 + 1.168253968254*G0_1_1_1_0_0 + 1.168253968254*G0_1_1_2_0_1 - 1.168253968254*G0_1_1_3_1_0 - 1.168253968254*G0_1_1_3_1_1 + 1.168253968254*G0_1_1_4_1_0 + 1.168253968254*G0_1_1_5_1_1; + A[132] = A[314] - 0.507936507936544*G0_0_0_0_0_0 - 0.507936507936544*G0_0_0_0_0_1 + 0.507936507936544*G0_0_0_1_0_0 + 0.507936507936544*G0_0_0_2_0_1 - 0.507936507936544*G0_0_0_3_1_0 - 0.507936507936544*G0_0_0_3_1_1 + 0.507936507936544*G0_0_0_4_1_0 + 0.507936507936544*G0_0_0_5_1_1 - 0.507936507936544*G0_0_1_0_0_0 - 0.507936507936544*G0_0_1_0_0_1 + 0.507936507936544*G0_0_1_1_0_0 + 0.507936507936544*G0_0_1_2_0_1 - 0.507936507936544*G0_0_1_3_1_0 - 0.507936507936544*G0_0_1_3_1_1 + 0.507936507936544*G0_0_1_4_1_0 + 0.507936507936544*G0_0_1_5_1_1 - 0.50793650793654*G0_1_0_0_0_0 - 0.50793650793654*G0_1_0_0_0_1 + 0.50793650793654*G0_1_0_1_0_0 + 0.50793650793654*G0_1_0_2_0_1 - 0.50793650793654*G0_1_0_3_1_0 - 0.50793650793654*G0_1_0_3_1_1 + 0.50793650793654*G0_1_0_4_1_0 + 0.50793650793654*G0_1_0_5_1_1; + A[597] = A[132]; + A[312] = A[314] - 1.62539682539685*G0_0_1_0_0_0 - 1.62539682539685*G0_0_1_0_0_1 + 1.62539682539685*G0_0_1_1_0_0 + 1.62539682539685*G0_0_1_2_0_1 - 1.62539682539685*G0_0_1_3_1_0 - 1.62539682539685*G0_0_1_3_1_1 + 1.62539682539685*G0_0_1_4_1_0 + 1.62539682539685*G0_0_1_5_1_1 - 1.62539682539684*G0_1_0_0_0_0 - 1.62539682539684*G0_1_0_0_0_1 + 1.62539682539684*G0_1_0_1_0_0 + 1.62539682539684*G0_1_0_2_0_1 - 1.62539682539684*G0_1_0_3_1_0 - 1.62539682539684*G0_1_0_3_1_1 + 1.62539682539684*G0_1_0_4_1_0 + 1.62539682539684*G0_1_0_5_1_1; + A[367] = A[312] - 0.507936507936511*G0_0_0_0_0_0 - 0.507936507936511*G0_0_0_0_0_1 + 0.507936507936511*G0_0_0_1_0_0 + 0.507936507936511*G0_0_0_2_0_1 - 0.507936507936511*G0_0_0_3_1_0 - 0.507936507936511*G0_0_0_3_1_1 + 0.507936507936511*G0_0_0_4_1_0 + 0.507936507936511*G0_0_0_5_1_1 + 0.507936507936506*G0_1_1_0_0_0 + 0.507936507936506*G0_1_1_0_0_1 - 0.507936507936506*G0_1_1_1_0_0 - 0.507936507936506*G0_1_1_2_0_1 + 0.507936507936506*G0_1_1_3_1_0 + 0.507936507936506*G0_1_1_3_1_1 - 0.507936507936506*G0_1_1_4_1_0 - 0.507936507936506*G0_1_1_5_1_1; + A[370] = A[312]; + A[134] = A[314] + 2.74285714285719*G0_0_0_0_0_0 + 2.74285714285719*G0_0_0_0_0_1 - 2.74285714285719*G0_0_0_1_0_0 - 2.74285714285719*G0_0_0_2_0_1 + 2.74285714285719*G0_0_0_3_1_0 + 2.74285714285719*G0_0_0_3_1_1 - 2.74285714285719*G0_0_0_4_1_0 - 2.74285714285719*G0_0_0_5_1_1 + 1.11746031746035*G0_0_1_0_0_0 + 1.11746031746035*G0_0_1_0_0_1 - 1.11746031746035*G0_0_1_1_0_0 - 1.11746031746035*G0_0_1_2_0_1 + 1.11746031746035*G0_0_1_3_1_0 + 1.11746031746035*G0_0_1_3_1_1 - 1.11746031746035*G0_0_1_4_1_0 - 1.11746031746035*G0_0_1_5_1_1 + 1.11746031746034*G0_1_0_0_0_0 + 1.11746031746034*G0_1_0_0_0_1 - 1.11746031746034*G0_1_0_1_0_0 - 1.11746031746034*G0_1_0_2_0_1 + 1.11746031746034*G0_1_0_3_1_0 + 1.11746031746034*G0_1_0_3_1_1 - 1.11746031746034*G0_1_0_4_1_0 - 1.11746031746034*G0_1_0_5_1_1; + A[394] = A[134] - 3.2507936507937*G0_0_0_0_0_0 - 3.2507936507937*G0_0_0_0_0_1 + 3.2507936507937*G0_0_0_1_0_0 + 3.2507936507937*G0_0_0_2_0_1 - 3.2507936507937*G0_0_0_3_1_0 - 3.2507936507937*G0_0_0_3_1_1 + 3.2507936507937*G0_0_0_4_1_0 + 3.2507936507937*G0_0_0_5_1_1 + 3.25079365079369*G0_1_1_0_0_0 + 3.25079365079369*G0_1_1_0_0_1 - 3.25079365079369*G0_1_1_1_0_0 - 3.25079365079369*G0_1_1_2_0_1 + 3.25079365079369*G0_1_1_3_1_0 + 3.25079365079369*G0_1_1_3_1_1 - 3.25079365079369*G0_1_1_4_1_0 - 3.25079365079369*G0_1_1_5_1_1; + A[599] = A[134]; + A[688] = A[314] - 0.507936507936539*G0_0_0_0_0_0 - 0.507936507936539*G0_0_0_0_0_1 + 0.507936507936539*G0_0_0_1_0_0 + 0.507936507936539*G0_0_0_2_0_1 - 0.507936507936539*G0_0_0_3_1_0 - 0.507936507936539*G0_0_0_3_1_1 + 0.507936507936539*G0_0_0_4_1_0 + 0.507936507936539*G0_0_0_5_1_1 + 0.507936507936546*G0_1_1_0_0_0 + 0.507936507936546*G0_1_1_0_0_1 - 0.507936507936546*G0_1_1_1_0_0 - 0.507936507936546*G0_1_1_2_0_1 + 0.507936507936546*G0_1_1_3_1_0 + 0.507936507936546*G0_1_1_3_1_1 - 0.507936507936546*G0_1_1_4_1_0 - 0.507936507936546*G0_1_1_5_1_1; + A[832] = A[367]; + A[476] = -A[5] + 0.203174603174605*G0_0_0_0_0_0 + 0.203174603174605*G0_0_0_0_0_1 - 0.203174603174605*G0_0_0_1_0_0 - 0.203174603174605*G0_0_0_2_0_1 + 0.203174603174605*G0_0_0_3_1_0 + 0.203174603174605*G0_0_0_3_1_1 - 0.203174603174605*G0_0_0_4_1_0 - 0.203174603174605*G0_0_0_5_1_1 + 0.203174603174604*G0_1_0_0_0_0 + 0.203174603174604*G0_1_0_0_0_1 - 0.203174603174604*G0_1_0_1_0_0 - 0.203174603174604*G0_1_0_2_0_1 + 0.203174603174604*G0_1_0_3_1_0 + 0.203174603174604*G0_1_0_3_1_1 - 0.203174603174604*G0_1_0_4_1_0 - 0.203174603174604*G0_1_0_5_1_1; + A[340] = A[805]; + A[21] = 0.0; + A[738] = A[273]; + A[425] = A[890]; + A[373] = A[897] + 3.2507936507937*G0_0_0_0_0_0 + 3.2507936507937*G0_0_0_0_0_1 - 3.2507936507937*G0_0_0_1_0_0 - 3.2507936507937*G0_0_0_2_0_1 + 3.2507936507937*G0_0_0_3_1_0 + 3.2507936507937*G0_0_0_3_1_1 - 3.2507936507937*G0_0_0_4_1_0 - 3.2507936507937*G0_0_0_5_1_1 - 3.2507936507937*G0_1_1_0_0_0 - 3.2507936507937*G0_1_1_0_0_1 + 3.2507936507937*G0_1_1_1_0_0 + 3.2507936507937*G0_1_1_2_0_1 - 3.2507936507937*G0_1_1_3_1_0 - 3.2507936507937*G0_1_1_3_1_1 + 3.2507936507937*G0_1_1_4_1_0 + 3.2507936507937*G0_1_1_5_1_1; + A[46] = 0.0; + A[769] = A[679] + 0.342857142857162*G0_0_0_0_0_0 + 0.342857142857162*G0_0_0_0_0_1 - 0.342857142857162*G0_0_0_1_0_0 - 0.342857142857162*G0_0_0_2_0_1 + 0.342857142857162*G0_0_0_3_1_0 + 0.342857142857162*G0_0_0_3_1_1 - 0.342857142857162*G0_0_0_4_1_0 - 0.342857142857162*G0_0_0_5_1_1 - 0.342857142857158*G0_1_1_0_0_0 - 0.342857142857158*G0_1_1_0_0_1 + 0.342857142857158*G0_1_1_1_0_0 + 0.342857142857158*G0_1_1_2_0_1 - 0.342857142857158*G0_1_1_3_1_0 - 0.342857142857158*G0_1_1_3_1_1 + 0.342857142857158*G0_1_1_4_1_0 + 0.342857142857158*G0_1_1_5_1_1; + A[450] = 0.0; + A[406] = 0.0; + A[83] = 0.0; + A[788] = 0.0; + A[11] = A[476]; + A[96] = -A[716] + 0.203174603174611*G0_0_0_0_0_0 + 0.203174603174611*G0_0_0_0_0_1 - 0.203174603174611*G0_0_0_1_0_0 - 0.203174603174611*G0_0_0_2_0_1 + 0.203174603174611*G0_0_0_3_1_0 + 0.203174603174611*G0_0_0_3_1_1 - 0.203174603174611*G0_0_0_4_1_0 - 0.203174603174611*G0_0_0_5_1_1; + A[815] = 0.0; + A[121] = A[181] + 0.425396825396831*G0_1_0_0_0_0 + 0.425396825396831*G0_1_0_0_0_1 - 0.425396825396831*G0_1_0_1_0_0 - 0.425396825396831*G0_1_0_2_0_1 + 0.425396825396831*G0_1_0_3_1_0 + 0.425396825396831*G0_1_0_3_1_1 - 0.425396825396831*G0_1_0_4_1_0 - 0.425396825396831*G0_1_0_5_1_1; + A[766] = -A[121] - 0.510052910052917*G0_0_0_0_0_0 - 0.510052910052917*G0_0_0_0_0_1 + 0.510052910052917*G0_0_0_1_0_0 + 0.510052910052917*G0_0_0_2_0_1 - 0.510052910052917*G0_0_0_3_1_0 - 0.510052910052917*G0_0_0_3_1_1 + 0.510052910052917*G0_0_0_4_1_0 + 0.510052910052917*G0_0_0_5_1_1; + A[846] = 0.0; + A[154] = -A[709] - 1.11746031746032*G0_1_0_0_0_0 - 1.11746031746032*G0_1_0_0_0_1 + 1.11746031746032*G0_1_0_1_0_0 + 1.11746031746032*G0_1_0_2_0_1 - 1.11746031746032*G0_1_0_3_1_0 - 1.11746031746032*G0_1_0_3_1_1 + 1.11746031746032*G0_1_0_4_1_0 + 1.11746031746032*G0_1_0_5_1_1 + 0.728042328042336*G0_1_1_0_0_0 + 0.728042328042336*G0_1_1_0_0_1 - 0.728042328042336*G0_1_1_1_0_0 - 0.728042328042336*G0_1_1_2_0_1 + 0.728042328042336*G0_1_1_3_1_0 + 0.728042328042336*G0_1_1_3_1_1 - 0.728042328042336*G0_1_1_4_1_0 - 0.728042328042336*G0_1_1_5_1_1; + A[877] = 0.0; + A[484] = 0.0; + A[191] = A[656]; + A[587] = A[534] + 0.425396825396829*G0_0_1_0_0_0 + 0.425396825396829*G0_0_1_0_0_1 - 0.425396825396829*G0_0_1_1_0_0 - 0.425396825396829*G0_0_1_2_0_1 + 0.425396825396829*G0_0_1_3_1_0 + 0.425396825396829*G0_0_1_3_1_1 - 0.425396825396829*G0_0_1_4_1_0 - 0.425396825396829*G0_0_1_5_1_1; + A[677] = -A[587] - 0.510052910052918*G0_1_1_0_0_0 - 0.510052910052918*G0_1_1_0_0_1 + 0.510052910052918*G0_1_1_1_0_0 + 0.510052910052918*G0_1_1_2_0_1 - 0.510052910052918*G0_1_1_3_1_0 - 0.510052910052918*G0_1_1_3_1_1 + 0.510052910052918*G0_1_1_4_1_0 + 0.510052910052918*G0_1_1_5_1_1; + A[511] = 0.0; + A[228] = 0.0; + A[610] = 0.0; + A[546] = 0.0; + A[506] = 0.651851851851859*G0_0_0_0_0_0 + 0.651851851851859*G0_0_0_0_0_1 - 0.651851851851859*G0_0_0_1_0_0 - 0.651851851851859*G0_0_0_2_0_1 + 0.651851851851859*G0_0_0_3_1_0 + 0.651851851851859*G0_0_0_3_1_1 - 0.651851851851859*G0_0_0_4_1_0 - 0.651851851851859*G0_0_0_5_1_1 + 0.778835978835987*G0_0_1_0_0_0 + 0.778835978835987*G0_0_1_0_0_1 - 0.778835978835987*G0_0_1_1_0_0 - 0.778835978835987*G0_0_1_2_0_1 + 0.778835978835987*G0_0_1_3_1_0 + 0.778835978835987*G0_0_1_3_1_1 - 0.778835978835987*G0_0_1_4_1_0 - 0.778835978835987*G0_0_1_5_1_1; + A[641] = 0.0; + A[537] = A[887]; + A[660] = 0.0; + A[283] = A[748]; + A[695] = 0.0; + A[310] = A[775]; + A[262] = 0.0; + A[333] = A[101]; + A[293] = 0.0; + A[745] = A[309] - 1.11746031746033*G0_0_1_0_0_0 - 1.11746031746033*G0_0_1_0_0_1 + 1.11746031746033*G0_0_1_1_0_0 + 1.11746031746033*G0_0_1_2_0_1 - 1.11746031746033*G0_0_1_3_1_0 - 1.11746031746033*G0_0_1_3_1_1 + 1.11746031746033*G0_0_1_4_1_0 + 1.11746031746033*G0_0_1_5_1_1 + 1.11746031746033*G0_1_0_0_0_0 + 1.11746031746033*G0_1_0_0_0_1 - 1.11746031746033*G0_1_0_1_0_0 - 1.11746031746033*G0_1_0_2_0_1 + 1.11746031746033*G0_1_0_3_1_0 + 1.11746031746033*G0_1_0_3_1_1 - 1.11746031746033*G0_1_0_4_1_0 - 1.11746031746033*G0_1_0_5_1_1; + A[432] = A[897]; + A[364] = A[132]; + A[320] = 0.0; + A[770] = A[625]; + A[459] = 0.0; + A[399] = A[748]; + A[355] = 0.0; + A[799] = A[334]; + A[105] = 0.0; + A[836] = -A[569] - 0.948148148148171*G0_0_0_0_0_0 - 0.948148148148171*G0_0_0_0_0_1 + 0.948148148148171*G0_0_0_1_0_0 + 0.948148148148171*G0_0_0_2_0_1 - 0.948148148148171*G0_0_0_3_1_0 - 0.948148148148171*G0_0_0_3_1_1 + 0.948148148148171*G0_0_0_4_1_0 + 0.948148148148171*G0_0_0_5_1_1; + A[33] = -A[506] + 0.524867724867733*G0_0_0_0_0_0 + 0.524867724867733*G0_0_0_0_0_1 - 0.524867724867733*G0_0_0_1_0_0 - 0.524867724867733*G0_0_0_2_0_1 + 0.524867724867733*G0_0_0_3_1_0 + 0.524867724867733*G0_0_0_3_1_1 - 0.524867724867733*G0_0_0_4_1_0 - 0.524867724867733*G0_0_0_5_1_1; + A[128] = A[709]; + A[869] = -A[628] + 0.812698412698434*G0_0_0_0_0_0 + 0.812698412698434*G0_0_0_0_0_1 - 0.812698412698434*G0_0_0_1_0_0 - 0.812698412698434*G0_0_0_2_0_1 + 0.812698412698434*G0_0_0_3_1_0 + 0.812698412698434*G0_0_0_3_1_1 - 0.812698412698434*G0_0_0_4_1_0 - 0.812698412698434*G0_0_0_5_1_1 - 1.55767195767197*G0_0_1_0_0_0 - 1.55767195767197*G0_0_1_0_0_1 + 1.55767195767197*G0_0_1_1_0_0 + 1.55767195767197*G0_0_1_2_0_1 - 1.55767195767197*G0_0_1_3_1_0 - 1.55767195767197*G0_0_1_3_1_1 + 1.55767195767197*G0_0_1_4_1_0 + 1.55767195767197*G0_0_1_5_1_1 - 1.55767195767197*G0_1_0_0_0_0 - 1.55767195767197*G0_1_0_0_0_1 + 1.55767195767197*G0_1_0_1_0_0 + 1.55767195767197*G0_1_0_2_0_1 - 1.55767195767197*G0_1_0_3_1_0 - 1.55767195767197*G0_1_0_3_1_1 + 1.55767195767197*G0_1_0_4_1_0 + 1.55767195767197*G0_1_0_5_1_1; + A[68] = A[533]; + A[163] = A[628]; + A[870] = 0.0; + A[111] = 0.0; + A[182] = A[647]; + A[142] = 0.0; + A[592] = A[679]; + A[221] = -A[213] + 0.220105820105836*G0_0_0_0_0_0 + 0.220105820105836*G0_0_0_0_0_1 - 0.220105820105836*G0_0_0_1_0_0 - 0.220105820105836*G0_0_0_2_0_1 + 0.220105820105836*G0_0_0_3_1_0 + 0.220105820105836*G0_0_0_3_1_1 - 0.220105820105836*G0_0_0_4_1_0 - 0.220105820105836*G0_0_0_5_1_1; + A[219] = A[221] + 0.406349206349211*G0_0_1_0_0_0 + 0.406349206349211*G0_0_1_0_0_1 - 0.406349206349211*G0_0_1_1_0_0 - 0.406349206349211*G0_0_1_2_0_1 + 0.406349206349211*G0_0_1_3_1_0 + 0.406349206349211*G0_0_1_3_1_1 - 0.406349206349211*G0_0_1_4_1_0 - 0.406349206349211*G0_0_1_5_1_1 + 0.406349206349205*G0_1_0_0_0_0 + 0.406349206349205*G0_1_0_0_0_1 - 0.406349206349205*G0_1_0_1_0_0 - 0.406349206349205*G0_1_0_2_0_1 + 0.406349206349205*G0_1_0_3_1_0 + 0.406349206349205*G0_1_0_3_1_1 - 0.406349206349205*G0_1_0_4_1_0 - 0.406349206349205*G0_1_0_5_1_1 - 0.101587301587311*G0_1_1_0_0_0 - 0.101587301587311*G0_1_1_0_0_1 + 0.101587301587311*G0_1_1_1_0_0 + 0.101587301587311*G0_1_1_2_0_1 - 0.101587301587311*G0_1_1_3_1_0 - 0.101587301587311*G0_1_1_3_1_1 + 0.101587301587311*G0_1_1_4_1_0 + 0.101587301587311*G0_1_1_5_1_1; + A[274] = A[221] + 0.152380952380964*G0_0_1_0_0_0 + 0.152380952380964*G0_0_1_0_0_1 - 0.152380952380964*G0_0_1_1_0_0 - 0.152380952380964*G0_0_1_2_0_1 + 0.152380952380964*G0_0_1_3_1_0 + 0.152380952380964*G0_0_1_3_1_1 - 0.152380952380964*G0_0_1_4_1_0 - 0.152380952380964*G0_0_1_5_1_1 + 0.152380952380965*G0_1_0_0_0_0 + 0.152380952380965*G0_1_0_0_0_1 - 0.152380952380965*G0_1_0_1_0_0 - 0.152380952380965*G0_1_0_2_0_1 + 0.152380952380965*G0_1_0_3_1_0 + 0.152380952380965*G0_1_0_3_1_1 - 0.152380952380965*G0_1_0_4_1_0 - 0.152380952380965*G0_1_0_5_1_1 + 0.152380952380967*G0_1_1_0_0_0 + 0.152380952380967*G0_1_1_0_0_1 - 0.152380952380967*G0_1_1_1_0_0 - 0.152380952380967*G0_1_1_2_0_1 + 0.152380952380967*G0_1_1_3_1_0 + 0.152380952380967*G0_1_1_3_1_1 - 0.152380952380967*G0_1_1_4_1_0 - 0.152380952380967*G0_1_1_5_1_1; + A[173] = 0.0; + A[617] = -A[242] + 0.524867724867732*G0_1_1_0_0_0 + 0.524867724867732*G0_1_1_0_0_1 - 0.524867724867732*G0_1_1_1_0_0 - 0.524867724867732*G0_1_1_2_0_1 + 0.524867724867732*G0_1_1_3_1_0 + 0.524867724867732*G0_1_1_3_1_1 - 0.524867724867732*G0_1_1_4_1_0 - 0.524867724867732*G0_1_1_5_1_1; + A[541] = 0.0; + A[497] = 0.0566137566137575*G0_0_1_0_0_0 + 0.0566137566137575*G0_0_1_0_0_1 - 0.0566137566137575*G0_0_1_1_0_0 - 0.0566137566137575*G0_0_1_2_0_1 + 0.0566137566137575*G0_0_1_3_1_0 + 0.0566137566137575*G0_0_1_3_1_1 - 0.0566137566137575*G0_0_1_4_1_0 - 0.0566137566137575*G0_0_1_5_1_1; + A[30] = -A[497] - 0.0566137566137574*G0_0_0_0_0_0 - 0.0566137566137574*G0_0_0_0_0_1 + 0.0566137566137574*G0_0_0_1_0_0 + 0.0566137566137574*G0_0_0_2_0_1 - 0.0566137566137574*G0_0_0_3_1_0 - 0.0566137566137574*G0_0_0_3_1_1 + 0.0566137566137574*G0_0_0_4_1_0 + 0.0566137566137574*G0_0_0_5_1_1; + A[2] = -A[497] - 0.0566137566137576*G0_1_1_0_0_0 - 0.0566137566137576*G0_1_1_0_0_1 + 0.0566137566137576*G0_1_1_1_0_0 + 0.0566137566137576*G0_1_1_2_0_1 - 0.0566137566137576*G0_1_1_3_1_0 - 0.0566137566137576*G0_1_1_3_1_1 + 0.0566137566137576*G0_1_1_4_1_0 + 0.0566137566137576*G0_1_1_5_1_1; + A[650] = A[621]; + A[538] = A[887]; + A[687] = A[367]; + A[567] = A[569]; + A[692] = 0.0; + A[269] = 0.0; + A[294] = 0.0; + A[443] = 0.0; + A[363] = A[569]; + A[779] = A[314]; + A[472] = A[7]; + A[392] = A[887]; + A[806] = -A[101] - 1.69312169312171*G0_0_0_0_0_0 - 1.69312169312171*G0_0_0_0_0_1 + 1.69312169312171*G0_0_0_1_0_0 + 1.69312169312171*G0_0_0_2_0_1 - 1.69312169312171*G0_0_0_3_1_0 - 1.69312169312171*G0_0_0_3_1_1 + 1.69312169312171*G0_0_0_4_1_0 + 1.69312169312171*G0_0_0_5_1_1; + A[25] = 0.0; + A[726] = 0.0; + A[385] = 0.0; + A[829] = A[132]; + A[34] = A[181] + 0.42539682539683*G0_0_1_0_0_0 + 0.42539682539683*G0_0_1_0_0_1 - 0.42539682539683*G0_0_1_1_0_0 - 0.42539682539683*G0_0_1_2_0_1 + 0.42539682539683*G0_0_1_3_1_0 + 0.42539682539683*G0_0_1_3_1_1 - 0.42539682539683*G0_0_1_4_1_0 - 0.42539682539683*G0_0_1_5_1_1; + A[40] = -A[34] - 0.510052910052917*G0_0_0_0_0_0 - 0.510052910052917*G0_0_0_0_0_1 + 0.510052910052917*G0_0_0_1_0_0 + 0.510052910052917*G0_0_0_2_0_1 - 0.510052910052917*G0_0_0_3_1_0 - 0.510052910052917*G0_0_0_3_1_1 + 0.510052910052917*G0_0_0_4_1_0 + 0.510052910052917*G0_0_0_5_1_1; + A[757] = 0.0; + A[418] = 0.0; + A[860] = A[628]; + A[63] = -A[534] - 0.203174603174605*G0_1_0_0_0_0 - 0.203174603174605*G0_1_0_0_0_1 + 0.203174603174605*G0_1_0_1_0_0 + 0.203174603174605*G0_1_0_2_0_1 - 0.203174603174605*G0_1_0_3_1_0 - 0.203174603174605*G0_1_0_3_1_1 + 0.203174603174605*G0_1_0_4_1_0 + 0.203174603174605*G0_1_0_5_1_1; + A[784] = 0.0; + A[895] = A[314]; + A[116] = 0.0; + A[819] = 0.0; + A[185] = A[621]; + A[149] = 0.0; + A[210] = A[5] - 0.425396825396829*G0_1_0_0_0_0 - 0.425396825396829*G0_1_0_0_0_1 + 0.425396825396829*G0_1_0_1_0_0 + 0.425396825396829*G0_1_0_2_0_1 - 0.425396825396829*G0_1_0_3_1_0 - 0.425396825396829*G0_1_0_3_1_1 + 0.425396825396829*G0_1_0_4_1_0 + 0.425396825396829*G0_1_0_5_1_1 - 0.425396825396829*G0_1_1_0_0_0 - 0.425396825396829*G0_1_1_0_0_1 + 0.425396825396829*G0_1_1_1_0_0 + 0.425396825396829*G0_1_1_2_0_1 - 0.425396825396829*G0_1_1_3_1_0 - 0.425396825396829*G0_1_1_3_1_1 + 0.425396825396829*G0_1_1_4_1_0 + 0.425396825396829*G0_1_1_5_1_1; + A[166] = 0.0; + A[624] = -A[716] + 0.203174603174612*G0_1_1_0_0_0 + 0.203174603174612*G0_1_1_0_0_1 - 0.203174603174612*G0_1_1_1_0_0 - 0.203174603174612*G0_1_1_2_0_1 + 0.203174603174612*G0_1_1_3_1_0 + 0.203174603174612*G0_1_1_3_1_1 - 0.203174603174612*G0_1_1_4_1_0 - 0.203174603174612*G0_1_1_5_1_1; + A[488] = 0.0; + A[659] = A[658]; + A[575] = 0.0; + A[531] = -A[63] + 0.287830687830693*G0_1_1_0_0_0 + 0.287830687830693*G0_1_1_0_0_1 - 0.287830687830693*G0_1_1_1_0_0 - 0.287830687830693*G0_1_1_2_0_1 + 0.287830687830693*G0_1_1_3_1_0 + 0.287830687830693*G0_1_1_3_1_1 - 0.287830687830693*G0_1_1_4_1_0 - 0.287830687830693*G0_1_1_5_1_1; + A[678] = A[213]; + A[606] = 0.0; + A[558] = A[806]; + A[717] = A[252]; + A[637] = 0.0; + A[244] = A[709]; + A[271] = A[736]; + A[306] = A[219] - 0.169312169312181*G0_0_0_0_0_0 - 0.169312169312181*G0_0_0_0_0_1 + 0.169312169312181*G0_0_0_1_0_0 + 0.169312169312181*G0_0_0_2_0_1 - 0.169312169312181*G0_0_0_3_1_0 - 0.169312169312181*G0_0_0_3_1_1 + 0.169312169312181*G0_0_0_4_1_0 + 0.169312169312181*G0_0_0_5_1_1 + 0.169312169312183*G0_1_1_0_0_0 + 0.169312169312183*G0_1_1_0_0_1 - 0.169312169312183*G0_1_1_1_0_0 - 0.169312169312183*G0_1_1_2_0_1 + 0.169312169312183*G0_1_1_3_1_0 + 0.169312169312183*G0_1_1_3_1_1 - 0.169312169312183*G0_1_1_4_1_0 - 0.169312169312183*G0_1_1_5_1_1; + A[353] = 0.0; + A[16] = 0.0; + A[733] = 0.0; + A[420] = A[14]; + A[376] = 0.0; + A[59] = 0.0; + A[758] = 0.0; + A[455] = 0.0; + A[411] = 0.0; + A[859] = A[394]; + A[86] = 0.0; + A[795] = -A[5] + 0.203174603174605*G0_0_0_0_0_0 + 0.203174603174605*G0_0_0_0_0_1 - 0.203174603174605*G0_0_0_1_0_0 - 0.203174603174605*G0_0_0_2_0_1 + 0.203174603174605*G0_0_0_3_1_0 + 0.203174603174605*G0_0_0_3_1_1 - 0.203174603174605*G0_0_0_4_1_0 - 0.203174603174605*G0_0_0_5_1_1 + 0.203174603174603*G0_0_1_0_0_0 + 0.203174603174603*G0_0_1_0_0_1 - 0.203174603174603*G0_0_1_1_0_0 - 0.203174603174603*G0_0_1_2_0_1 + 0.203174603174603*G0_0_1_3_1_0 + 0.203174603174603*G0_0_1_3_1_1 - 0.203174603174603*G0_0_1_4_1_0 - 0.203174603174603*G0_0_1_5_1_1; + A[888] = A[569]; + A[93] = A[806]; + A[824] = 0.0; + A[124] = A[775] + 0.507936507936516*G0_0_0_0_0_0 + 0.507936507936516*G0_0_0_0_0_1 - 0.507936507936516*G0_0_0_1_0_0 - 0.507936507936516*G0_0_0_2_0_1 + 0.507936507936516*G0_0_0_3_1_0 + 0.507936507936516*G0_0_0_3_1_1 - 0.507936507936516*G0_0_0_4_1_0 - 0.507936507936516*G0_0_0_5_1_1 + 0.507936507936515*G0_0_1_0_0_0 + 0.507936507936515*G0_0_1_0_0_1 - 0.507936507936515*G0_0_1_1_0_0 - 0.507936507936515*G0_0_1_2_0_1 + 0.507936507936515*G0_0_1_3_1_0 + 0.507936507936515*G0_0_1_3_1_1 - 0.507936507936515*G0_0_1_4_1_0 - 0.507936507936515*G0_0_1_5_1_1 + 0.507936507936515*G0_1_0_0_0_0 + 0.507936507936515*G0_1_0_0_0_1 - 0.507936507936515*G0_1_0_1_0_0 - 0.507936507936515*G0_1_0_2_0_1 + 0.507936507936515*G0_1_0_3_1_0 + 0.507936507936515*G0_1_0_3_1_1 - 0.507936507936515*G0_1_0_4_1_0 - 0.507936507936515*G0_1_0_5_1_1; + A[849] = 0.0; + A[175] = 0.0; + A[882] = 0.0; + A[495] = A[30]; + A[202] = 0.0; + A[580] = 0.0; + A[524] = 0.0; + A[233] = 0.0; + A[681] = A[216]; + A[613] = 0.0; + A[553] = 0.0; + A[706] = A[181]; + A[630] = 0.0; + A[251] = A[716]; + A[675] = A[210]; + A[280] = A[745]; + A[704] = 0.0; + A[301] = A[766]; + A[257] = 0.0; + A[342] = A[836]; + A[23] = 0.0; + A[740] = A[624]; + A[431] = A[836]; + A[375] = 0.0; + A[52] = 0.0; + A[767] = A[534]; + A[452] = 0.0; + A[404] = A[869]; + A[81] = 0.0; + A[802] = A[221]; + A[13] = A[14]; + A[98] = -A[716] + 0.338624338624345*G0_0_0_0_0_0 + 0.338624338624345*G0_0_0_0_0_1 - 0.338624338624345*G0_0_0_1_0_0 - 0.338624338624345*G0_0_0_2_0_1 + 0.338624338624345*G0_0_0_3_1_0 + 0.338624338624345*G0_0_0_3_1_1 - 0.338624338624345*G0_0_0_4_1_0 - 0.338624338624345*G0_0_0_5_1_1; + A[560] = -A[98] + 0.541798941798936*G0_0_1_0_0_0 + 0.541798941798936*G0_0_1_0_0_1 - 0.541798941798936*G0_0_1_1_0_0 - 0.541798941798936*G0_0_1_2_0_1 + 0.541798941798936*G0_0_1_3_1_0 + 0.541798941798936*G0_0_1_3_1_1 - 0.541798941798936*G0_0_1_4_1_0 - 0.541798941798936*G0_0_1_5_1_1 - 0.338624338624348*G0_1_1_0_0_0 - 0.338624338624348*G0_1_1_0_0_1 + 0.338624338624348*G0_1_1_1_0_0 + 0.338624338624348*G0_1_1_2_0_1 - 0.338624338624348*G0_1_1_3_1_0 - 0.338624338624348*G0_1_1_3_1_1 + 0.338624338624348*G0_1_1_4_1_0 + 0.338624338624348*G0_1_1_5_1_1; + A[817] = 0.0; + A[38] = A[181]; + A[123] = A[588]; + A[840] = 0.0; + A[75] = 0.0; + A[152] = A[617]; + A[875] = 0.0; + A[486] = 0.0; + A[189] = A[741]; + A[589] = A[124]; + A[517] = 0.0; + A[222] = A[367]; + A[620] = -A[245] - 1.69312169312171*G0_1_1_0_0_0 - 1.69312169312171*G0_1_1_0_0_1 + 1.69312169312171*G0_1_1_1_0_0 + 1.69312169312171*G0_1_1_2_0_1 - 1.69312169312171*G0_1_1_3_1_0 - 1.69312169312171*G0_1_1_3_1_1 + 1.69312169312171*G0_1_1_4_1_0 + 1.69312169312171*G0_1_1_5_1_1; + A[544] = 0.0; + A[508] = A[421]; + A[639] = 0.0; + A[535] = A[534]; + A[666] = 0.0; + A[697] = 0.0; + A[308] = A[715]; + A[264] = 0.0; + A[335] = -A[716] + 0.338624338624348*G0_1_1_0_0_0 + 0.338624338624348*G0_1_1_0_0_1 - 0.338624338624348*G0_1_1_1_0_0 - 0.338624338624348*G0_1_1_2_0_1 + 0.338624338624348*G0_1_1_3_1_0 + 0.338624338624348*G0_1_1_3_1_1 - 0.338624338624348*G0_1_1_4_1_0 - 0.338624338624348*G0_1_1_5_1_1; + A[291] = 0.0; + A[747] = A[834]; + A[438] = 0.0; + A[366] = A[192]; + A[318] = 0.0; + A[776] = A[805] - 1.11746031746033*G0_0_1_0_0_0 - 1.11746031746033*G0_0_1_0_0_1 + 1.11746031746033*G0_0_1_1_0_0 + 1.11746031746033*G0_0_1_2_0_1 - 1.11746031746033*G0_0_1_3_1_0 - 1.11746031746033*G0_0_1_3_1_1 + 1.11746031746033*G0_0_1_4_1_0 + 1.11746031746033*G0_0_1_5_1_1 + 1.11746031746033*G0_1_0_0_0_0 + 1.11746031746033*G0_1_0_0_0_1 - 1.11746031746033*G0_1_0_1_0_0 - 1.11746031746033*G0_1_0_2_0_1 + 1.11746031746033*G0_1_0_3_1_0 + 1.11746031746033*G0_1_0_3_1_1 - 1.11746031746033*G0_1_0_4_1_0 - 1.11746031746033*G0_1_0_5_1_1; + A[461] = 0.0; + A[397] = A[688]; + A[357] = 0.0; + A[797] = A[534]; + A[4] = A[5]; + A[721] = 0.0; + A[388] = 0.0; + A[838] = A[373]; + A[31] = -4.40624999999983*A[421]; + A[130] = A[769]; + A[66] = A[531]; + A[161] = A[335]; + A[113] = 0.0; + A[180] = A[645]; + A[136] = 0.0; + A[594] = A[274]; + A[215] = -A[683] + 1.11746031746033*G0_0_1_0_0_0 + 1.11746031746033*G0_0_1_0_0_1 - 1.11746031746033*G0_0_1_1_0_0 - 1.11746031746033*G0_0_1_2_0_1 + 1.11746031746033*G0_0_1_3_1_0 + 1.11746031746033*G0_0_1_3_1_1 - 1.11746031746033*G0_0_1_4_1_0 - 1.11746031746033*G0_0_1_5_1_1 + 1.84550264550266*G0_1_1_0_0_0 + 1.84550264550266*G0_1_1_0_0_1 - 1.84550264550266*G0_1_1_1_0_0 - 1.84550264550266*G0_1_1_2_0_1 + 1.84550264550266*G0_1_1_3_1_0 + 1.84550264550266*G0_1_1_3_1_1 - 1.84550264550266*G0_1_1_4_1_0 - 1.84550264550266*G0_1_1_5_1_1; + A[892] = -A[215] + 2.08253968253974*G0_0_0_0_0_0 + 2.08253968253974*G0_0_0_0_0_1 - 2.08253968253974*G0_0_0_1_0_0 - 2.08253968253974*G0_0_0_2_0_1 + 2.08253968253974*G0_0_0_3_1_0 + 2.08253968253974*G0_0_0_3_1_1 - 2.08253968253974*G0_0_0_4_1_0 - 2.08253968253974*G0_0_0_5_1_1 + 1.21058201058204*G0_0_1_0_0_0 + 1.21058201058204*G0_0_1_0_0_1 - 1.21058201058204*G0_0_1_1_0_0 - 1.21058201058204*G0_0_1_2_0_1 + 1.21058201058204*G0_0_1_3_1_0 + 1.21058201058204*G0_0_1_3_1_1 - 1.21058201058204*G0_0_1_4_1_0 - 1.21058201058204*G0_0_1_5_1_1 + 1.21058201058203*G0_1_0_0_0_0 + 1.21058201058203*G0_1_0_0_0_1 - 1.21058201058203*G0_1_0_1_0_0 - 1.21058201058203*G0_1_0_2_0_1 + 1.21058201058203*G0_1_0_3_1_0 + 1.21058201058203*G0_1_0_3_1_1 - 1.21058201058203*G0_1_0_4_1_0 - 1.21058201058203*G0_1_0_5_1_1; + A[427] = A[892]; + A[171] = 0.0; + A[619] = A[154]; + A[499] = A[34]; + A[206] = 0.0; + A[648] = A[96]; + A[528] = A[63]; + A[685] = A[307]; + A[565] = A[303]; + A[718] = A[252]; + A[441] = 0.0; + A[329] = 0.0; + A[390] = A[14]; + A[346] = 0.0; + A[804] = -A[273] - 0.880423280423283*G0_0_0_0_0_0 - 0.880423280423283*G0_0_0_0_0_1 + 0.880423280423283*G0_0_0_1_0_0 + 0.880423280423283*G0_0_0_2_0_1 - 0.880423280423283*G0_0_0_3_1_0 - 0.880423280423283*G0_0_0_3_1_1 + 0.880423280423283*G0_0_0_4_1_0 + 0.880423280423283*G0_0_0_5_1_1 - 0.541798941798942*G0_0_1_0_0_0 - 0.541798941798942*G0_0_1_0_0_1 + 0.541798941798942*G0_0_1_1_0_0 + 0.541798941798942*G0_0_1_2_0_1 - 0.541798941798942*G0_0_1_3_1_0 - 0.541798941798942*G0_0_1_3_1_1 + 0.541798941798942*G0_0_1_4_1_0 + 0.541798941798942*G0_0_1_5_1_1; + A[27] = 0.0; + A[728] = 0.0; + A[387] = 0.0; + A[831] = A[192]; + A[56] = 0.0; + A[755] = 0.0; + A[416] = 0.0; + A[862] = A[688]; + A[61] = 0.0566137566137575*G0_1_0_0_0_0 + 0.0566137566137575*G0_1_0_0_0_1 - 0.0566137566137575*G0_1_0_1_0_0 - 0.0566137566137575*G0_1_0_2_0_1 + 0.0566137566137575*G0_1_0_3_1_0 + 0.0566137566137575*G0_1_0_3_1_1 - 0.0566137566137575*G0_1_0_4_1_0 - 0.0566137566137575*G0_1_0_5_1_1; + A[466] = -A[61] - 0.0566137566137574*G0_0_0_0_0_0 - 0.0566137566137574*G0_0_0_0_0_1 + 0.0566137566137574*G0_0_0_1_0_0 + 0.0566137566137574*G0_0_0_2_0_1 - 0.0566137566137574*G0_0_0_3_1_0 - 0.0566137566137574*G0_0_0_3_1_1 + 0.0566137566137574*G0_0_0_4_1_0 + 0.0566137566137574*G0_0_0_5_1_1; + A[782] = 0.0; + A[893] = A[428]; + A[118] = 0.0; + A[821] = 0.0; + A[852] = 0.0; + A[212] = A[677]; + A[626] = A[335]; + A[490] = 0.0; + A[209] = 0.0; + A[657] = A[192]; + A[577] = 0.0; + A[521] = 0.0; + A[234] = 0.0; + A[676] = A[181]; + A[600] = 0.0; + A[556] = A[91]; + A[711] = -A[621] - 0.541798941798938*G0_1_0_0_0_0 - 0.541798941798938*G0_1_0_0_0_1 + 0.541798941798938*G0_1_0_1_0_0 + 0.541798941798938*G0_1_0_2_0_1 - 0.541798941798938*G0_1_0_3_1_0 - 0.541798941798938*G0_1_0_3_1_1 + 0.541798941798938*G0_1_0_4_1_0 + 0.541798941798938*G0_1_0_5_1_1 - 0.880423280423282*G0_1_1_0_0_0 - 0.880423280423282*G0_1_1_0_0_1 + 0.880423280423282*G0_1_1_1_0_0 + 0.880423280423282*G0_1_1_2_0_1 - 0.880423280423282*G0_1_1_3_1_0 - 0.880423280423282*G0_1_1_3_1_1 + 0.880423280423282*G0_1_1_4_1_0 + 0.880423280423282*G0_1_1_5_1_1; + A[635] = 0.0; + A[246] = A[711]; + A[670] = 0.0; + A[277] = A[219]; + A[448] = 0.0; + A[304] = A[769]; + A[475] = A[5] - 0.42539682539683*G0_0_0_0_0_0 - 0.42539682539683*G0_0_0_0_0_1 + 0.42539682539683*G0_0_0_1_0_0 + 0.42539682539683*G0_0_0_2_0_1 - 0.42539682539683*G0_0_0_3_1_0 - 0.42539682539683*G0_0_0_3_1_1 + 0.42539682539683*G0_0_0_4_1_0 + 0.42539682539683*G0_0_0_5_1_1 - 0.425396825396829*G0_1_0_0_0_0 - 0.425396825396829*G0_1_0_0_0_1 + 0.425396825396829*G0_1_0_1_0_0 + 0.425396825396829*G0_1_0_2_0_1 - 0.425396825396829*G0_1_0_3_1_0 - 0.425396825396829*G0_1_0_3_1_1 + 0.425396825396829*G0_1_0_4_1_0 + 0.425396825396829*G0_1_0_5_1_1; + A[339] = A[804]; + A[18] = 0.0; + A[735] = A[270]; + A[426] = A[658]; + A[378] = 0.0; + A[49] = 0.0; + A[764] = 0.0; + A[457] = 0.0; + A[409] = 0.0; + A[84] = 0.0; + A[793] = 0.0; + A[8] = -A[5] + 0.203174603174604*G0_0_1_0_0_0 + 0.203174603174604*G0_0_1_0_0_1 - 0.203174603174604*G0_0_1_1_0_0 - 0.203174603174604*G0_0_1_2_0_1 + 0.203174603174604*G0_0_1_3_1_0 + 0.203174603174604*G0_0_1_3_1_1 - 0.203174603174604*G0_0_1_4_1_0 - 0.203174603174604*G0_0_1_5_1_1 + 0.203174603174604*G0_1_1_0_0_0 + 0.203174603174604*G0_1_1_0_0_1 - 0.203174603174604*G0_1_1_1_0_0 - 0.203174603174604*G0_1_1_2_0_1 + 0.203174603174604*G0_1_1_3_1_0 + 0.203174603174604*G0_1_1_3_1_1 - 0.203174603174604*G0_1_1_4_1_0 - 0.203174603174604*G0_1_1_5_1_1; + A[886] = A[421]; + A[95] = A[560]; + A[810] = 0.0; + A[126] = A[274] + 0.0846560846560904*G0_0_0_0_0_0 + 0.0846560846560904*G0_0_0_0_0_1 - 0.0846560846560904*G0_0_0_1_0_0 - 0.0846560846560904*G0_0_0_2_0_1 + 0.0846560846560904*G0_0_0_3_1_0 + 0.0846560846560904*G0_0_0_3_1_1 - 0.0846560846560904*G0_0_0_4_1_0 - 0.0846560846560904*G0_0_0_5_1_1 - 0.0846560846560903*G0_1_1_0_0_0 - 0.0846560846560903*G0_1_1_0_0_1 + 0.0846560846560903*G0_1_1_1_0_0 + 0.0846560846560903*G0_1_1_2_0_1 - 0.0846560846560903*G0_1_1_3_1_0 - 0.0846560846560903*G0_1_1_3_1_1 + 0.0846560846560903*G0_1_1_4_1_0 + 0.0846560846560903*G0_1_1_5_1_1; + A[851] = 0.0; + A[157] = A[215]; + A[880] = 0.0; + A[481] = 0.0; + A[200] = 0.0; + A[582] = 0.0; + A[522] = 0.0; + A[227] = 0.0; + A[615] = A[5]; + A[551] = 0.0; + A[708] = A[98]; + A[644] = 0.0; + A[253] = A[252]; + A[673] = 0.0; + A[278] = A[743]; + A[698] = 0.0; + A[315] = 0.0; + A[259] = 0.0; + A[344] = A[836]; + A[288] = 0.0; + A[742] = A[219]; + A[429] = A[748]; + A[369] = A[834]; + A[50] = 0.0; + A[773] = A[715]; + A[462] = 0.0; + A[402] = A[373]; + A[79] = 0.0; + A[800] = A[335]; + A[15] = 0.0; + A[100] = A[303]; + A[835] = A[312]; + A[44] = A[421]; + A[133] = A[394]; + A[842] = 0.0; + A[73] = A[887]; + A[150] = A[5]; + A[873] = 0.0; + A[106] = 0.0; + A[195] = 0.0; + A[591] = A[126]; + A[515] = 0.0; + A[224] = A[892]; + A[622] = A[215]; + A[542] = 0.0; + A[653] = -A[621] - 0.541798941798943*G0_0_1_0_0_0 - 0.541798941798943*G0_0_1_0_0_1 + 0.541798941798943*G0_0_1_1_0_0 + 0.541798941798943*G0_0_1_2_0_1 - 0.541798941798943*G0_0_1_3_1_0 - 0.541798941798943*G0_0_1_3_1_1 + 0.541798941798943*G0_0_1_4_1_0 + 0.541798941798943*G0_0_1_5_1_1 - 0.880423280423282*G0_1_1_0_0_0 - 0.880423280423282*G0_1_1_0_0_1 + 0.880423280423282*G0_1_1_1_0_0 + 0.880423280423282*G0_1_1_2_0_1 - 0.880423280423282*G0_1_1_3_1_0 - 0.880423280423282*G0_1_1_3_1_1 + 0.880423280423282*G0_1_1_4_1_0 + 0.880423280423282*G0_1_1_5_1_1; + A[664] = 0.0; + A[568] = A[103]; + A[691] = 0.0; + A[266] = 0.0; + A[337] = A[221]; + A[297] = 0.0; + A[749] = A[748]; + A[436] = 0.0; + A[360] = A[14]; + A[316] = 0.0; + A[774] = A[309]; + A[471] = A[270] - 0.778835978835986*G0_0_0_0_0_0 - 0.778835978835986*G0_0_0_0_0_1 + 0.778835978835986*G0_0_0_1_0_0 + 0.778835978835986*G0_0_0_2_0_1 - 0.778835978835986*G0_0_0_3_1_0 - 0.778835978835986*G0_0_0_3_1_1 + 0.778835978835986*G0_0_0_4_1_0 + 0.778835978835986*G0_0_0_5_1_1 + 0.778835978835986*G0_1_1_0_0_0 + 0.778835978835986*G0_1_1_0_0_1 - 0.778835978835986*G0_1_1_1_0_0 - 0.778835978835986*G0_1_1_2_0_1 + 0.778835978835986*G0_1_1_3_1_0 + 0.778835978835986*G0_1_1_3_1_1 - 0.778835978835986*G0_1_1_4_1_0 - 0.778835978835986*G0_1_1_5_1_1; + A[395] = A[628]; + A[359] = 0.0; + A[6] = A[471]; + A[723] = 0.0; + A[37] = A[181]; + A[752] = 0.0; + A[865] = A[892] - 2.74285714285719*G0_0_0_0_0_0 - 2.74285714285719*G0_0_0_0_0_1 + 2.74285714285719*G0_0_0_1_0_0 + 2.74285714285719*G0_0_0_2_0_1 - 2.74285714285719*G0_0_0_3_1_0 - 2.74285714285719*G0_0_0_3_1_1 + 2.74285714285719*G0_0_0_4_1_0 + 2.74285714285719*G0_0_0_5_1_1 + 2.74285714285719*G0_1_1_0_0_0 + 2.74285714285719*G0_1_1_0_0_1 - 2.74285714285719*G0_1_1_1_0_0 - 2.74285714285719*G0_1_1_2_0_1 + 2.74285714285719*G0_1_1_3_1_0 + 2.74285714285719*G0_1_1_3_1_1 - 2.74285714285719*G0_1_1_4_1_0 - 2.74285714285719*G0_1_1_5_1_1; + A[64] = A[534] + 0.42539682539683*G0_1_0_0_0_0 + 0.42539682539683*G0_1_0_0_0_1 - 0.42539682539683*G0_1_0_1_0_0 - 0.42539682539683*G0_1_0_2_0_1 + 0.42539682539683*G0_1_0_3_1_0 + 0.42539682539683*G0_1_0_3_1_1 - 0.42539682539683*G0_1_0_4_1_0 - 0.42539682539683*G0_1_0_5_1_1; + A[67] = -A[64] - 0.510052910052918*G0_1_1_0_0_0 - 0.510052910052918*G0_1_1_0_0_1 + 0.510052910052918*G0_1_1_1_0_0 + 0.510052910052918*G0_1_1_2_0_1 - 0.510052910052918*G0_1_1_3_1_0 - 0.510052910052918*G0_1_1_3_1_1 + 0.510052910052918*G0_1_1_4_1_0 + 0.510052910052918*G0_1_1_5_1_1; + A[159] = A[624]; + A[898] = A[869]; + A[115] = 0.0; + A[186] = A[279]; + A[138] = 0.0; + A[596] = A[334]; + A[217] = A[775] + 0.507936507936508*G0_0_0_0_0_0 + 0.507936507936508*G0_0_0_0_0_1 - 0.507936507936508*G0_0_0_1_0_0 - 0.507936507936508*G0_0_0_2_0_1 + 0.507936507936508*G0_0_0_3_1_0 + 0.507936507936508*G0_0_0_3_1_1 - 0.507936507936508*G0_0_0_4_1_0 - 0.507936507936508*G0_0_0_5_1_1 - 0.507936507936511*G0_1_1_0_0_0 - 0.507936507936511*G0_1_1_0_0_1 + 0.507936507936511*G0_1_1_1_0_0 + 0.507936507936511*G0_1_1_2_0_1 - 0.507936507936511*G0_1_1_3_1_0 - 0.507936507936511*G0_1_1_3_1_1 + 0.507936507936511*G0_1_1_4_1_0 + 0.507936507936511*G0_1_1_5_1_1; + A[169] = 0.0; + A[629] = A[890]; + A[501] = A[181]; + A[204] = 0.0; + A[646] = A[181]; + A[570] = 0.0; + A[526] = A[61]; + A[239] = 0.0; + A[563] = A[98]; + A[241] = A[181]; + A[298] = 0.0; + A[447] = 0.0; + A[327] = 0.0; + A[468] = A[5]; + A[348] = 0.0; + A[29] = 0.0; + A[730] = 0.0; + A[381] = 0.0; + A[833] = A[252]; + A[54] = 0.0; + A[761] = 0.0; + A[414] = 0.0; + A[856] = A[421]; + A[780] = 0.0; + A[891] = A[658]; + A[823] = 0.0; + A[145] = 0.0; + A[854] = 0.0; + A[178] = 0.0; + A[885] = A[14]; + A[492] = 0.0; + A[199] = 0.0; + A[655] = A[306]; + A[579] = 0.0; + A[519] = 0.0; + A[236] = 0.0; + A[682] = A[217]; + A[602] = 0.0; + A[554] = 0.0; + A[713] = A[620]; + A[633] = 0.0; + A[248] = A[620]; + A[668] = 0.0; + A[275] = A[624]; + A[703] = 0.0; + A[302] = A[534]; + A[477] = A[14]; + A[341] = A[806]; + A[20] = 0.0; + A[737] = A[534]; + A[424] = A[134]; + A[372] = A[403]; + A[47] = 0.0; + A[762] = 0.0; + A[451] = 0.0; + A[407] = 0.0; + A[82] = 0.0; + A[791] = 0.0; + A[10] = A[475]; + A[97] = A[213]; + A[812] = 0.0; + A[41] = A[506]; + A[120] = A[5]; + A[845] = 0.0; + A[155] = A[620]; + A[878] = 0.0; + A[483] = 0.0; + A[190] = A[306]; + A[584] = 0.0; + A[512] = 0.0; + A[229] = 0.0; + A[609] = 0.0; + A[549] = 0.0; + A[505] = A[40]; + A[642] = 0.0; + A[255] = 0.0; + A[663] = 0.0; + A[284] = A[748]; + A[700] = 0.0; + A[313] = A[865]; + A[261] = 0.0; + A[330] = A[795]; + A[286] = 0.0; + A[744] = A[279]; + A[435] = 0.0; + A[371] = A[836]; + A[323] = 0.0; + A[771] = A[306]; + A[464] = 0.0; + A[400] = A[865]; + A[77] = 0.0; + A[798] = A[101]; + A[1] = A[466]; + A[102] = A[569]; + A[837] = A[403]; + A[42] = A[421]; + A[135] = 0.0; + A[868] = A[403]; + A[71] = A[534]; + A[164] = A[890]; + A[871] = 0.0; + A[108] = 0.0; + A[193] = A[658]; + A[141] = 0.0; + A[593] = A[709]; + A[218] = A[683]; + A[616] = A[151]; + A[540] = 0.0; + A[496] = A[31]; + A[651] = A[279]; + A[539] = A[887]; + A[686] = A[221]; + A[566] = A[101]; + A[693] = 0.0; + A[268] = 0.0; + A[295] = 0.0; + A[442] = 0.0; + A[362] = A[887]; + A[473] = A[8]; + A[393] = A[103]; + A[809] = A[836]; + A[24] = 0.0; + A[725] = 0.0; + A[384] = 0.0; + A[826] = A[421]; + A[35] = A[500]; + A[750] = 0.0; + A[419] = 0.0; + A[867] = A[373]; + A[62] = A[527]; + A[787] = 0.0; + A[896] = A[836]; + A[117] = 0.0; + A[184] = A[126]; + A[148] = 0.0; + A[598] = A[394]; + A[211] = A[181]; + A[167] = 0.0; + A[503] = A[181]; + A[572] = 0.0; + A[532] = A[67]; + A[689] = A[892]; + A[605] = 0.0; + A[561] = A[96]; + A[714] = A[743]; + A[243] = A[98]; + A[272] = A[534]; + A[445] = 0.0; + A[325] = 0.0; + A[478] = A[14]; + A[350] = 0.0; + A[732] = 0.0; + A[423] = A[569]; + A[383] = 0.0; + A[759] = 0.0; + A[412] = 0.0; + A[858] = A[103]; + A[89] = 0.0; + A[794] = 0.0; + A[889] = A[134]; + A[90] = A[5]; + A[825] = A[14]; + A[147] = 0.0; + A[848] = 0.0; + A[176] = 0.0; + A[883] = 0.0; + A[494] = 0.0; + A[197] = 0.0; + A[581] = 0.0; + A[525] = -A[61] - 0.0566137566137576*G0_1_1_0_0_0 - 0.0566137566137576*G0_1_1_0_0_1 + 0.0566137566137576*G0_1_1_1_0_0 + 0.0566137566137576*G0_1_1_2_0_1 - 0.0566137566137576*G0_1_1_3_1_0 - 0.0566137566137576*G0_1_1_3_1_1 + 0.0566137566137576*G0_1_1_4_1_0 + 0.0566137566137576*G0_1_1_5_1_1; + A[230] = 0.0; + A[680] = A[215]; + A[612] = 0.0; + A[552] = 0.0; + A[707] = A[242]; + A[631] = 0.0; + A[250] = A[715]; + A[674] = 0.0; + A[281] = -A[273] - 0.880423280423283*G0_0_0_0_0_0 - 0.880423280423283*G0_0_0_0_0_1 + 0.880423280423283*G0_0_0_1_0_0 + 0.880423280423283*G0_0_0_2_0_1 - 0.880423280423283*G0_0_0_3_1_0 - 0.880423280423283*G0_0_0_3_1_1 + 0.880423280423283*G0_0_0_4_1_0 + 0.880423280423283*G0_0_0_5_1_1 - 0.541798941798937*G0_1_0_0_0_0 - 0.541798941798937*G0_1_0_0_0_1 + 0.541798941798937*G0_1_0_1_0_0 + 0.541798941798937*G0_1_0_2_0_1 - 0.541798941798937*G0_1_0_3_1_0 - 0.541798941798937*G0_1_0_3_1_1 + 0.541798941798937*G0_1_0_4_1_0 + 0.541798941798937*G0_1_0_5_1_1; + A[705] = A[240]; + A[300] = A[765]; + A[256] = 0.0; + A[343] = A[401]; + A[22] = 0.0; + A[739] = A[274]; + A[430] = A[314]; + A[374] = A[897]; + A[53] = 0.0; + A[768] = A[303]; + A[453] = 0.0; + A[405] = 0.0; + A[80] = 0.0; + A[789] = 0.0; + A[12] = A[14]; + A[99] = A[273]; + A[814] = 0.0; + A[39] = A[504]; + A[122] = A[587]; + A[847] = 0.0; + A[74] = A[887]; + A[153] = -A[98] + 0.54179894179894*G0_1_0_0_0_0 + 0.54179894179894*G0_1_0_0_0_1 - 0.54179894179894*G0_1_0_1_0_0 - 0.54179894179894*G0_1_0_2_0_1 + 0.54179894179894*G0_1_0_3_1_0 + 0.54179894179894*G0_1_0_3_1_1 - 0.54179894179894*G0_1_0_4_1_0 - 0.54179894179894*G0_1_0_5_1_1 - 0.338624338624348*G0_1_1_0_0_0 - 0.338624338624348*G0_1_1_0_0_1 + 0.338624338624348*G0_1_1_1_0_0 + 0.338624338624348*G0_1_1_2_0_1 - 0.338624338624348*G0_1_1_3_1_0 - 0.338624338624348*G0_1_1_3_1_1 + 0.338624338624348*G0_1_1_4_1_0 + 0.338624338624348*G0_1_1_5_1_1; + A[876] = 0.0; + A[485] = 0.0; + A[188] = A[653]; + A[586] = A[121]; + A[510] = 0.0; + A[223] = A[688]; + A[611] = 0.0; + A[547] = 0.0; + A[507] = A[421]; + A[640] = 0.0; + A[536] = A[534]; + A[661] = 0.0; + A[282] = A[834]; + A[694] = 0.0; + A[311] = A[776]; + A[263] = 0.0; + A[332] = A[534]; + A[292] = 0.0; + A[746] = A[281]; + A[433] = A[869]; + A[365] = A[628]; + A[321] = 0.0; + A[777] = A[312]; + A[458] = 0.0; + A[398] = A[252]; + A[354] = 0.0; + A[796] = A[331]; + A[3] = A[5]; + A[720] = 0.0; + A[104] = A[569]; + A[839] = A[897]; + A[32] = A[497]; + A[129] = A[274]; + A[69] = A[534]; + A[162] = A[628]; + A[110] = 0.0; + A[183] = A[96]; + A[143] = 0.0; + A[595] = A[769]; + A[220] = A[307]; + A[172] = 0.0; + A[618] = A[153]; + A[498] = A[33]; + A[649] = A[126]; + A[529] = A[64]; + A[684] = A[219]; + A[564] = A[273]; + A[719] = A[428]; + A[440] = 0.0; + A[328] = 0.0; + A[778] = A[865]; + A[467] = A[2]; + A[391] = A[421]; + A[347] = 0.0; + A[807] = A[836]; + A[26] = 0.0; + A[727] = 0.0; + A[386] = 0.0; + A[828] = A[569]; + A[57] = 0.0; + A[756] = 0.0; + A[417] = 0.0; + A[861] = A[658]; + A[60] = A[525]; + A[785] = 0.0; + A[894] = A[748]; + A[119] = 0.0; + A[818] = 0.0; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p1_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p1_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p1_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q4_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p1_q4_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p1_q4_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q1_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q1_excafe.h new file mode 100644 index 0000000..d3444a9 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q1_excafe.h @@ -0,0 +1,136 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 3.27 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -x[0][0]; + const double var_3 = x[1][0] + var_2; + const double var_4 = var_1*w[0][4] + var_3*w[0][11]; + const double var_5 = w[0][6] + -4.0000000000000000000000000*w[0][9]; + const double var_6 = var_3*var_5; + const double var_7 = x[1][1] + var_0; + const double var_8 = -0.5000000000000000000000000*w[0][0] + 2.0000000000000000000000000*w[0][3]; + const double var_9 = var_7*var_8; + const double var_10 = x[2][0] + var_2; + const double var_11 = 2.0000000000000000000000000*w[0][9] + -0.5000000000000000000000000*w[0][6]; + const double var_12 = var_10*var_11; + const double var_13 = var_9 + var_6 + var_12; + const double var_14 = var_1*var_3 + -var_10*var_7; + const double var_15 = var_14; + const double var_16 = std::abs(var_15); + const double var_17 = var_14; + const double var_18 = var_10*w[0][10] + var_7*w[0][5]; + const double var_19 = var_18 + -var_4; + const double var_20 = var_10*w[0][7] + var_7*w[0][2]; + const double var_21 = var_1*w[0][1] + var_3*w[0][8]; + const double var_22 = -var_20 + var_21; + const double var_23 = 2.0000000000000000000000000*var_19 + 0.5000000000000000000000000*var_22; + const double var_24 = var_23 + var_1*var_8; + const double var_25 = 0.5000000000000000000000000*w[0][0] + -2.0000000000000000000000000*w[0][3]; + const double var_26 = var_25*var_7 + var_11*var_3; + const double var_27 = -2.0000000000000000000000000*w[0][9] + 0.5000000000000000000000000*w[0][6]; + const double var_28 = var_10*var_27; + const double var_29 = var_26 + var_28; + const double var_30 = var_29 + var_24; + const double var_31 = var_3*var_3 + var_7*var_7; + A[14] = 0.3333333333333333148296163*var_16*var_30*var_31/(var_17*var_17*var_17); + A[35] = A[14]; + const double var_32 = var_1*var_7 + var_10*var_3; + const double var_33 = var_27*var_3; + const double var_34 = var_12 + var_33; + const double var_35 = var_20 + -var_21; + const double var_36 = var_4 + -var_18; + const double var_37 = 0.5000000000000000000000000*var_35 + 2.0000000000000000000000000*var_36; + const double var_38 = w[0][0] + -4.0000000000000000000000000*w[0][3]; + const double var_39 = var_34 + var_37 + var_1*var_38; + const double var_40 = var_10*var_25; + const double var_41 = var_1*var_11; + const double var_42 = var_40 + var_41; + const double var_43 = var_39*var_7 + var_31*var_8 + var_3*var_42; + const double var_44 = var_1*var_25; + const double var_45 = var_37 + var_44; + const double var_46 = 4.0000000000000000000000000*w[0][9] + -w[0][6]; + const double var_47 = var_10*var_46; + const double var_48 = var_45 + var_47 + var_33; + const double var_49 = var_24 + var_28; + const double var_50 = var_3*var_3*var_48 + var_43*var_7 + var_32*var_49; + A[2] = 0.3333333333333333148296163*var_16*var_50/(var_17*var_17*var_17); + A[33] = A[2]; + const double var_51 = var_23 + var_29; + A[12] = A[2]; + const double var_52 = var_1*var_1 + var_10*var_10; + A[7] = 0.3333333333333333148296163*var_16*var_30*var_52/(var_17*var_17*var_17); + const double var_53 = var_26 + var_24; + const double var_54 = var_3*var_53; + const double var_55 = var_35 + 4.0000000000000000000000000*var_36; + const double var_56 = 4.0000000000000000000000000*w[0][3] + -w[0][0]; + const double var_57 = var_1*var_56 + var_51; + const double var_58 = var_1*var_34 + var_57*var_7; + const double var_59 = var_10*var_13 + var_54; + const double var_60 = var_1*var_58 + var_45*var_52 + var_10*var_59; + A[1] = 0.3333333333333333148296163*var_16*var_60/(var_17*var_17*var_17); + A[6] = A[1]; + const double var_61 = var_9 + var_44; + A[32] = 0.0000000000000000000000000; + const double var_62 = var_10*var_38 + var_41; + A[16] = 0.0000000000000000000000000; + A[3] = 0.0000000000000000000000000; + const double var_63 = var_6 + var_47; + A[11] = 0.0000000000000000000000000; + const double var_64 = var_45 + var_34 + var_9; + A[5] = 0.0000000000000000000000000; + A[8] = 0.3333333333333333148296163*var_16*var_32*var_64/(var_17*var_17*var_17); + A[34] = A[8]; + A[13] = A[8]; + A[19] = 0.0000000000000000000000000; + A[4] = 0.0000000000000000000000000; + A[30] = 0.0000000000000000000000000; + A[10] = 0.0000000000000000000000000; + A[20] = 0.0000000000000000000000000; + const double var_65 = var_40 + var_3*var_56; + const double var_66 = var_1*var_63 + var_51*var_7 + var_10*var_65; + const double var_67 = var_1*var_62 + var_54; + const double var_68 = var_3*var_67 + var_66*var_7 + var_32*var_55 + var_49*var_52; + const double var_69 = 0.3333333333333333148296163*var_68 + var_10*var_3*var_34 + var_1*var_61*var_7; + A[0] = var_16*var_69/(var_17*var_17*var_17); + A[21] = A[0]; + A[29] = A[8]; + A[28] = A[7]; + A[24] = 0.0000000000000000000000000; + A[23] = A[2]; + A[18] = 0.0000000000000000000000000; + A[22] = A[1]; + A[17] = 0.0000000000000000000000000; + A[26] = 0.0000000000000000000000000; + A[27] = A[1]; + A[25] = 0.0000000000000000000000000; + A[15] = 0.0000000000000000000000000; + A[9] = 0.0000000000000000000000000; + A[31] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q1_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q1_quadrature.h new file mode 100644 index 0000000..68514fd --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q1_quadrature.h @@ -0,0 +1,8453 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P2_Q1_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P2_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q1_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q1_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q1_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q1_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q1_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q1_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p2_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W1 = 0.5; + // Quadrature points on the UFC reference element: (0.333333333333333, 0.333333333333333) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[1][2] = \ + {{-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + static const double FE1_C0_D01[1][4] = \ + {{-0.333333333333333, 0.333333333333334, 1.33333333333333, -1.33333333333333}}; + + // Array of non-zero columns + static const unsigned int nzc11[4] = {6, 7, 9, 10}; + + // Array of non-zero columns + static const unsigned int nzc10[4] = {6, 8, 9, 11}; + + // Array of non-zero columns + static const unsigned int nzc7[4] = {0, 2, 3, 5}; + + // Array of non-zero columns + static const unsigned int nzc8[4] = {0, 1, 3, 4}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 72. + double G[12]; + G[0] = K_00*W1*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*W1*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*W1*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*W1*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*W1*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*W1*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*W1*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*W1*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*W1*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*W1*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*W1*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*W1*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 149 + // Only 1 integration point, omitting IP loop. + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 32 + for (unsigned int r = 0; r < 4; r++) + { + F0 += FE1_C0_D01[0][r]*w[0][nzc8[r]]; + F1 += FE1_C0_D01[0][r]*w[0][nzc7[r]]; + F2 += FE1_C0_D01[0][r]*w[0][nzc11[r]]; + F3 += FE1_C0_D01[0][r]*w[0][nzc10[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 21 + double I[3]; + // Number of operations: 7 + I[0] = (F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 7 + I[1] = (F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 7 + I[2] = (F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 96 + for (unsigned int j = 0; j < 2; j++) + { + for (unsigned int k = 0; k < 2; k++) + { + // Number of operations to compute entry: 3 + A[nzc1[j]*6 + nzc1[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc1[j]*6 + nzc2[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*6 + nzc1[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*6 + nzc2[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc4[j]*6 + nzc4[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc4[j]*6 + nzc5[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*6 + nzc4[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*6 + nzc5[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p2_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q1_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q1_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q1_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q1_tensor.h new file mode 100644 index 0000000..afc694b --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q1_tensor.h @@ -0,0 +1,8442 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P2_Q1_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P2_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q1_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q1_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q1_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q1_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q1_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q1_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p2_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 192 + // Number of operations (multiply-add pairs) for tensor contraction: 158 + // Total number of operations (multiply-add pairs): 361 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0 = det*(w[0][3]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1 = det*(w[0][3]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0 = det*(w[0][4]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1 = det*(w[0][5]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0 = det*(w[0][6]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1 = det*(w[0][6]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0 = det*(w[0][7]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1 = det*(w[0][8]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0 = det*(w[0][9]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1 = det*(w[0][9]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0 = det*(w[0][10]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1 = det*(w[0][11]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0 = det*(w[0][3]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1 = det*(w[0][3]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0 = det*(w[0][4]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1 = det*(w[0][5]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0 = det*(w[0][6]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1 = det*(w[0][6]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0 = det*(w[0][7]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1 = det*(w[0][8]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0 = det*(w[0][9]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1 = det*(w[0][9]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0 = det*(w[0][10]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1 = det*(w[0][11]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0 = det*(w[0][3]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1 = det*(w[0][3]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0 = det*(w[0][4]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1 = det*(w[0][5]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0 = det*(w[0][6]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1 = det*(w[0][6]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0 = det*(w[0][7]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1 = det*(w[0][8]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0 = det*(w[0][9]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1 = det*(w[0][9]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0 = det*(w[0][10]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1 = det*(w[0][11]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0 = det*(w[0][3]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1 = det*(w[0][3]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0 = det*(w[0][4]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1 = det*(w[0][5]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0 = det*(w[0][6]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1 = det*(w[0][6]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0 = det*(w[0][7]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1 = det*(w[0][8]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0 = det*(w[0][9]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1 = det*(w[0][9]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0 = det*(w[0][10]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1 = det*(w[0][11]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[9] = 0.0; + A[18] = 0.0; + A[20] = 0.0; + A[31] = 0.0; + A[3] = 0.0; + A[17] = 0.0; + A[24] = 0.0; + A[8] = -0.166666666666667*G0_0_1_0_0_0 - 0.166666666666667*G0_0_1_0_0_1 + 0.166666666666667*G0_0_1_1_0_0 + 0.166666666666667*G0_0_1_2_0_1 + 0.666666666666667*G0_0_1_3_0_0 + 0.666666666666667*G0_0_1_3_0_1 - 0.666666666666667*G0_0_1_4_0_0 - 0.666666666666667*G0_0_1_5_0_1 - 0.166666666666667*G0_0_1_6_1_0 - 0.166666666666667*G0_0_1_6_1_1 + 0.166666666666667*G0_0_1_7_1_0 + 0.166666666666667*G0_0_1_8_1_1 + 0.666666666666667*G0_0_1_9_1_0 + 0.666666666666667*G0_0_1_9_1_1 - 0.666666666666667*G0_0_1_10_1_0 - 0.666666666666667*G0_0_1_11_1_1; + A[28] = -0.166666666666667*G0_0_0_0_0_0 - 0.166666666666667*G0_0_0_0_0_1 + 0.166666666666667*G0_0_0_1_0_0 + 0.166666666666667*G0_0_0_2_0_1 + 0.666666666666667*G0_0_0_3_0_0 + 0.666666666666667*G0_0_0_3_0_1 - 0.666666666666667*G0_0_0_4_0_0 - 0.666666666666667*G0_0_0_5_0_1 - 0.166666666666667*G0_0_0_6_1_0 - 0.166666666666667*G0_0_0_6_1_1 + 0.166666666666667*G0_0_0_7_1_0 + 0.166666666666667*G0_0_0_8_1_1 + 0.666666666666667*G0_0_0_9_1_0 + 0.666666666666667*G0_0_0_9_1_1 - 0.666666666666667*G0_0_0_10_1_0 - 0.666666666666667*G0_0_0_11_1_1; + A[11] = 0.0; + A[30] = 0.0; + A[4] = 0.0; + A[25] = 0.0; + A[7] = A[28]; + A[34] = -0.166666666666667*G0_1_0_0_0_0 - 0.166666666666667*G0_1_0_0_0_1 + 0.166666666666667*G0_1_0_1_0_0 + 0.166666666666667*G0_1_0_2_0_1 + 0.666666666666667*G0_1_0_3_0_0 + 0.666666666666667*G0_1_0_3_0_1 - 0.666666666666667*G0_1_0_4_0_0 - 0.666666666666667*G0_1_0_5_0_1 - 0.166666666666667*G0_1_0_6_1_0 - 0.166666666666667*G0_1_0_6_1_1 + 0.166666666666667*G0_1_0_7_1_0 + 0.166666666666667*G0_1_0_8_1_1 + 0.666666666666667*G0_1_0_9_1_0 + 0.666666666666667*G0_1_0_9_1_1 - 0.666666666666667*G0_1_0_10_1_0 - 0.666666666666667*G0_1_0_11_1_1; + A[13] = A[34]; + A[33] = -A[34] + 0.166666666666667*G0_1_1_0_0_0 + 0.166666666666667*G0_1_1_0_0_1 - 0.166666666666667*G0_1_1_1_0_0 - 0.166666666666667*G0_1_1_2_0_1 - 0.666666666666667*G0_1_1_3_0_0 - 0.666666666666667*G0_1_1_3_0_1 + 0.666666666666667*G0_1_1_4_0_0 + 0.666666666666667*G0_1_1_5_0_1 + 0.166666666666667*G0_1_1_6_1_0 + 0.166666666666667*G0_1_1_6_1_1 - 0.166666666666667*G0_1_1_7_1_0 - 0.166666666666667*G0_1_1_8_1_1 - 0.666666666666667*G0_1_1_9_1_0 - 0.666666666666667*G0_1_1_9_1_1 + 0.666666666666667*G0_1_1_10_1_0 + 0.666666666666667*G0_1_1_11_1_1; + A[1] = -A[34] + 0.166666666666667*G0_0_0_0_0_0 + 0.166666666666667*G0_0_0_0_0_1 - 0.166666666666667*G0_0_0_1_0_0 - 0.166666666666667*G0_0_0_2_0_1 - 0.666666666666667*G0_0_0_3_0_0 - 0.666666666666667*G0_0_0_3_0_1 + 0.666666666666667*G0_0_0_4_0_0 + 0.666666666666667*G0_0_0_5_0_1 + 0.166666666666667*G0_0_0_6_1_0 + 0.166666666666667*G0_0_0_6_1_1 - 0.166666666666667*G0_0_0_7_1_0 - 0.166666666666667*G0_0_0_8_1_1 - 0.666666666666667*G0_0_0_9_1_0 - 0.666666666666667*G0_0_0_9_1_1 + 0.666666666666667*G0_0_0_10_1_0 + 0.666666666666667*G0_0_0_11_1_1; + A[29] = A[8]; + A[14] = -0.166666666666667*G0_1_1_0_0_0 - 0.166666666666667*G0_1_1_0_0_1 + 0.166666666666667*G0_1_1_1_0_0 + 0.166666666666667*G0_1_1_2_0_1 + 0.666666666666667*G0_1_1_3_0_0 + 0.666666666666667*G0_1_1_3_0_1 - 0.666666666666667*G0_1_1_4_0_0 - 0.666666666666667*G0_1_1_5_0_1 - 0.166666666666667*G0_1_1_6_1_0 - 0.166666666666667*G0_1_1_6_1_1 + 0.166666666666667*G0_1_1_7_1_0 + 0.166666666666667*G0_1_1_8_1_1 + 0.666666666666667*G0_1_1_9_1_0 + 0.666666666666667*G0_1_1_9_1_1 - 0.666666666666667*G0_1_1_10_1_0 - 0.666666666666667*G0_1_1_11_1_1; + A[10] = 0.0; + A[5] = 0.0; + A[26] = 0.0; + A[6] = -A[8] + 0.166666666666667*G0_0_0_0_0_0 + 0.166666666666667*G0_0_0_0_0_1 - 0.166666666666667*G0_0_0_1_0_0 - 0.166666666666667*G0_0_0_2_0_1 - 0.666666666666667*G0_0_0_3_0_0 - 0.666666666666667*G0_0_0_3_0_1 + 0.666666666666667*G0_0_0_4_0_0 + 0.666666666666667*G0_0_0_5_0_1 + 0.166666666666667*G0_0_0_6_1_0 + 0.166666666666667*G0_0_0_6_1_1 - 0.166666666666667*G0_0_0_7_1_0 - 0.166666666666667*G0_0_0_8_1_1 - 0.666666666666667*G0_0_0_9_1_0 - 0.666666666666667*G0_0_0_9_1_1 + 0.666666666666667*G0_0_0_10_1_0 + 0.666666666666667*G0_0_0_11_1_1; + A[35] = A[14]; + A[23] = -A[8] + 0.166666666666667*G0_1_1_0_0_0 + 0.166666666666667*G0_1_1_0_0_1 - 0.166666666666667*G0_1_1_1_0_0 - 0.166666666666667*G0_1_1_2_0_1 - 0.666666666666667*G0_1_1_3_0_0 - 0.666666666666667*G0_1_1_3_0_1 + 0.666666666666667*G0_1_1_4_0_0 + 0.666666666666667*G0_1_1_5_0_1 + 0.166666666666667*G0_1_1_6_1_0 + 0.166666666666667*G0_1_1_6_1_1 - 0.166666666666667*G0_1_1_7_1_0 - 0.166666666666667*G0_1_1_8_1_1 - 0.666666666666667*G0_1_1_9_1_0 - 0.666666666666667*G0_1_1_9_1_1 + 0.666666666666667*G0_1_1_10_1_0 + 0.666666666666667*G0_1_1_11_1_1; + A[21] = -A[23] - 0.166666666666667*G0_0_0_0_0_0 - 0.166666666666667*G0_0_0_0_0_1 + 0.166666666666667*G0_0_0_1_0_0 + 0.166666666666667*G0_0_0_2_0_1 + 0.666666666666667*G0_0_0_3_0_0 + 0.666666666666667*G0_0_0_3_0_1 - 0.666666666666667*G0_0_0_4_0_0 - 0.666666666666667*G0_0_0_5_0_1 - 0.166666666666667*G0_0_0_6_1_0 - 0.166666666666667*G0_0_0_6_1_1 + 0.166666666666667*G0_0_0_7_1_0 + 0.166666666666667*G0_0_0_8_1_1 + 0.666666666666667*G0_0_0_9_1_0 + 0.666666666666667*G0_0_0_9_1_1 - 0.666666666666667*G0_0_0_10_1_0 - 0.666666666666667*G0_0_0_11_1_1 - 0.166666666666667*G0_1_0_0_0_0 - 0.166666666666667*G0_1_0_0_0_1 + 0.166666666666667*G0_1_0_1_0_0 + 0.166666666666667*G0_1_0_2_0_1 + 0.666666666666667*G0_1_0_3_0_0 + 0.666666666666667*G0_1_0_3_0_1 - 0.666666666666667*G0_1_0_4_0_0 - 0.666666666666667*G0_1_0_5_0_1 - 0.166666666666667*G0_1_0_6_1_0 - 0.166666666666667*G0_1_0_6_1_1 + 0.166666666666667*G0_1_0_7_1_0 + 0.166666666666667*G0_1_0_8_1_1 + 0.666666666666667*G0_1_0_9_1_0 + 0.666666666666667*G0_1_0_9_1_1 - 0.666666666666667*G0_1_0_10_1_0 - 0.666666666666667*G0_1_0_11_1_1; + A[0] = A[21]; + A[22] = A[1]; + A[19] = 0.0; + A[16] = 0.0; + A[12] = A[33]; + A[27] = A[6]; + A[15] = 0.0; + A[32] = 0.0; + A[2] = A[23]; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p2_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q1_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q1_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q1_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q2_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q2_excafe.h new file mode 100644 index 0000000..2088971 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q2_excafe.h @@ -0,0 +1,455 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 55.75 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -x[0][0]; + const double var_3 = x[1][0] + var_2; + const double var_4 = x[1][1] + var_0; + const double var_5 = x[2][0] + var_2; + const double var_6 = -var_3*var_5*var_5*w[0][9] + var_1*var_1*var_4*w[0][3]; + const double var_7 = -var_4 + var_1; + const double var_8 = -var_5 + var_3; + const double var_9 = var_1*var_4*var_8*w[0][6] + var_3*var_5*var_7*w[0][0]; + const double var_10 = 0.2000000000000000111022302*var_9; + A[7] = 0.0000000000000000000000000; + const double var_11 = var_1*var_1 + var_5*var_5; + const double var_12 = var_4*w[0][2] + -var_3*w[0][8]; + const double var_13 = var_3*var_5; + const double var_14 = var_1*var_4; + const double var_15 = var_13 + var_14; + const double var_16 = var_3*w[0][8] + -var_4*w[0][2]; + const double var_17 = var_15*var_16; + const double var_18 = var_11*var_12 + var_17; + const double var_19 = var_5*w[0][10]; + const double var_20 = var_1*w[0][4]; + const double var_21 = var_1*w[0][3]; + const double var_22 = var_5*w[0][9] + -var_21 + var_20 + -var_19; + const double var_23 = var_11*var_22; + const double var_24 = var_18 + var_23; + const double var_25 = -var_3*var_3*var_5*w[0][10] + var_1*var_4*var_4*w[0][4]; + const double var_26 = 2.0000000000000000000000000*var_6; + const double var_27 = var_25 + var_26; + const double var_28 = var_24 + var_3*var_5*var_8*w[0][11] + var_1*var_4*var_7*w[0][5] + 2.0000000000000000000000000*var_27; + A[100] = 0.0000000000000000000000000; + const double var_29 = var_1*var_3; + const double var_30 = -var_4*var_5 + var_29; + const double var_31 = var_30; + const double var_32 = std::abs(var_31); + const double var_33 = var_30; + const double var_34 = var_3*w[0][3] + -var_4*w[0][9]; + const double var_35 = var_4*w[0][10] + -var_3*w[0][4]; + const double var_36 = var_1*var_35*var_5; + const double var_37 = var_1*var_34*var_5 + var_36; + const double var_38 = -var_1*var_1*var_4*w[0][5] + var_3*var_5*var_5*w[0][11]; + const double var_39 = var_4*var_5 + var_29; + const double var_40 = var_4*var_5*var_5*w[0][3] + -var_1*var_1*var_3*w[0][9]; + const double var_41 = var_1*w[0][11] + -var_5*w[0][5]; + const double var_42 = var_40 + var_39*var_41; + const double var_43 = -var_1*var_1*var_4*w[0][4] + var_3*var_5*var_5*w[0][10]; + const double var_44 = 4.0000000000000000000000000*var_22 + var_16; + const double var_45 = 0.3333333333333333148296163*var_11*var_44; + const double var_46 = var_5*w[0][7] + -var_1*w[0][1]; + const double var_47 = var_1*w[0][5] + -var_5*w[0][11]; + const double var_48 = var_47 + var_46; + const double var_49 = var_4*w[0][5]; + const double var_50 = -var_3*w[0][11] + var_49; + const double var_51 = var_3*w[0][9]; + const double var_52 = var_50 + -var_4*w[0][3] + var_51; + const double var_53 = -var_5*w[0][7] + var_1*w[0][1]; + const double var_54 = var_7*w[0][0] + var_8*w[0][6]; + const double var_55 = var_54 + var_12; + const double var_56 = 0.6666666666666666296592325*var_55 + 3.0000000000000000000000000*var_53 + 4.6666666666666660745477202*var_52; + const double var_57 = -var_1*var_1*var_3*w[0][10] + var_4*var_5*var_5*w[0][4]; + const double var_58 = 0.3333333333333333148296163*var_57; + const double var_59 = var_15*var_56 + var_45 + 3.6666666666666665186369300*var_42 + 4.6666666666666660745477202*var_6 + var_37 + 7.3333333333333330372738601*var_38 + 0.6666666666666666296592325*var_43 + 2.0000000000000000000000000*var_11*var_48 + var_58; + A[17] = 0.4000000000000000222044605*var_32*var_59/(var_33*var_33*var_33); + A[61] = A[17]; + A[97] = 0.0000000000000000000000000; + const double var_60 = var_11*var_16; + const double var_61 = var_5*w[0][6]; + const double var_62 = -var_1*w[0][0] + var_61; + const double var_63 = var_11*var_62; + const double var_64 = var_4*var_5*var_5*w[0][0] + -var_1*var_1*var_3*w[0][6] + var_63; + const double var_65 = var_5 + -var_3; + const double var_66 = -var_1 + var_4; + const double var_67 = var_1*var_4*var_66*w[0][3] + var_3*var_5*var_65*w[0][9]; + const double var_68 = var_1*var_4*var_65*w[0][9] + var_3*var_5*var_66*w[0][3]; + const double var_69 = var_3*w[0][5]; + const double var_70 = var_1*w[0][10]; + const double var_71 = var_69 + var_70; + const double var_72 = var_5*w[0][4]; + const double var_73 = var_4*w[0][11]; + const double var_74 = var_72 + var_73; + const double var_75 = -var_4*var_4*var_5*w[0][9] + var_1*var_3*var_3*w[0][3]; + const double var_76 = var_1*var_1*var_3*w[0][9] + -var_4*var_5*var_5*w[0][3]; + const double var_77 = var_75 + var_76; + const double var_78 = var_4*var_5*var_5*w[0][5] + -var_1*var_1*var_3*w[0][11]; + const double var_79 = -var_1*var_3*var_3*w[0][4] + var_4*var_4*var_5*w[0][10]; + const double var_80 = var_78 + var_77 + var_79; + const double var_81 = var_11*var_53; + const double var_82 = var_4*var_4 + var_3*var_3; + const double var_83 = var_16*var_82; + const double var_84 = var_83 + var_81 + var_80; + const double var_85 = var_1*var_3*var_74 + var_68 + 0.3333333333333333148296163*var_84 + -var_4*var_5*var_71 + 1.3333333333333332593184650*var_67; + const double var_86 = var_1*var_4*var_7*w[0][0] + var_3*var_5*var_8*w[0][6]; + const double var_87 = -var_1*w[0][10] + var_72; + const double var_88 = var_3*var_4*var_87; + const double var_89 = -var_3*w[0][5] + var_73; + const double var_90 = var_1*var_5*var_89; + const double var_91 = var_88 + var_90; + const double var_92 = -var_1*var_3*var_3*w[0][5] + var_4*var_4*var_5*w[0][11]; + const double var_93 = var_92 + var_57; + const double var_94 = var_1*var_1*var_4*w[0][4] + -var_3*var_5*var_5*w[0][10]; + const double var_95 = var_3*var_3*var_5*w[0][11] + -var_1*var_4*var_4*w[0][5]; + const double var_96 = var_94 + var_95; + const double var_97 = -var_3*w[0][10] + var_4*w[0][4]; + const double var_98 = var_82*var_97; + const double var_99 = -var_1*w[0][5] + var_5*w[0][11]; + const double var_100 = var_11*var_99; + const double var_101 = var_98 + var_100 + 2.0000000000000000000000000*var_96; + const double var_102 = 2.0000000000000000000000000*var_101; + const double var_103 = var_3*w[0][6]; + const double var_104 = -var_4*w[0][0] + var_103; + const double var_105 = var_104*var_82; + const double var_106 = var_1*var_3*var_3*w[0][0] + -var_4*var_4*var_5*w[0][6] + var_105; + const double var_107 = var_1*w[0][0]; + const double var_108 = -var_5*w[0][6] + var_107; + const double var_109 = var_108*var_11; + const double var_110 = -var_4*var_5*var_5*w[0][0] + var_1*var_1*var_3*w[0][6] + var_109; + const double var_111 = var_110 + var_106; + const double var_112 = var_102 + var_91 + var_93 + var_111; + const double var_113 = var_46 + var_12; + const double var_114 = var_113*var_15; + const double var_115 = 2.0000000000000000000000000*var_112 + var_114 + var_86; + const double var_116 = var_9 + 2.0000000000000000000000000*var_85 + 0.3333333333333333148296163*var_115; + A[53] = 0.8000000000000000444089210*var_116*var_32/(var_33*var_33*var_33); + A[142] = A[53]; + const double var_117 = var_53*var_82; + const double var_118 = -var_5*w[0][3] + var_1*w[0][9]; + const double var_119 = var_5*w[0][5] + -var_1*w[0][11]; + const double var_120 = var_119*var_3*var_4; + const double var_121 = var_118*var_3*var_4 + var_120; + const double var_122 = var_3*var_3*var_5*w[0][6] + -var_1*var_4*var_4*w[0][0]; + const double var_123 = var_3*w[0][10] + -var_4*w[0][4]; + const double var_124 = var_123*var_82; + const double var_125 = -var_1*var_4*var_4*w[0][3] + var_3*var_3*var_5*w[0][9]; + const double var_126 = 2.0000000000000000000000000*var_125; + const double var_127 = var_124 + var_126; + const double var_128 = 0.2666666666666666629659233*var_127; + const double var_129 = var_4*w[0][0]; + const double var_130 = -var_3*w[0][6] + var_129; + const double var_131 = var_130*var_82; + const double var_132 = -var_1*var_3*var_3*w[0][0] + var_4*var_4*var_5*w[0][6] + var_131; + const double var_133 = var_1*var_3*var_3*w[0][4] + -var_4*var_4*var_5*w[0][10]; + const double var_134 = var_4*var_4*var_5*w[0][9] + -var_1*var_3*var_3*w[0][3]; + const double var_135 = var_12*var_82; + const double var_136 = var_134 + var_133 + var_135; + const double var_137 = var_1*var_3*var_3*w[0][5] + -var_4*var_4*var_5*w[0][11]; + const double var_138 = var_136 + var_137 + var_132; + const double var_139 = var_37 + var_23 + var_25; + const double var_140 = var_1*var_1*var_3*w[0][10] + -var_4*var_5*var_5*w[0][4]; + const double var_141 = var_3*var_5*var_65*w[0][11] + var_140 + var_1*var_4*var_66*w[0][5] + var_26; + const double var_142 = var_64 + var_81; + const double var_143 = var_15*var_53; + const double var_144 = var_142 + var_143; + const double var_145 = -var_3*var_5*var_5*w[0][6] + var_1*var_1*var_4*w[0][0]; + const double var_146 = var_42 + var_145; + const double var_147 = 0.0666666666666666657414808*var_144 + 0.2666666666666666629659233*var_146 + 0.1333333333333333314829616*var_138 + 0.5333333333333333259318465*var_141 + var_10 + 1.3333333333333332593184650*var_43 + 0.3333333333333333148296163*var_122 + 0.8000000000000000444089210*var_139 + var_128 + 0.6666666666666666296592325*var_88 + 0.4000000000000000222044605*var_121 + 0.4666666666666666740681535*var_18; + A[40] = 4.0000000000000000000000000*var_147*var_32/(var_33*var_33*var_33); + A[129] = A[40]; + const double var_148 = var_3*var_5*var_5*w[0][9] + -var_1*var_1*var_4*w[0][3]; + const double var_149 = -var_1*w[0][4] + var_19; + const double var_150 = var_149 + -var_5*w[0][9] + var_21; + const double var_151 = var_11*var_150; + const double var_152 = var_72 + var_70; + const double var_153 = 2.0000000000000000000000000*var_76 + var_151 + var_152*var_30; + const double var_154 = var_148 + 0.3333333333333333148296163*var_153; + const double var_155 = -var_1*w[0][6] + var_5*w[0][0]; + const double var_156 = var_15*var_46; + const double var_157 = var_155*var_39 + var_156 + 0.3333333333333333148296163*var_18 + var_104*var_15 + var_81 + var_63; + const double var_158 = var_4*w[0][9] + -var_3*w[0][3]; + const double var_159 = 0.6666666666666666296592325*var_1*var_158*var_5; + const double var_160 = var_3*w[0][11]; + const double var_161 = var_160 + var_4*w[0][3] + -var_49 + -var_51; + const double var_162 = 2.0000000000000000000000000*var_161 + var_97; + const double var_163 = var_159 + 1.3333333333333332593184650*var_11*var_50 + var_145 + 2.0000000000000000000000000*var_154 + 0.5000000000000000000000000*var_157 + 0.6666666666666666296592325*var_15*var_162; + A[1] = 0.2000000000000000111022302*var_163*var_32/(var_33*var_33*var_33); + A[90] = A[1]; + A[96] = 0.0000000000000000000000000; + const double var_164 = var_46*var_82 + var_143; + const double var_165 = var_4*w[0][6] + -var_3*w[0][0]; + const double var_166 = var_12*var_15; + const double var_167 = 0.3333333333333333148296163*var_164 + var_108*var_15 + var_83 + var_166 + var_165*var_39 + var_131; + const double var_168 = var_3*var_5*var_66*w[0][0] + var_1*var_4*var_65*w[0][6]; + const double var_169 = -var_4*var_5*var_5*w[0][5] + var_1*var_1*var_3*w[0][11]; + const double var_170 = var_11*var_46; + const double var_171 = var_40 + var_169 + var_170; + const double var_172 = -var_4*w[0][11] + var_69; + const double var_173 = var_172 + var_158 + var_165; + const double var_174 = var_6 + var_38 + var_94 + var_151 + var_123*var_15 + var_60; + const double var_175 = 4.0000000000000000000000000*var_11*var_47; + const double var_176 = var_175 + var_39*var_87 + 2.0000000000000000000000000*var_174 + var_1*var_173*var_5 + var_64 + var_130*var_15 + var_166; + const double var_177 = var_171 + 0.3333333333333333148296163*var_176; + A[16] = 0.4000000000000000222044605*var_177*var_32/(var_33*var_33*var_33); + A[127] = A[16]; + const double var_178 = -var_5*w[0][4] + var_70; + const double var_179 = var_178*var_3*var_4; + const double var_180 = var_45 + var_179 + var_168 + var_132; + A[55] = 0.0000000000000000000000000; + const double var_181 = var_1*var_1*var_4*w[0][5] + -var_3*var_5*var_5*w[0][11]; + const double var_182 = 1.3333333333333332593184650*var_119*var_39 + 2.6666666666666665186369300*var_181 + 4.0000000000000000000000000*var_151 + 2.3333333333333330372738601*var_11*var_16 + 0.3333333333333333148296163*var_170; + const double var_183 = 0.6666666666666666296592325*var_3*var_5 + var_14; + A[111] = 0.0000000000000000000000000; + const double var_184 = var_3*var_3*var_5*w[0][10] + -var_1*var_4*var_4*w[0][4]; + const double var_185 = var_52*var_82; + const double var_186 = 4.0000000000000000000000000*var_185 + 2.6666666666666665186369300*var_184 + 2.3333333333333330372738601*var_53*var_82 + 1.3333333333333332593184650*var_35*var_39 + 0.3333333333333333148296163*var_135; + const double var_187 = var_3*var_5*var_65*w[0][6] + var_1*var_4*var_66*w[0][0]; + const double var_188 = var_89 + var_87; + const double var_189 = var_7*w[0][6] + var_8*w[0][0] + 8.0000000000000000000000000*var_188; + const double var_190 = var_105 + 16.0000000000000000000000000*var_96 + var_189*var_39 + 2.0000000000000000000000000*var_187 + 4.0000000000000000000000000*var_77 + var_109; + const double var_191 = 0.6666666666666666296592325*var_1*var_4 + var_13; + const double var_192 = var_183*var_66*w[0][3] + var_191*var_65*w[0][9]; + const double var_193 = var_182 + 0.3333333333333333148296163*var_190 + var_186 + var_114 + 4.0000000000000000000000000*var_192; + A[110] = 0.0000000000000000000000000; + const double var_194 = var_18 + var_106; + const double var_195 = -var_3*var_3*var_5*w[0][11] + var_1*var_4*var_4*w[0][5]; + const double var_196 = var_137 + var_1*var_4*var_66*w[0][4] + var_6 + var_126 + var_3*var_5*var_65*w[0][10]; + const double var_197 = var_161*var_82; + const double var_198 = var_38 + var_121 + var_197; + const double var_199 = var_171 + var_64 + var_140; + const double var_200 = var_175 + var_17; + const double var_201 = var_132 + var_83; + const double var_202 = var_201 + var_200; + const double var_203 = -var_4*w[0][10] + var_3*w[0][4]; + const double var_204 = var_134 + var_203*var_39; + const double var_205 = var_122 + var_204; + const double var_206 = 0.4666666666666666740681535*var_164 + 0.4000000000000000222044605*var_37 + 1.3333333333333332593184650*var_195 + 0.6666666666666666296592325*var_90 + 0.0666666666666666657414808*var_202 + 0.3333333333333333148296163*var_145 + 0.8000000000000000444089210*var_198 + 0.1333333333333333314829616*var_199 + var_10 + 0.5333333333333333259318465*var_196 + 0.2666666666666666629659233*var_205; + A[41] = 4.0000000000000000000000000*var_206*var_32/(var_33*var_33*var_33); + A[119] = A[41]; + const double var_207 = 4.0000000000000000000000000*var_161 + var_53; + const double var_208 = 0.3333333333333333148296163*var_207*var_82; + A[75] = 0.0000000000000000000000000; + const double var_209 = var_5*w[0][3] + -var_1*w[0][9]; + const double var_210 = var_209 + var_178 + var_155; + const double var_211 = var_185 + var_95 + var_25 + var_15*var_47 + var_117 + var_125; + const double var_212 = var_210*var_3*var_4 + 4.0000000000000000000000000*var_123*var_82 + var_39*var_89 + var_15*var_62 + 2.0000000000000000000000000*var_211 + var_132 + var_156; + const double var_213 = var_136 + 0.3333333333333333148296163*var_212; + A[29] = 0.4000000000000000222044605*var_213*var_32/(var_33*var_33*var_33); + A[107] = A[29]; + A[51] = A[40]; + const double var_214 = var_74 + var_71; + const double var_215 = var_124 + var_214*var_30 + 2.0000000000000000000000000*var_91 + var_68; + const double var_216 = var_114 + var_85 + var_111; + const double var_217 = var_1*var_172*var_5; + const double var_218 = var_217 + var_179 + var_187; + const double var_219 = var_185 + var_151; + const double var_220 = var_60 + var_102 + var_219 + var_117; + const double var_221 = var_181 + var_184; + const double var_222 = 0.1333333333333333314829616*var_220 + 0.4000000000000000222044605*var_168 + 0.6666666666666666296592325*var_221 + 0.2000000000000000111022302*var_216 + 0.6000000000000000888178420*var_218 + 0.3333333333333333148296163*var_93; + A[3] = 2.0000000000000000000000000*var_222*var_32/(var_33*var_33*var_33); + A[133] = 0.0000000000000000000000000; + const double var_223 = var_1*var_4*var_4*w[0][3] + -var_3*var_3*var_5*w[0][9]; + const double var_224 = var_73 + var_69; + const double var_225 = var_185 + 2.0000000000000000000000000*var_75 + var_224*var_30; + const double var_226 = var_223 + 0.3333333333333333148296163*var_225; + const double var_227 = var_3*var_5*var_5*w[0][6] + -var_1*var_1*var_4*w[0][0]; + const double var_228 = var_1*var_4*var_4*w[0][0] + -var_3*var_3*var_5*w[0][6]; + const double var_229 = var_159 + var_191*var_8*w[0][10] + 0.3333333333333333148296163*var_79 + var_183*var_7*w[0][4] + var_58; + const double var_230 = 0.3333333333333333148296163*var_168; + const double var_231 = var_182 + var_201; + const double var_232 = var_164 + var_110; + const double var_233 = var_4*var_5*var_8*w[0][3] + var_1*var_3*var_7*w[0][9]; + const double var_234 = 0.0666666666666666657414808*var_232 + 0.2666666666666666629659233*var_233 + 0.4000000000000000222044605*var_227 + 1.3333333333333332593184650*var_148 + 0.7333333333333332815229255*var_12*var_15 + 1.6000000000000000888178420*var_229 + 0.8000000000000000444089210*var_226 + var_230 + 0.1333333333333333314829616*var_228 + 0.2000000000000000111022302*var_231; + const double var_235 = var_217 + var_64 + var_168 + var_208; + const double var_236 = var_171 + var_179 + var_175; + const double var_237 = var_37 + var_92; + const double var_238 = var_140 + var_158*var_39 + var_133 + 0.2000000000000000111022302*var_236 + var_120 + 1.4000000000000001332267630*var_237 + 0.4000000000000000222044605*var_28 + var_126; + const double var_239 = var_98 + var_106; + const double var_240 = 0.2000000000000000111022302*var_235 + 0.6000000000000000888178420*var_228 + 0.3333333333333333148296163*var_238 + 0.8000000000000000444089210*var_43 + 0.4000000000000000222044605*var_239; + const double var_241 = var_164 + var_197; + const double var_242 = var_3*var_5*var_8*w[0][10] + var_241 + var_1*var_4*var_7*w[0][4]; + const double var_243 = var_217 + var_136; + const double var_244 = var_121 + var_57; + const double var_245 = 0.4000000000000000222044605*var_242 + var_169 + 0.8000000000000000444089210*var_38 + var_137 + var_209*var_39 + 1.4000000000000001332267630*var_244 + var_36 + 0.2000000000000000111022302*var_243 + var_26; + const double var_246 = var_100 + var_110; + const double var_247 = 0.3333333333333333148296163*var_245 + var_128 + 0.8000000000000000444089210*var_195 + 0.2000000000000000111022302*var_180 + 0.6000000000000000888178420*var_227 + 0.4000000000000000222044605*var_246; + A[5] = 2.0000000000000000000000000*var_247*var_32/(var_33*var_33*var_33); + A[83] = A[5]; + A[4] = 2.0000000000000000000000000*var_240*var_32/(var_33*var_33*var_33); + A[62] = A[29]; + A[30] = 0.0000000000000000000000000; + A[74] = 0.0000000000000000000000000; + A[11] = 0.0000000000000000000000000; + A[99] = 0.0000000000000000000000000; + A[71] = 0.0000000000000000000000000; + const double var_248 = var_67 + var_38 + var_25; + const double var_249 = 0.6666666666666666296592325*var_209*var_3*var_4; + const double var_250 = 0.3333333333333333148296163*var_92; + const double var_251 = var_183*var_7*w[0][5] + 0.3333333333333333148296163*var_78 + var_191*var_8*w[0][11] + var_249 + var_250; + const double var_252 = var_186 + var_142; + const double var_253 = var_4*var_5*var_7*w[0][9] + var_1*var_3*var_8*w[0][3]; + const double var_254 = 0.1333333333333333314829616*var_227 + 0.7333333333333332815229255*var_15*var_46 + 0.4000000000000000222044605*var_228 + 0.0666666666666666657414808*var_194 + var_230 + 1.3333333333333332593184650*var_223 + 0.8000000000000000444089210*var_154 + 1.6000000000000000888178420*var_251 + 0.2000000000000000111022302*var_252 + 0.2666666666666666629659233*var_253; + A[132] = 0.0000000000000000000000000; + A[67] = 0.0000000000000000000000000; + A[34] = 0.0000000000000000000000000; + const double var_255 = var_54 + var_46; + A[49] = A[16]; + const double var_256 = var_129 + var_160; + A[21] = 0.0000000000000000000000000; + A[77] = 0.0000000000000000000000000; + const double var_257 = 2.0000000000000000000000000*var_52 + 3.5000000000000000000000000*var_16 + 4.0000000000000000000000000*var_97 + 6.0000000000000000000000000*var_150 + 0.5000000000000000000000000*var_255; + A[26] = 0.2000000000000000111022302*var_257*var_32*var_82/(var_33*var_33*var_33); + A[104] = A[26]; + A[70] = 0.0000000000000000000000000; + A[109] = 0.0000000000000000000000000; + A[52] = 4.0000000000000000000000000*var_234*var_32/(var_33*var_33*var_33); + A[130] = A[52]; + A[8] = 0.0000000000000000000000000; + A[94] = A[16]; + A[35] = 0.0000000000000000000000000; + const double var_258 = var_16 + var_53; + const double var_259 = var_99 + var_97; + const double var_260 = var_150 + var_52; + const double var_261 = 0.6666666666666666296592325*var_259 + 0.5000000000000000000000000*var_258 + 0.1666666666666666574148081*var_54 + 1.3333333333333332593184650*var_260; + A[14] = 0.2000000000000000111022302*var_15*var_261*var_32/(var_33*var_33*var_33); + A[92] = A[14]; + const double var_262 = var_99 + 2.0000000000000000000000000*var_22; + const double var_263 = var_249 + 2.0000000000000000000000000*var_226 + 0.6666666666666666296592325*var_15*var_262 + 1.3333333333333332593184650*var_149*var_82 + var_122 + 0.5000000000000000000000000*var_167; + A[2] = 0.2000000000000000111022302*var_263*var_32/(var_33*var_33*var_33); + A[114] = A[3]; + A[60] = A[5]; + A[108] = 0.0000000000000000000000000; + A[139] = A[17]; + const double var_264 = var_82 + var_11; + const double var_265 = var_64 + var_132; + const double var_266 = var_219 + var_80; + const double var_267 = 3.5000000000000000000000000*var_265 + 2.0000000000000000000000000*var_266 + 10.5000000000000000000000000*var_86 + var_143 + var_200 + 4.0000000000000000000000000*var_215 + 6.0000000000000000000000000*var_248 + 7.0000000000000000000000000*var_9 + 0.5000000000000000000000000*var_113*var_264; + A[0] = 0.2000000000000000111022302*var_267*var_32/(var_33*var_33*var_33); + A[22] = 0.0000000000000000000000000; + const double var_268 = var_19 + var_107; + const double var_269 = 0.6666666666666666296592325*var_130 + 3.0000000000000000000000000*var_46 + 4.6666666666666660745477202*var_161; + const double var_270 = var_61 + var_20; + const double var_271 = var_140 + var_110; + const double var_272 = 0.6666666666666666296592325*var_24 + var_191*var_270 + -var_183*var_268 + var_118*var_39 + 4.6666666666666660745477202*var_181 + var_78 + var_15*var_269 + 2.0000000000000000000000000*var_148 + 1.3333333333333332593184650*var_11*var_99 + 3.6666666666666665186369300*var_1*var_172*var_5 + var_81 + 0.3333333333333333148296163*var_271; + A[15] = 0.4000000000000000222044605*var_272*var_32/(var_33*var_33*var_33); + A[37] = A[15]; + const double var_273 = var_123 + var_12; + const double var_274 = 3.0000000000000000000000000*var_16 + 4.6666666666666660745477202*var_150 + 0.6666666666666666296592325*var_255; + const double var_275 = var_15*var_274 + var_208 + var_250 + 2.0000000000000000000000000*var_273*var_82 + 3.6666666666666665186369300*var_204 + 7.3333333333333330372738601*var_25 + 4.6666666666666660745477202*var_125 + var_121 + 0.6666666666666666296592325*var_195; + A[28] = 0.4000000000000000222044605*var_275*var_32/(var_33*var_33*var_33); + A[65] = 4.0000000000000000000000000*var_254*var_32/(var_33*var_33*var_33); + A[143] = A[65]; + A[36] = A[3]; + A[32] = 0.0000000000000000000000000; + A[126] = A[4]; + A[112] = 0.0000000000000000000000000; + A[23] = 0.0000000000000000000000000; + A[24] = A[2]; + A[79] = A[1]; + A[18] = 0.0000000000000000000000000; + const double var_276 = var_137 + var_106; + A[66] = 0.0000000000000000000000000; + A[54] = 0.0000000000000000000000000; + A[124] = 0.0000000000000000000000000; + A[20] = 0.0000000000000000000000000; + A[80] = A[2]; + A[78] = A[0]; + A[134] = 0.0000000000000000000000000; + const double var_277 = 4.0000000000000000000000000*var_99 + 2.0000000000000000000000000*var_150 + 3.5000000000000000000000000*var_53 + 0.5000000000000000000000000*var_55 + 6.0000000000000000000000000*var_52; + A[13] = 0.2000000000000000111022302*var_11*var_277*var_32/(var_33*var_33*var_33); + A[91] = A[13]; + A[135] = 0.0000000000000000000000000; + A[88] = 0.0000000000000000000000000; + A[103] = A[14]; + const double var_278 = var_49 + var_103; + const double var_279 = 3.0000000000000000000000000*var_12 + 4.6666666666666660745477202*var_22 + 0.6666666666666666296592325*var_62; + const double var_280 = var_183*var_256 + 1.3333333333333332593184650*var_82*var_97 + 2.0000000000000000000000000*var_223 + 3.6666666666666665186369300*var_178*var_3*var_4 + -var_191*var_278 + var_83 + 0.6666666666666666296592325*var_241 + 4.6666666666666660745477202*var_184 + var_15*var_279 + var_79 + var_34*var_39 + 0.3333333333333333148296163*var_276; + A[27] = 0.4000000000000000222044605*var_280*var_32/(var_33*var_33*var_33); + A[116] = A[27]; + A[12] = A[1]; + A[44] = 0.0000000000000000000000000; + A[123] = 0.0000000000000000000000000; + A[43] = 0.0000000000000000000000000; + A[19] = 0.0000000000000000000000000; + A[31] = 0.0000000000000000000000000; + A[72] = 0.0000000000000000000000000; + A[141] = A[41]; + A[84] = 0.0000000000000000000000000; + A[57] = 0.0000000000000000000000000; + A[115] = A[15]; + A[93] = A[15]; + A[118] = A[40]; + A[87] = 0.0000000000000000000000000; + A[82] = A[4]; + A[69] = 0.0000000000000000000000000; + A[86] = 0.0000000000000000000000000; + A[25] = A[14]; + A[89] = 0.0000000000000000000000000; + A[95] = A[17]; + A[45] = 0.0000000000000000000000000; + A[59] = 0.0000000000000000000000000; + A[39] = 0.8000000000000000444089210*var_193*var_32/(var_33*var_33*var_33); + A[73] = 0.0000000000000000000000000; + A[42] = 0.0000000000000000000000000; + A[68] = 0.0000000000000000000000000; + A[98] = 0.0000000000000000000000000; + A[63] = A[41]; + A[85] = 0.0000000000000000000000000; + A[140] = A[29]; + A[121] = 0.0000000000000000000000000; + A[10] = 0.0000000000000000000000000; + A[117] = A[39]; + A[33] = 0.0000000000000000000000000; + A[113] = 0.0000000000000000000000000; + A[64] = A[53]; + A[137] = 0.0000000000000000000000000; + A[138] = A[5]; + A[102] = A[2]; + A[81] = A[3]; + A[58] = 0.0000000000000000000000000; + A[6] = 0.0000000000000000000000000; + A[50] = A[28]; + A[46] = 0.0000000000000000000000000; + A[120] = 0.0000000000000000000000000; + A[136] = 0.0000000000000000000000000; + A[48] = A[4]; + A[47] = 0.0000000000000000000000000; + A[76] = 0.0000000000000000000000000; + A[122] = 0.0000000000000000000000000; + A[101] = 0.0000000000000000000000000; + A[106] = A[28]; + A[38] = A[27]; + A[105] = A[27]; + A[125] = 0.0000000000000000000000000; + A[131] = A[53]; + A[128] = A[28]; + A[56] = 0.0000000000000000000000000; + A[9] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q2_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q2_quadrature.h new file mode 100644 index 0000000..432d246 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q2_quadrature.h @@ -0,0 +1,5541 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P2_Q2_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P2_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q2_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q2_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q2_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q2_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q2_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q2_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q2_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q2_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q2_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p2_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W6[6] = {0.0833333333333333, 0.0833333333333333, 0.0833333333333333, 0.0833333333333333, 0.0833333333333333, 0.0833333333333333}; + // Quadrature points on the UFC reference element: (0.659027622374092, 0.231933368553031), (0.659027622374092, 0.109039009072877), (0.231933368553031, 0.659027622374092), (0.231933368553031, 0.109039009072877), (0.109039009072877, 0.659027622374092), (0.109039009072877, 0.231933368553031) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[6][5] = \ + {{0.563843963708492, -0.0722665257878755, 2.63611048949637, -0.491577437920616, -2.63611048949637}, + {0.0722665257878762, -0.563843963708492, 2.63611048949637, 0.491577437920617, -2.63611048949637}, + {0.563843963708492, 1.63611048949637, 0.927733474212124, -2.19995445320486, -0.927733474212124}, + {-1.63611048949637, -0.563843963708492, 0.927733474212123, 2.19995445320486, -0.927733474212124}, + {0.0722665257878759, 1.63611048949637, 0.436156036291507, -1.70837701528424, -0.436156036291507}, + {-1.63611048949637, -0.0722665257878757, 0.436156036291508, 1.70837701528424, -0.436156036291507}}; + + // Array of non-zero columns + static const unsigned int nzc4[5] = {6, 8, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc1[5] = {0, 2, 3, 4, 5}; + + static const double FE0_C0_D10[6][5] = \ + {{0.563843963708492, 1.63611048949637, 0.927733474212124, -0.927733474212124, -2.19995445320486}, + {0.0722665257878758, 1.63611048949637, 0.436156036291507, -0.436156036291507, -1.70837701528424}, + {0.563843963708492, -0.0722665257878758, 2.63611048949637, -2.63611048949637, -0.491577437920616}, + {-1.63611048949637, -0.0722665257878757, 0.436156036291507, -0.436156036291507, 1.70837701528424}, + {0.0722665257878762, -0.563843963708492, 2.63611048949637, -2.63611048949637, 0.491577437920617}, + {-1.63611048949637, -0.563843963708492, 0.927733474212124, -0.927733474212124, 2.19995445320486}}; + + // Array of non-zero columns + static const unsigned int nzc5[5] = {6, 7, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc2[5] = {0, 1, 3, 4, 5}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 144; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 60. + double G[12]; + G[0] = K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 3984 + for (unsigned int ip = 0; ip < 6; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 40 + for (unsigned int r = 0; r < 5; r++) + { + F0 += FE0_C0_D10[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D10[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 24 + double I[3]; + // Number of operations: 8 + I[0] = W6[ip]*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 8 + I[1] = W6[ip]*(F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 8 + I[2] = W6[ip]*(F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 600 + for (unsigned int j = 0; j < 5; j++) + { + for (unsigned int k = 0; k < 5; k++) + { + // Number of operations to compute entry: 3 + A[nzc1[j]*12 + nzc1[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc1[j]*12 + nzc2[k]] += FE0_C0_D01[ip][j]*FE0_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*12 + nzc1[k]] += FE0_C0_D01[ip][k]*FE0_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*12 + nzc2[k]] += FE0_C0_D10[ip][j]*FE0_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc4[j]*12 + nzc4[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc4[j]*12 + nzc5[k]] += FE0_C0_D01[ip][j]*FE0_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*12 + nzc4[k]] += FE0_C0_D01[ip][k]*FE0_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*12 + nzc5[k]] += FE0_C0_D10[ip][j]*FE0_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p2_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q2_quadrature_finite_element_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q2_quadrature_finite_element_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q2_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q2_quadrature_dofmap_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q2_quadrature_dofmap_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q2_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q2_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q2_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q2_tensor.h new file mode 100644 index 0000000..9b63072 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q2_tensor.h @@ -0,0 +1,5654 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P2_Q2_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P2_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q2_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q2_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q2_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q2_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q2_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q2_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q2_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q2_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q2_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p2_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 240 + // Number of operations (multiply-add pairs) for tensor contraction: 1163 + // Total number of operations (multiply-add pairs): 1414 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0 = det*(w[0][3]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1 = det*(w[0][3]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0 = det*(w[0][4]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1 = det*(w[0][4]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0 = det*(w[0][5]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1 = det*(w[0][5]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0 = det*(w[0][6]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1 = det*(w[0][6]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0 = det*(w[0][7]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1 = det*(w[0][8]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0 = det*(w[0][9]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1 = det*(w[0][9]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0 = det*(w[0][10]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1 = det*(w[0][10]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0 = det*(w[0][11]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1 = det*(w[0][11]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0 = det*(w[0][3]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1 = det*(w[0][3]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0 = det*(w[0][4]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1 = det*(w[0][4]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0 = det*(w[0][5]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1 = det*(w[0][5]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0 = det*(w[0][6]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1 = det*(w[0][6]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0 = det*(w[0][7]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1 = det*(w[0][8]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0 = det*(w[0][9]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1 = det*(w[0][9]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0 = det*(w[0][10]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1 = det*(w[0][10]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0 = det*(w[0][11]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1 = det*(w[0][11]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0 = det*(w[0][3]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1 = det*(w[0][3]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0 = det*(w[0][4]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1 = det*(w[0][4]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0 = det*(w[0][5]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1 = det*(w[0][5]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0 = det*(w[0][6]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1 = det*(w[0][6]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0 = det*(w[0][7]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1 = det*(w[0][8]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0 = det*(w[0][9]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1 = det*(w[0][9]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0 = det*(w[0][10]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1 = det*(w[0][10]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0 = det*(w[0][11]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1 = det*(w[0][11]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0 = det*(w[0][3]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1 = det*(w[0][3]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0 = det*(w[0][4]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1 = det*(w[0][4]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0 = det*(w[0][5]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1 = det*(w[0][5]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0 = det*(w[0][6]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1 = det*(w[0][6]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0 = det*(w[0][7]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1 = det*(w[0][8]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0 = det*(w[0][9]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1 = det*(w[0][9]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0 = det*(w[0][10]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1 = det*(w[0][10]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0 = det*(w[0][11]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1 = det*(w[0][11]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[87] = 0.0; + A[7] = 0.0; + A[18] = 0.0; + A[10] = 0.0; + A[43] = 0.0; + A[29] = 0.133333333333332*G0_1_0_0_0_0 + 0.133333333333332*G0_1_0_0_0_1 + 0.133333333333332*G0_1_0_1_0_0 + 0.133333333333332*G0_1_0_3_0_1 - 0.133333333333332*G0_1_0_4_0_1 - 0.266666666666663*G0_1_0_5_0_0 - 0.133333333333332*G0_1_0_5_0_1 + 0.133333333333332*G0_1_0_6_1_0 + 0.133333333333332*G0_1_0_6_1_1 + 0.133333333333332*G0_1_0_7_1_0 + 0.133333333333332*G0_1_0_9_1_1 - 0.133333333333332*G0_1_0_10_1_1 - 0.266666666666663*G0_1_0_11_1_0 - 0.133333333333332*G0_1_0_11_1_1 - 0.133333333333334*G0_1_1_0_0_0 - 0.133333333333334*G0_1_1_0_0_1 + 0.266666666666665*G0_1_1_1_0_0 - 0.4*G0_1_1_2_0_1 - 0.4*G0_1_1_3_0_0 + 0.266666666666665*G0_1_1_3_0_1 + 0.4*G0_1_1_4_0_0 + 0.533333333333334*G0_1_1_4_0_1 - 0.133333333333332*G0_1_1_5_0_0 - 0.266666666666665*G0_1_1_5_0_1 - 0.133333333333334*G0_1_1_6_1_0 - 0.133333333333334*G0_1_1_6_1_1 + 0.266666666666665*G0_1_1_7_1_0 - 0.4*G0_1_1_8_1_1 - 0.4*G0_1_1_9_1_0 + 0.266666666666665*G0_1_1_9_1_1 + 0.4*G0_1_1_10_1_0 + 0.533333333333334*G0_1_1_10_1_1 - 0.133333333333332*G0_1_1_11_1_0 - 0.266666666666665*G0_1_1_11_1_1; + A[81] = A[29] + 0.4*G0_0_0_0_0_0 + 0.4*G0_0_0_0_0_1 + 0.133333333333334*G0_0_0_1_0_0 + 0.266666666666666*G0_0_0_2_0_1 + 0.266666666666666*G0_0_0_3_0_0 + 0.133333333333334*G0_0_0_3_0_1 - 0.266666666666666*G0_0_0_4_0_0 - 0.666666666666666*G0_0_0_4_0_1 - 0.533333333333333*G0_0_0_5_0_0 - 0.133333333333334*G0_0_0_5_0_1 + 0.4*G0_0_0_6_1_0 + 0.4*G0_0_0_6_1_1 + 0.133333333333334*G0_0_0_7_1_0 + 0.266666666666666*G0_0_0_8_1_1 + 0.266666666666666*G0_0_0_9_1_0 + 0.133333333333334*G0_0_0_9_1_1 - 0.266666666666666*G0_0_0_10_1_0 - 0.666666666666666*G0_0_0_10_1_1 - 0.533333333333333*G0_0_0_11_1_0 - 0.133333333333334*G0_0_0_11_1_1 + 0.4*G0_0_1_0_0_0 + 0.4*G0_0_1_0_0_1 + 0.266666666666666*G0_0_1_1_0_0 + 0.133333333333334*G0_0_1_2_0_1 + 0.133333333333334*G0_0_1_3_0_0 + 0.266666666666665*G0_0_1_3_0_1 - 0.133333333333334*G0_0_1_4_0_0 - 0.533333333333333*G0_0_1_4_0_1 - 0.666666666666665*G0_0_1_5_0_0 - 0.266666666666665*G0_0_1_5_0_1 + 0.4*G0_0_1_6_1_0 + 0.4*G0_0_1_6_1_1 + 0.266666666666666*G0_0_1_7_1_0 + 0.133333333333334*G0_0_1_8_1_1 + 0.133333333333334*G0_0_1_9_1_0 + 0.266666666666665*G0_0_1_9_1_1 - 0.133333333333334*G0_0_1_10_1_0 - 0.533333333333333*G0_0_1_10_1_1 - 0.666666666666665*G0_0_1_11_1_0 - 0.266666666666665*G0_0_1_11_1_1 + 0.266666666666668*G0_1_0_0_0_0 + 0.266666666666668*G0_1_0_0_0_1 + 0.266666666666666*G0_1_0_2_0_1 + 0.266666666666665*G0_1_0_3_0_0 - 0.266666666666665*G0_1_0_4_0_0 - 0.533333333333334*G0_1_0_4_0_1 - 0.26666666666667*G0_1_0_5_0_0 + 0.266666666666668*G0_1_0_6_1_0 + 0.266666666666668*G0_1_0_6_1_1 + 0.266666666666666*G0_1_0_8_1_1 + 0.266666666666665*G0_1_0_9_1_0 - 0.266666666666665*G0_1_0_10_1_0 - 0.533333333333334*G0_1_0_10_1_1 - 0.26666666666667*G0_1_0_11_1_0 + 0.533333333333334*G0_1_1_0_0_0 + 0.533333333333334*G0_1_1_0_0_1 + 0.533333333333333*G0_1_1_2_0_1 + 0.533333333333334*G0_1_1_3_0_0 - 0.533333333333334*G0_1_1_4_0_0 - 1.06666666666667*G0_1_1_4_0_1 - 0.533333333333334*G0_1_1_5_0_0 + 0.533333333333334*G0_1_1_6_1_0 + 0.533333333333334*G0_1_1_6_1_1 + 0.533333333333333*G0_1_1_8_1_1 + 0.533333333333334*G0_1_1_9_1_0 - 0.533333333333334*G0_1_1_10_1_0 - 1.06666666666667*G0_1_1_10_1_1 - 0.533333333333334*G0_1_1_11_1_0; + A[23] = 0.0; + A[101] = 0.0; + A[68] = 0.0; + A[108] = 0.0; + A[137] = 0.0; + A[127] = -0.133333333333334*G0_0_0_0_0_0 - 0.133333333333334*G0_0_0_0_0_1 - 0.4*G0_0_0_1_0_0 + 0.266666666666666*G0_0_0_2_0_1 + 0.266666666666666*G0_0_0_3_0_0 - 0.4*G0_0_0_3_0_1 - 0.266666666666666*G0_0_0_4_0_0 - 0.133333333333332*G0_0_0_4_0_1 + 0.533333333333333*G0_0_0_5_0_0 + 0.4*G0_0_0_5_0_1 - 0.133333333333334*G0_0_0_6_1_0 - 0.133333333333334*G0_0_0_6_1_1 - 0.4*G0_0_0_7_1_0 + 0.266666666666666*G0_0_0_8_1_1 + 0.266666666666666*G0_0_0_9_1_0 - 0.4*G0_0_0_9_1_1 - 0.266666666666666*G0_0_0_10_1_0 - 0.133333333333332*G0_0_0_10_1_1 + 0.533333333333333*G0_0_0_11_1_0 + 0.4*G0_0_0_11_1_1 + 0.133333333333332*G0_1_0_0_0_0 + 0.133333333333332*G0_1_0_0_0_1 + 0.133333333333332*G0_1_0_2_0_1 + 0.133333333333332*G0_1_0_3_0_0 - 0.133333333333332*G0_1_0_4_0_0 - 0.266666666666664*G0_1_0_4_0_1 - 0.133333333333332*G0_1_0_5_0_0 + 0.133333333333332*G0_1_0_6_1_0 + 0.133333333333332*G0_1_0_6_1_1 + 0.133333333333332*G0_1_0_8_1_1 + 0.133333333333332*G0_1_0_9_1_0 - 0.133333333333332*G0_1_0_10_1_0 - 0.266666666666664*G0_1_0_10_1_1 - 0.133333333333332*G0_1_0_11_1_0; + A[82] = -A[81] + 1.2*G0_0_1_0_0_0 + 1.2*G0_0_1_0_0_1 + 0.399999999999998*G0_0_1_1_0_0 + 0.133333333333334*G0_0_1_2_0_1 - 0.533333333333332*G0_0_1_3_0_0 - 0.266666666666668*G0_0_1_3_0_1 + 0.533333333333332*G0_0_1_4_0_0 - 1.33333333333333*G0_0_1_4_0_1 - 1.59999999999999*G0_0_1_5_0_0 + 0.266666666666668*G0_0_1_5_0_1 + 1.2*G0_0_1_6_1_0 + 1.2*G0_0_1_6_1_1 + 0.399999999999998*G0_0_1_7_1_0 + 0.133333333333334*G0_0_1_8_1_1 - 0.533333333333332*G0_0_1_9_1_0 - 0.266666666666668*G0_0_1_9_1_1 + 0.533333333333332*G0_0_1_10_1_0 - 1.33333333333333*G0_0_1_10_1_1 - 1.59999999999999*G0_0_1_11_1_0 + 0.266666666666668*G0_0_1_11_1_1 + 1.2*G0_1_1_0_0_0 + 1.2*G0_1_1_0_0_1 + 0.399999999999998*G0_1_1_1_0_0 + 0.133333333333334*G0_1_1_2_0_1 - 0.533333333333332*G0_1_1_3_0_0 - 0.266666666666668*G0_1_1_3_0_1 + 0.533333333333332*G0_1_1_4_0_0 - 1.33333333333333*G0_1_1_4_0_1 - 1.6*G0_1_1_5_0_0 + 0.266666666666668*G0_1_1_5_0_1 + 1.2*G0_1_1_6_1_0 + 1.2*G0_1_1_6_1_1 + 0.399999999999998*G0_1_1_7_1_0 + 0.133333333333334*G0_1_1_8_1_1 - 0.533333333333332*G0_1_1_9_1_0 - 0.266666666666668*G0_1_1_9_1_1 + 0.533333333333332*G0_1_1_10_1_0 - 1.33333333333333*G0_1_1_10_1_1 - 1.6*G0_1_1_11_1_0 + 0.266666666666668*G0_1_1_11_1_1; + A[4] = A[82]; + A[13] = 0.1*G0_0_0_0_0_0 + 0.1*G0_0_0_0_0_1 + 0.699999999999998*G0_0_0_1_0_0 - 0.1*G0_0_0_2_0_1 + 0.4*G0_0_0_3_0_0 + 1.2*G0_0_0_3_0_1 - 0.4*G0_0_0_4_0_0 - 0.799999999999997*G0_0_0_5_0_0 - 1.2*G0_0_0_5_0_1 + 0.1*G0_0_0_6_1_0 + 0.1*G0_0_0_6_1_1 + 0.699999999999998*G0_0_0_7_1_0 - 0.1*G0_0_0_8_1_1 + 0.4*G0_0_0_9_1_0 + 1.2*G0_0_0_9_1_1 - 0.4*G0_0_0_10_1_0 - 0.799999999999997*G0_0_0_11_1_0 - 1.2*G0_0_0_11_1_1; + A[58] = 0.0; + A[30] = 0.0; + A[98] = 0.0; + A[71] = 0.0; + A[111] = 0.0; + A[72] = 0.0; + A[132] = 0.0; + A[89] = 0.0; + A[37] = -A[127] + 0.399999999999998*G0_1_0_0_0_0 + 0.399999999999998*G0_1_0_0_0_1 + 1.2*G0_1_0_1_0_0 - 0.133333333333334*G0_1_0_2_0_1 + 0.533333333333331*G0_1_0_3_0_0 + 1.86666666666666*G0_1_0_3_0_1 - 0.533333333333331*G0_1_0_4_0_0 - 0.266666666666664*G0_1_0_4_0_1 - 1.59999999999999*G0_1_0_5_0_0 - 1.86666666666666*G0_1_0_5_0_1 + 0.399999999999998*G0_1_0_6_1_0 + 0.399999999999998*G0_1_0_6_1_1 + 1.2*G0_1_0_7_1_0 - 0.133333333333334*G0_1_0_8_1_1 + 0.533333333333331*G0_1_0_9_1_0 + 1.86666666666666*G0_1_0_9_1_1 - 0.533333333333331*G0_1_0_10_1_0 - 0.266666666666664*G0_1_0_10_1_1 - 1.59999999999999*G0_1_0_11_1_0 - 1.86666666666666*G0_1_0_11_1_1; + A[35] = 0.0; + A[92] = -0.0333333333333325*G0_0_1_0_0_0 - 0.0333333333333325*G0_0_1_0_0_1 - 0.1*G0_0_1_1_0_0 - 0.1*G0_0_1_2_0_1 - 0.266666666666666*G0_0_1_3_0_0 - 0.266666666666665*G0_0_1_3_0_1 + 0.266666666666666*G0_0_1_4_0_0 + 0.133333333333332*G0_0_1_4_0_1 + 0.133333333333332*G0_0_1_5_0_0 + 0.266666666666665*G0_0_1_5_0_1 - 0.0333333333333325*G0_0_1_6_1_0 - 0.0333333333333325*G0_0_1_6_1_1 - 0.1*G0_0_1_7_1_0 - 0.1*G0_0_1_8_1_1 - 0.266666666666666*G0_0_1_9_1_0 - 0.266666666666665*G0_0_1_9_1_1 + 0.266666666666666*G0_0_1_10_1_0 + 0.133333333333332*G0_0_1_10_1_1 + 0.133333333333332*G0_0_1_11_1_0 + 0.266666666666665*G0_0_1_11_1_1; + A[90] = -A[92] - 0.1*G0_0_0_0_0_0 - 0.1*G0_0_0_0_0_1 + 0.1*G0_0_0_1_0_0 - 0.0333333333333325*G0_0_0_2_0_1 + 0.133333333333334*G0_0_0_3_0_0 + 0.266666666666666*G0_0_0_3_0_1 - 0.133333333333334*G0_0_0_4_0_0 + 0.133333333333332*G0_0_0_4_0_1 - 0.266666666666666*G0_0_0_5_0_1 - 0.1*G0_0_0_6_1_0 - 0.1*G0_0_0_6_1_1 + 0.1*G0_0_0_7_1_0 - 0.0333333333333325*G0_0_0_8_1_1 + 0.133333333333334*G0_0_0_9_1_0 + 0.266666666666666*G0_0_0_9_1_1 - 0.133333333333334*G0_0_0_10_1_0 + 0.133333333333332*G0_0_0_10_1_1 - 0.266666666666666*G0_0_0_11_1_1 - 0.133333333333332*G0_0_1_0_0_0 - 0.133333333333332*G0_0_1_0_0_1 - 0.133333333333332*G0_0_1_2_0_1 - 0.133333333333332*G0_0_1_3_0_0 + 0.133333333333332*G0_0_1_4_0_0 + 0.266666666666664*G0_0_1_4_0_1 + 0.133333333333332*G0_0_1_5_0_0 - 0.133333333333332*G0_0_1_6_1_0 - 0.133333333333332*G0_0_1_6_1_1 - 0.133333333333332*G0_0_1_8_1_1 - 0.133333333333332*G0_0_1_9_1_0 + 0.133333333333332*G0_0_1_10_1_0 + 0.266666666666664*G0_0_1_10_1_1 + 0.133333333333332*G0_0_1_11_1_0; + A[47] = 0.0; + A[25] = -0.0333333333333325*G0_1_0_0_0_0 - 0.0333333333333325*G0_1_0_0_0_1 - 0.1*G0_1_0_1_0_0 - 0.1*G0_1_0_2_0_1 - 0.266666666666666*G0_1_0_3_0_0 - 0.266666666666665*G0_1_0_3_0_1 + 0.266666666666666*G0_1_0_4_0_0 + 0.133333333333332*G0_1_0_4_0_1 + 0.133333333333332*G0_1_0_5_0_0 + 0.266666666666666*G0_1_0_5_0_1 - 0.0333333333333325*G0_1_0_6_1_0 - 0.0333333333333325*G0_1_0_6_1_1 - 0.1*G0_1_0_7_1_0 - 0.1*G0_1_0_8_1_1 - 0.266666666666666*G0_1_0_9_1_0 - 0.266666666666665*G0_1_0_9_1_1 + 0.266666666666666*G0_1_0_10_1_0 + 0.133333333333332*G0_1_0_10_1_1 + 0.133333333333332*G0_1_0_11_1_0 + 0.266666666666666*G0_1_0_11_1_1; + A[79] = -A[25] - 0.1*G0_0_0_0_0_0 - 0.1*G0_0_0_0_0_1 + 0.1*G0_0_0_1_0_0 - 0.0333333333333325*G0_0_0_2_0_1 + 0.133333333333334*G0_0_0_3_0_0 + 0.266666666666666*G0_0_0_3_0_1 - 0.133333333333334*G0_0_0_4_0_0 + 0.133333333333332*G0_0_0_4_0_1 - 0.266666666666666*G0_0_0_5_0_1 - 0.1*G0_0_0_6_1_0 - 0.1*G0_0_0_6_1_1 + 0.1*G0_0_0_7_1_0 - 0.0333333333333325*G0_0_0_8_1_1 + 0.133333333333334*G0_0_0_9_1_0 + 0.266666666666666*G0_0_0_9_1_1 - 0.133333333333334*G0_0_0_10_1_0 + 0.133333333333332*G0_0_0_10_1_1 - 0.266666666666666*G0_0_0_11_1_1 - 0.133333333333332*G0_1_0_0_0_0 - 0.133333333333332*G0_1_0_0_0_1 - 0.133333333333332*G0_1_0_2_0_1 - 0.133333333333332*G0_1_0_3_0_0 + 0.133333333333332*G0_1_0_4_0_0 + 0.266666666666664*G0_1_0_4_0_1 + 0.133333333333332*G0_1_0_5_0_0 - 0.133333333333332*G0_1_0_6_1_0 - 0.133333333333332*G0_1_0_6_1_1 - 0.133333333333332*G0_1_0_8_1_1 - 0.133333333333332*G0_1_0_9_1_0 + 0.133333333333332*G0_1_0_10_1_0 + 0.266666666666664*G0_1_0_10_1_1 + 0.133333333333332*G0_1_0_11_1_0; + A[1] = A[79]; + A[105] = -A[29] + 0.399999999999998*G0_1_0_0_0_0 + 0.399999999999998*G0_1_0_0_0_1 - 0.133333333333334*G0_1_0_1_0_0 + 1.2*G0_1_0_2_0_1 + 1.86666666666666*G0_1_0_3_0_0 + 0.533333333333331*G0_1_0_3_0_1 - 1.86666666666666*G0_1_0_4_0_0 - 1.59999999999999*G0_1_0_4_0_1 - 0.266666666666663*G0_1_0_5_0_0 - 0.533333333333331*G0_1_0_5_0_1 + 0.399999999999998*G0_1_0_6_1_0 + 0.399999999999998*G0_1_0_6_1_1 - 0.133333333333334*G0_1_0_7_1_0 + 1.2*G0_1_0_8_1_1 + 1.86666666666666*G0_1_0_9_1_0 + 0.533333333333331*G0_1_0_9_1_1 - 1.86666666666666*G0_1_0_10_1_0 - 1.59999999999999*G0_1_0_10_1_1 - 0.266666666666663*G0_1_0_11_1_0 - 0.533333333333331*G0_1_0_11_1_1; + A[112] = 0.0; + A[61] = -A[37] + 0.133333333333334*G0_0_0_0_0_0 + 0.133333333333334*G0_0_0_0_0_1 - 0.399999999999998*G0_0_0_1_0_0 - 0.133333333333334*G0_0_0_2_0_1 - 0.8*G0_0_0_3_0_0 - 1.06666666666666*G0_0_0_3_0_1 + 0.8*G0_0_0_4_0_0 + 0.266666666666663*G0_0_0_5_0_0 + 1.06666666666666*G0_0_0_5_0_1 + 0.133333333333334*G0_0_0_6_1_0 + 0.133333333333334*G0_0_0_6_1_1 - 0.399999999999998*G0_0_0_7_1_0 - 0.133333333333334*G0_0_0_8_1_1 - 0.8*G0_0_0_9_1_0 - 1.06666666666666*G0_0_0_9_1_1 + 0.8*G0_0_0_10_1_0 + 0.266666666666663*G0_0_0_11_1_0 + 1.06666666666666*G0_0_0_11_1_1; + A[123] = 0.0; + A[86] = 0.0; + A[11] = 0.0; + A[42] = 0.0; + A[26] = 0.1*G0_1_1_0_0_0 + 0.1*G0_1_1_0_0_1 - 0.1*G0_1_1_1_0_0 + 0.699999999999998*G0_1_1_2_0_1 + 1.2*G0_1_1_3_0_0 + 0.4*G0_1_1_3_0_1 - 1.2*G0_1_1_4_0_0 - 0.799999999999998*G0_1_1_4_0_1 - 0.4*G0_1_1_5_0_1 + 0.1*G0_1_1_6_1_0 + 0.1*G0_1_1_6_1_1 - 0.1*G0_1_1_7_1_0 + 0.699999999999998*G0_1_1_8_1_1 + 1.2*G0_1_1_9_1_0 + 0.4*G0_1_1_9_1_1 - 1.2*G0_1_1_10_1_0 - 0.799999999999998*G0_1_1_10_1_1 - 0.4*G0_1_1_11_1_1; + A[22] = 0.0; + A[102] = -A[25] - 0.133333333333332*G0_1_0_0_0_0 - 0.133333333333332*G0_1_0_0_0_1 - 0.133333333333332*G0_1_0_1_0_0 - 0.133333333333332*G0_1_0_3_0_1 + 0.133333333333332*G0_1_0_4_0_1 + 0.266666666666663*G0_1_0_5_0_0 + 0.133333333333332*G0_1_0_5_0_1 - 0.133333333333332*G0_1_0_6_1_0 - 0.133333333333332*G0_1_0_6_1_1 - 0.133333333333332*G0_1_0_7_1_0 - 0.133333333333332*G0_1_0_9_1_1 + 0.133333333333332*G0_1_0_10_1_1 + 0.266666666666663*G0_1_0_11_1_0 + 0.133333333333332*G0_1_0_11_1_1 - 0.1*G0_1_1_0_0_0 - 0.1*G0_1_1_0_0_1 - 0.0333333333333325*G0_1_1_1_0_0 + 0.1*G0_1_1_2_0_1 + 0.266666666666666*G0_1_1_3_0_0 + 0.133333333333334*G0_1_1_3_0_1 - 0.266666666666666*G0_1_1_4_0_0 + 0.133333333333332*G0_1_1_5_0_0 - 0.133333333333334*G0_1_1_5_0_1 - 0.1*G0_1_1_6_1_0 - 0.1*G0_1_1_6_1_1 - 0.0333333333333325*G0_1_1_7_1_0 + 0.1*G0_1_1_8_1_1 + 0.266666666666666*G0_1_1_9_1_0 + 0.133333333333334*G0_1_1_9_1_1 - 0.266666666666666*G0_1_1_10_1_0 + 0.133333333333332*G0_1_1_11_1_0 - 0.133333333333334*G0_1_1_11_1_1; + A[49] = A[127]; + A[115] = A[37]; + A[76] = 0.0; + A[136] = 0.0; + A[124] = 0.0; + A[85] = 0.0; + A[83] = -A[81] + 1.2*G0_0_0_0_0_0 + 1.2*G0_0_0_0_0_1 + 0.133333333333334*G0_0_0_1_0_0 + 0.399999999999998*G0_0_0_2_0_1 - 0.266666666666668*G0_0_0_3_0_0 - 0.533333333333332*G0_0_0_3_0_1 + 0.266666666666668*G0_0_0_4_0_0 - 1.6*G0_0_0_4_0_1 - 1.33333333333333*G0_0_0_5_0_0 + 0.533333333333332*G0_0_0_5_0_1 + 1.2*G0_0_0_6_1_0 + 1.2*G0_0_0_6_1_1 + 0.133333333333334*G0_0_0_7_1_0 + 0.399999999999998*G0_0_0_8_1_1 - 0.266666666666668*G0_0_0_9_1_0 - 0.533333333333332*G0_0_0_9_1_1 + 0.266666666666668*G0_0_0_10_1_0 - 1.6*G0_0_0_10_1_1 - 1.33333333333333*G0_0_0_11_1_0 + 0.533333333333332*G0_0_0_11_1_1 + 1.2*G0_1_0_0_0_0 + 1.2*G0_1_0_0_0_1 + 0.133333333333334*G0_1_0_1_0_0 + 0.399999999999998*G0_1_0_2_0_1 - 0.266666666666668*G0_1_0_3_0_0 - 0.533333333333332*G0_1_0_3_0_1 + 0.266666666666668*G0_1_0_4_0_0 - 1.6*G0_1_0_4_0_1 - 1.33333333333333*G0_1_0_5_0_0 + 0.533333333333332*G0_1_0_5_0_1 + 1.2*G0_1_0_6_1_0 + 1.2*G0_1_0_6_1_1 + 0.133333333333334*G0_1_0_7_1_0 + 0.399999999999998*G0_1_0_8_1_1 - 0.266666666666668*G0_1_0_9_1_0 - 0.533333333333332*G0_1_0_9_1_1 + 0.266666666666668*G0_1_0_10_1_0 - 1.6*G0_1_0_10_1_1 - 1.33333333333333*G0_1_0_11_1_0 + 0.533333333333332*G0_1_0_11_1_1; + A[143] = -A[83] + 0.799999999999997*G0_0_0_1_0_0 - 0.133333333333332*G0_0_0_2_0_1 + 0.533333333333334*G0_0_0_3_0_0 + 1.46666666666666*G0_0_0_3_0_1 - 0.533333333333334*G0_0_0_4_0_0 + 0.133333333333332*G0_0_0_4_0_1 - 0.799999999999997*G0_0_0_5_0_0 - 1.46666666666666*G0_0_0_5_0_1 + 0.799999999999997*G0_0_0_7_1_0 - 0.133333333333332*G0_0_0_8_1_1 + 0.533333333333334*G0_0_0_9_1_0 + 1.46666666666666*G0_0_0_9_1_1 - 0.533333333333334*G0_0_0_10_1_0 + 0.133333333333332*G0_0_0_10_1_1 - 0.799999999999997*G0_0_0_11_1_0 - 1.46666666666666*G0_0_0_11_1_1 + 0.266666666666665*G0_0_1_0_0_0 + 0.266666666666666*G0_0_1_0_0_1 + 1.2*G0_0_1_1_0_0 - 0.266666666666666*G0_0_1_2_0_1 + 0.4*G0_0_1_3_0_0 + 1.86666666666666*G0_0_1_3_0_1 - 0.4*G0_0_1_4_0_0 - 1.46666666666666*G0_0_1_5_0_0 - 1.86666666666666*G0_0_1_5_0_1 + 0.266666666666665*G0_0_1_6_1_0 + 0.266666666666666*G0_0_1_6_1_1 + 1.2*G0_0_1_7_1_0 - 0.266666666666666*G0_0_1_8_1_1 + 0.4*G0_0_1_9_1_0 + 1.86666666666666*G0_0_1_9_1_1 - 0.4*G0_0_1_10_1_0 - 1.46666666666666*G0_0_1_11_1_0 - 1.86666666666666*G0_0_1_11_1_1 + 1.46666666666666*G0_1_0_0_0_0 + 1.46666666666666*G0_1_0_0_0_1 + 1.46666666666666*G0_1_0_1_0_0 + 1.46666666666666*G0_1_0_3_0_1 - 1.46666666666666*G0_1_0_4_0_1 - 2.93333333333333*G0_1_0_5_0_0 - 1.46666666666666*G0_1_0_5_0_1 + 1.46666666666666*G0_1_0_6_1_0 + 1.46666666666666*G0_1_0_6_1_1 + 1.46666666666666*G0_1_0_7_1_0 + 1.46666666666666*G0_1_0_9_1_1 - 1.46666666666666*G0_1_0_10_1_1 - 2.93333333333333*G0_1_0_11_1_0 - 1.46666666666666*G0_1_0_11_1_1 - 0.133333333333334*G0_1_1_0_0_0 - 0.133333333333334*G0_1_1_0_0_1 + 1.6*G0_1_1_1_0_0 - 0.4*G0_1_1_2_0_1 + 0.933333333333332*G0_1_1_3_0_0 + 2.93333333333333*G0_1_1_3_0_1 - 0.933333333333332*G0_1_1_4_0_0 + 0.533333333333334*G0_1_1_4_0_1 - 1.46666666666666*G0_1_1_5_0_0 - 2.93333333333333*G0_1_1_5_0_1 - 0.133333333333334*G0_1_1_6_1_0 - 0.133333333333334*G0_1_1_6_1_1 + 1.6*G0_1_1_7_1_0 - 0.4*G0_1_1_8_1_1 + 0.933333333333332*G0_1_1_9_1_0 + 2.93333333333333*G0_1_1_9_1_1 - 0.933333333333332*G0_1_1_10_1_0 + 0.533333333333334*G0_1_1_10_1_1 - 1.46666666666666*G0_1_1_11_1_0 - 2.93333333333333*G0_1_1_11_1_1; + A[65] = A[143]; + A[141] = -A[143] - 1.33333333333333*G0_0_0_0_0_0 - 1.33333333333333*G0_0_0_0_0_1 + 0.266666666666663*G0_0_0_1_0_0 - 0.266666666666663*G0_0_0_2_0_1 + 1.06666666666667*G0_0_0_3_0_0 + 1.59999999999999*G0_0_0_3_0_1 - 1.06666666666667*G0_0_0_4_0_0 + 1.6*G0_0_0_4_0_1 + 1.06666666666667*G0_0_0_5_0_0 - 1.6*G0_0_0_5_0_1 - 1.33333333333333*G0_0_0_6_1_0 - 1.33333333333333*G0_0_0_6_1_1 + 0.266666666666663*G0_0_0_7_1_0 - 0.266666666666663*G0_0_0_8_1_1 + 1.06666666666667*G0_0_0_9_1_0 + 1.59999999999999*G0_0_0_9_1_1 - 1.06666666666667*G0_0_0_10_1_0 + 1.6*G0_0_0_10_1_1 + 1.06666666666667*G0_0_0_11_1_0 - 1.6*G0_0_0_11_1_1 + 0.533333333333332*G0_1_0_0_0_0 + 0.533333333333332*G0_1_0_0_0_1 + 1.06666666666666*G0_1_0_1_0_0 - 0.533333333333332*G0_1_0_2_0_1 - 0.533333333333332*G0_1_0_3_0_0 + 1.06666666666666*G0_1_0_3_0_1 + 0.533333333333332*G0_1_0_4_0_0 - 1.6*G0_1_0_5_0_0 - 1.06666666666666*G0_1_0_5_0_1 + 0.533333333333332*G0_1_0_6_1_0 + 0.533333333333332*G0_1_0_6_1_1 + 1.06666666666666*G0_1_0_7_1_0 - 0.533333333333332*G0_1_0_8_1_1 - 0.533333333333332*G0_1_0_9_1_0 + 1.06666666666666*G0_1_0_9_1_1 + 0.533333333333332*G0_1_0_10_1_0 - 1.6*G0_1_0_11_1_0 - 1.06666666666666*G0_1_0_11_1_1; + A[117] = -A[141] - 0.266666666666668*G0_0_0_0_0_0 - 0.266666666666668*G0_0_0_0_0_1 - 0.8*G0_0_0_1_0_0 + 1.86666666666666*G0_0_0_2_0_1 + 3.19999999999999*G0_0_0_3_0_0 + 0.533333333333332*G0_0_0_3_0_1 - 3.19999999999999*G0_0_0_4_0_0 - 1.59999999999999*G0_0_0_4_0_1 + 1.06666666666667*G0_0_0_5_0_0 - 0.533333333333332*G0_0_0_5_0_1 - 0.266666666666668*G0_0_0_6_1_0 - 0.266666666666668*G0_0_0_6_1_1 - 0.8*G0_0_0_7_1_0 + 1.86666666666666*G0_0_0_8_1_1 + 3.19999999999999*G0_0_0_9_1_0 + 0.533333333333332*G0_0_0_9_1_1 - 3.19999999999999*G0_0_0_10_1_0 - 1.59999999999999*G0_0_0_10_1_1 + 1.06666666666667*G0_0_0_11_1_0 - 0.533333333333332*G0_0_0_11_1_1 - 0.533333333333332*G0_0_1_0_0_0 - 0.533333333333332*G0_0_1_0_0_1 - 1.06666666666666*G0_0_1_1_0_0 + 0.533333333333332*G0_0_1_2_0_1 + 0.533333333333332*G0_0_1_3_0_0 - 1.06666666666666*G0_0_1_3_0_1 - 0.533333333333332*G0_0_1_4_0_0 + 1.59999999999999*G0_0_1_5_0_0 + 1.06666666666666*G0_0_1_5_0_1 - 0.533333333333332*G0_0_1_6_1_0 - 0.533333333333332*G0_0_1_6_1_1 - 1.06666666666666*G0_0_1_7_1_0 + 0.533333333333332*G0_0_1_8_1_1 + 0.533333333333332*G0_0_1_9_1_0 - 1.06666666666666*G0_0_1_9_1_1 - 0.533333333333332*G0_0_1_10_1_0 + 1.59999999999999*G0_0_1_11_1_0 + 1.06666666666666*G0_0_1_11_1_1; + A[142] = -A[141] - 1.6*G0_0_1_0_0_0 - 1.6*G0_0_1_0_0_1 - 1.59999999999999*G0_0_1_1_0_0 - 1.59999999999999*G0_0_1_3_0_1 + 1.59999999999999*G0_0_1_4_0_1 + 3.19999999999999*G0_0_1_5_0_0 + 1.59999999999999*G0_0_1_5_0_1 - 1.6*G0_0_1_6_1_0 - 1.6*G0_0_1_6_1_1 - 1.59999999999999*G0_0_1_7_1_0 - 1.59999999999999*G0_0_1_9_1_1 + 1.59999999999999*G0_0_1_10_1_1 + 3.19999999999999*G0_0_1_11_1_0 + 1.59999999999999*G0_0_1_11_1_1 + 0.266666666666668*G0_1_1_0_0_0 + 0.266666666666668*G0_1_1_0_0_1 - 1.86666666666666*G0_1_1_1_0_0 + 0.799999999999999*G0_1_1_2_0_1 - 0.533333333333332*G0_1_1_3_0_0 - 3.19999999999999*G0_1_1_3_0_1 + 0.533333333333332*G0_1_1_4_0_0 - 1.06666666666667*G0_1_1_4_0_1 + 1.59999999999999*G0_1_1_5_0_0 + 3.19999999999999*G0_1_1_5_0_1 + 0.266666666666668*G0_1_1_6_1_0 + 0.266666666666668*G0_1_1_6_1_1 - 1.86666666666666*G0_1_1_7_1_0 + 0.799999999999999*G0_1_1_8_1_1 - 0.533333333333332*G0_1_1_9_1_0 - 3.19999999999999*G0_1_1_9_1_1 + 0.533333333333332*G0_1_1_10_1_0 - 1.06666666666667*G0_1_1_10_1_1 + 1.59999999999999*G0_1_1_11_1_0 + 3.19999999999999*G0_1_1_11_1_1; + A[64] = A[142]; + A[5] = A[83]; + A[12] = A[90]; + A[8] = 0.0; + A[59] = 0.0; + A[31] = 0.0; + A[99] = 0.0; + A[70] = 0.0; + A[54] = 0.0; + A[110] = 0.0; + A[73] = 0.0; + A[67] = 0.0; + A[135] = 0.0; + A[88] = 0.0; + A[2] = -A[92] - 0.133333333333332*G0_0_1_0_0_0 - 0.133333333333332*G0_0_1_0_0_1 - 0.133333333333332*G0_0_1_1_0_0 - 0.133333333333332*G0_0_1_3_0_1 + 0.133333333333332*G0_0_1_4_0_1 + 0.266666666666663*G0_0_1_5_0_0 + 0.133333333333332*G0_0_1_5_0_1 - 0.133333333333332*G0_0_1_6_1_0 - 0.133333333333332*G0_0_1_6_1_1 - 0.133333333333332*G0_0_1_7_1_0 - 0.133333333333332*G0_0_1_9_1_1 + 0.133333333333332*G0_0_1_10_1_1 + 0.266666666666663*G0_0_1_11_1_0 + 0.133333333333332*G0_0_1_11_1_1 - 0.1*G0_1_1_0_0_0 - 0.1*G0_1_1_0_0_1 - 0.0333333333333325*G0_1_1_1_0_0 + 0.1*G0_1_1_2_0_1 + 0.266666666666666*G0_1_1_3_0_0 + 0.133333333333334*G0_1_1_3_0_1 - 0.266666666666666*G0_1_1_4_0_0 + 0.133333333333332*G0_1_1_5_0_0 - 0.133333333333334*G0_1_1_5_0_1 - 0.1*G0_1_1_6_1_0 - 0.1*G0_1_1_6_1_1 - 0.0333333333333325*G0_1_1_7_1_0 + 0.1*G0_1_1_8_1_1 + 0.266666666666666*G0_1_1_9_1_0 + 0.133333333333334*G0_1_1_9_1_1 - 0.266666666666666*G0_1_1_10_1_0 + 0.133333333333332*G0_1_1_11_1_0 - 0.133333333333334*G0_1_1_11_1_1; + A[56] = 0.0; + A[36] = A[81] - 0.133333333333332*G0_0_1_1_0_0 + 0.133333333333332*G0_0_1_2_0_1 + 0.133333333333332*G0_0_1_3_0_0 - 0.133333333333332*G0_0_1_3_0_1 - 0.133333333333332*G0_0_1_4_0_0 - 0.133333333333332*G0_0_1_4_0_1 + 0.133333333333332*G0_0_1_5_0_0 + 0.133333333333332*G0_0_1_5_0_1 - 0.133333333333332*G0_0_1_7_1_0 + 0.133333333333332*G0_0_1_8_1_1 + 0.133333333333332*G0_0_1_9_1_0 - 0.133333333333332*G0_0_1_9_1_1 - 0.133333333333332*G0_0_1_10_1_0 - 0.133333333333332*G0_0_1_10_1_1 + 0.133333333333332*G0_0_1_11_1_0 + 0.133333333333332*G0_0_1_11_1_1 + 0.133333333333332*G0_1_0_1_0_0 - 0.133333333333332*G0_1_0_2_0_1 - 0.133333333333332*G0_1_0_3_0_0 + 0.133333333333332*G0_1_0_3_0_1 + 0.133333333333332*G0_1_0_4_0_0 + 0.133333333333332*G0_1_0_4_0_1 - 0.133333333333332*G0_1_0_5_0_0 - 0.133333333333332*G0_1_0_5_0_1 + 0.133333333333332*G0_1_0_7_1_0 - 0.133333333333332*G0_1_0_8_1_1 - 0.133333333333332*G0_1_0_9_1_0 + 0.133333333333332*G0_1_0_9_1_1 + 0.133333333333332*G0_1_0_10_1_0 + 0.133333333333332*G0_1_0_10_1_1 - 0.133333333333332*G0_1_0_11_1_0 - 0.133333333333332*G0_1_0_11_1_1; + A[48] = -A[36] + 1.2*G0_1_0_0_0_0 + 1.2*G0_1_0_0_0_1 + 0.399999999999998*G0_1_0_1_0_0 + 0.133333333333334*G0_1_0_2_0_1 - 0.533333333333332*G0_1_0_3_0_0 - 0.266666666666668*G0_1_0_3_0_1 + 0.533333333333332*G0_1_0_4_0_0 - 1.33333333333333*G0_1_0_4_0_1 - 1.59999999999999*G0_1_0_5_0_0 + 0.266666666666668*G0_1_0_5_0_1 + 1.2*G0_1_0_6_1_0 + 1.2*G0_1_0_6_1_1 + 0.399999999999998*G0_1_0_7_1_0 + 0.133333333333334*G0_1_0_8_1_1 - 0.533333333333332*G0_1_0_9_1_0 - 0.266666666666668*G0_1_0_9_1_1 + 0.533333333333332*G0_1_0_10_1_0 - 1.33333333333333*G0_1_0_10_1_1 - 1.59999999999999*G0_1_0_11_1_0 + 0.266666666666668*G0_1_0_11_1_1 + 1.2*G0_1_1_0_0_0 + 1.2*G0_1_1_0_0_1 + 0.399999999999998*G0_1_1_1_0_0 + 0.133333333333334*G0_1_1_2_0_1 - 0.533333333333332*G0_1_1_3_0_0 - 0.266666666666668*G0_1_1_3_0_1 + 0.533333333333332*G0_1_1_4_0_0 - 1.33333333333333*G0_1_1_4_0_1 - 1.6*G0_1_1_5_0_0 + 0.266666666666668*G0_1_1_5_0_1 + 1.2*G0_1_1_6_1_0 + 1.2*G0_1_1_6_1_1 + 0.399999999999998*G0_1_1_7_1_0 + 0.133333333333334*G0_1_1_8_1_1 - 0.533333333333332*G0_1_1_9_1_0 - 0.266666666666668*G0_1_1_9_1_1 + 0.533333333333332*G0_1_1_10_1_0 - 1.33333333333333*G0_1_1_10_1_1 - 1.6*G0_1_1_11_1_0 + 0.266666666666668*G0_1_1_11_1_1; + A[32] = 0.0; + A[96] = 0.0; + A[74] = 0.0; + A[46] = 0.0; + A[106] = -A[105] + 0.133333333333334*G0_1_1_0_0_0 + 0.133333333333334*G0_1_1_0_0_1 - 0.133333333333334*G0_1_1_1_0_0 - 0.399999999999998*G0_1_1_2_0_1 - 1.06666666666666*G0_1_1_3_0_0 - 0.799999999999998*G0_1_1_3_0_1 + 1.06666666666666*G0_1_1_4_0_0 + 0.266666666666664*G0_1_1_4_0_1 + 0.799999999999999*G0_1_1_5_0_1 + 0.133333333333334*G0_1_1_6_1_0 + 0.133333333333334*G0_1_1_6_1_1 - 0.133333333333334*G0_1_1_7_1_0 - 0.399999999999998*G0_1_1_8_1_1 - 1.06666666666666*G0_1_1_9_1_0 - 0.799999999999998*G0_1_1_9_1_1 + 1.06666666666666*G0_1_1_10_1_0 + 0.266666666666664*G0_1_1_10_1_1 + 0.799999999999999*G0_1_1_11_1_1; + A[60] = -A[36] + 1.2*G0_0_0_0_0_0 + 1.2*G0_0_0_0_0_1 + 0.133333333333334*G0_0_0_1_0_0 + 0.399999999999998*G0_0_0_2_0_1 - 0.266666666666668*G0_0_0_3_0_0 - 0.533333333333332*G0_0_0_3_0_1 + 0.266666666666668*G0_0_0_4_0_0 - 1.6*G0_0_0_4_0_1 - 1.33333333333333*G0_0_0_5_0_0 + 0.533333333333332*G0_0_0_5_0_1 + 1.2*G0_0_0_6_1_0 + 1.2*G0_0_0_6_1_1 + 0.133333333333334*G0_0_0_7_1_0 + 0.399999999999998*G0_0_0_8_1_1 - 0.266666666666668*G0_0_0_9_1_0 - 0.533333333333332*G0_0_0_9_1_1 + 0.266666666666668*G0_0_0_10_1_0 - 1.6*G0_0_0_10_1_1 - 1.33333333333333*G0_0_0_11_1_0 + 0.533333333333332*G0_0_0_11_1_1 + 1.2*G0_0_1_0_0_0 + 1.2*G0_0_1_0_0_1 + 0.133333333333334*G0_0_1_1_0_0 + 0.399999999999998*G0_0_1_2_0_1 - 0.266666666666668*G0_0_1_3_0_0 - 0.533333333333332*G0_0_1_3_0_1 + 0.266666666666668*G0_0_1_4_0_0 - 1.6*G0_0_1_4_0_1 - 1.33333333333333*G0_0_1_5_0_0 + 0.533333333333332*G0_0_1_5_0_1 + 1.2*G0_0_1_6_1_0 + 1.2*G0_0_1_6_1_1 + 0.133333333333334*G0_0_1_7_1_0 + 0.399999999999998*G0_0_1_8_1_1 - 0.266666666666668*G0_0_1_9_1_0 - 0.533333333333332*G0_0_1_9_1_1 + 0.266666666666668*G0_0_1_10_1_0 - 1.6*G0_0_1_10_1_1 - 1.33333333333333*G0_0_1_11_1_0 + 0.533333333333332*G0_0_1_11_1_1; + A[120] = 0.0; + A[16] = A[127] + 0.133333333333332*G0_0_1_0_0_0 + 0.133333333333332*G0_0_1_0_0_1 + 0.133333333333332*G0_0_1_2_0_1 + 0.133333333333332*G0_0_1_3_0_0 - 0.133333333333332*G0_0_1_4_0_0 - 0.266666666666664*G0_0_1_4_0_1 - 0.133333333333332*G0_0_1_5_0_0 + 0.133333333333332*G0_0_1_6_1_0 + 0.133333333333332*G0_0_1_6_1_1 + 0.133333333333332*G0_0_1_8_1_1 + 0.133333333333332*G0_0_1_9_1_0 - 0.133333333333332*G0_0_1_10_1_0 - 0.266666666666664*G0_0_1_10_1_1 - 0.133333333333332*G0_0_1_11_1_0 - 0.133333333333332*G0_1_0_0_0_0 - 0.133333333333332*G0_1_0_0_0_1 - 0.133333333333332*G0_1_0_2_0_1 - 0.133333333333332*G0_1_0_3_0_0 + 0.133333333333332*G0_1_0_4_0_0 + 0.266666666666664*G0_1_0_4_0_1 + 0.133333333333332*G0_1_0_5_0_0 - 0.133333333333332*G0_1_0_6_1_0 - 0.133333333333332*G0_1_0_6_1_1 - 0.133333333333332*G0_1_0_8_1_1 - 0.133333333333332*G0_1_0_9_1_0 + 0.133333333333332*G0_1_0_10_1_0 + 0.266666666666664*G0_1_0_10_1_1 + 0.133333333333332*G0_1_0_11_1_0; + A[15] = -A[16] + 0.399999999999998*G0_0_1_0_0_0 + 0.399999999999998*G0_0_1_0_0_1 + 1.2*G0_0_1_1_0_0 - 0.133333333333334*G0_0_1_2_0_1 + 0.533333333333331*G0_0_1_3_0_0 + 1.86666666666666*G0_0_1_3_0_1 - 0.533333333333331*G0_0_1_4_0_0 - 0.266666666666664*G0_0_1_4_0_1 - 1.59999999999999*G0_0_1_5_0_0 - 1.86666666666666*G0_0_1_5_0_1 + 0.399999999999998*G0_0_1_6_1_0 + 0.399999999999998*G0_0_1_6_1_1 + 1.2*G0_0_1_7_1_0 - 0.133333333333334*G0_0_1_8_1_1 + 0.533333333333331*G0_0_1_9_1_0 + 1.86666666666666*G0_0_1_9_1_1 - 0.533333333333331*G0_0_1_10_1_0 - 0.266666666666664*G0_0_1_10_1_1 - 1.59999999999999*G0_0_1_11_1_0 - 1.86666666666666*G0_0_1_11_1_1; + A[17] = -A[15] + 0.133333333333334*G0_0_0_0_0_0 + 0.133333333333334*G0_0_0_0_0_1 - 0.399999999999998*G0_0_0_1_0_0 - 0.133333333333334*G0_0_0_2_0_1 - 0.8*G0_0_0_3_0_0 - 1.06666666666666*G0_0_0_3_0_1 + 0.8*G0_0_0_4_0_0 + 0.266666666666663*G0_0_0_5_0_0 + 1.06666666666666*G0_0_0_5_0_1 + 0.133333333333334*G0_0_0_6_1_0 + 0.133333333333334*G0_0_0_6_1_1 - 0.399999999999998*G0_0_0_7_1_0 - 0.133333333333334*G0_0_0_8_1_1 - 0.8*G0_0_0_9_1_0 - 1.06666666666666*G0_0_0_9_1_1 + 0.8*G0_0_0_10_1_0 + 0.266666666666663*G0_0_0_11_1_0 + 1.06666666666666*G0_0_0_11_1_1; + A[95] = A[17]; + A[45] = 0.0; + A[27] = A[105]; + A[21] = 0.0; + A[103] = A[25]; + A[114] = A[36]; + A[77] = 0.0; + A[63] = A[141]; + A[139] = A[61]; + A[125] = 0.0; + A[84] = 0.0; + A[80] = A[2]; + A[140] = A[29] + 0.133333333333332*G0_0_1_0_0_0 + 0.133333333333332*G0_0_1_0_0_1 + 0.133333333333332*G0_0_1_1_0_0 + 0.133333333333332*G0_0_1_3_0_1 - 0.133333333333332*G0_0_1_4_0_1 - 0.266666666666663*G0_0_1_5_0_0 - 0.133333333333332*G0_0_1_5_0_1 + 0.133333333333332*G0_0_1_6_1_0 + 0.133333333333332*G0_0_1_6_1_1 + 0.133333333333332*G0_0_1_7_1_0 + 0.133333333333332*G0_0_1_9_1_1 - 0.133333333333332*G0_0_1_10_1_1 - 0.266666666666663*G0_0_1_11_1_0 - 0.133333333333332*G0_0_1_11_1_1 - 0.133333333333332*G0_1_0_0_0_0 - 0.133333333333332*G0_1_0_0_0_1 - 0.133333333333332*G0_1_0_1_0_0 - 0.133333333333332*G0_1_0_3_0_1 + 0.133333333333332*G0_1_0_4_0_1 + 0.266666666666663*G0_1_0_5_0_0 + 0.133333333333332*G0_1_0_5_0_1 - 0.133333333333332*G0_1_0_6_1_0 - 0.133333333333332*G0_1_0_6_1_1 - 0.133333333333332*G0_1_0_7_1_0 - 0.133333333333332*G0_1_0_9_1_1 + 0.133333333333332*G0_1_0_10_1_1 + 0.266666666666663*G0_1_0_11_1_0 + 0.133333333333332*G0_1_0_11_1_1; + A[38] = -A[140] + 0.399999999999998*G0_0_1_0_0_0 + 0.399999999999997*G0_0_1_0_0_1 - 0.133333333333334*G0_0_1_1_0_0 + 1.2*G0_0_1_2_0_1 + 1.86666666666666*G0_0_1_3_0_0 + 0.533333333333332*G0_0_1_3_0_1 - 1.86666666666666*G0_0_1_4_0_0 - 1.59999999999999*G0_0_1_4_0_1 - 0.266666666666663*G0_0_1_5_0_0 - 0.533333333333331*G0_0_1_5_0_1 + 0.399999999999998*G0_0_1_6_1_0 + 0.399999999999997*G0_0_1_6_1_1 - 0.133333333333334*G0_0_1_7_1_0 + 1.2*G0_0_1_8_1_1 + 1.86666666666666*G0_0_1_9_1_0 + 0.533333333333332*G0_0_1_9_1_1 - 1.86666666666666*G0_0_1_10_1_0 - 1.59999999999999*G0_0_1_10_1_1 - 0.266666666666663*G0_0_1_11_1_0 - 0.533333333333331*G0_0_1_11_1_1; + A[128] = -A[38] + 0.133333333333334*G0_1_1_0_0_0 + 0.133333333333334*G0_1_1_0_0_1 - 0.133333333333334*G0_1_1_1_0_0 - 0.399999999999998*G0_1_1_2_0_1 - 1.06666666666666*G0_1_1_3_0_0 - 0.799999999999998*G0_1_1_3_0_1 + 1.06666666666666*G0_1_1_4_0_0 + 0.266666666666664*G0_1_1_4_0_1 + 0.799999999999999*G0_1_1_5_0_1 + 0.133333333333334*G0_1_1_6_1_0 + 0.133333333333334*G0_1_1_6_1_1 - 0.133333333333334*G0_1_1_7_1_0 - 0.399999999999998*G0_1_1_8_1_1 - 1.06666666666666*G0_1_1_9_1_0 - 0.799999999999998*G0_1_1_9_1_1 + 1.06666666666666*G0_1_1_10_1_0 + 0.266666666666664*G0_1_1_10_1_1 + 0.799999999999999*G0_1_1_11_1_1; + A[116] = A[38]; + A[50] = A[128]; + A[6] = 0.0; + A[19] = 0.0; + A[9] = 0.0; + A[40] = -A[142] + 0.266666666666668*G0_0_0_0_0_0 + 0.266666666666668*G0_0_0_0_0_1 + 0.8*G0_0_0_1_0_0 - 1.86666666666666*G0_0_0_2_0_1 - 3.19999999999999*G0_0_0_3_0_0 - 0.533333333333332*G0_0_0_3_0_1 + 3.19999999999999*G0_0_0_4_0_0 + 1.59999999999999*G0_0_0_4_0_1 - 1.06666666666667*G0_0_0_5_0_0 + 0.533333333333332*G0_0_0_5_0_1 + 0.266666666666668*G0_0_0_6_1_0 + 0.266666666666668*G0_0_0_6_1_1 + 0.8*G0_0_0_7_1_0 - 1.86666666666666*G0_0_0_8_1_1 - 3.19999999999999*G0_0_0_9_1_0 - 0.533333333333332*G0_0_0_9_1_1 + 3.19999999999999*G0_0_0_10_1_0 + 1.59999999999999*G0_0_0_10_1_1 - 1.06666666666667*G0_0_0_11_1_0 + 0.533333333333332*G0_0_0_11_1_1 - 1.6*G0_0_1_0_0_0 - 1.6*G0_0_1_0_0_1 - 1.59999999999999*G0_0_1_2_0_1 - 1.59999999999999*G0_0_1_3_0_0 + 1.59999999999999*G0_0_1_4_0_0 + 3.19999999999999*G0_0_1_4_0_1 + 1.6*G0_0_1_5_0_0 - 1.6*G0_0_1_6_1_0 - 1.6*G0_0_1_6_1_1 - 1.59999999999999*G0_0_1_8_1_1 - 1.59999999999999*G0_0_1_9_1_0 + 1.59999999999999*G0_0_1_10_1_0 + 3.19999999999999*G0_0_1_10_1_1 + 1.6*G0_0_1_11_1_0; + A[129] = A[40] + 0.533333333333332*G0_0_1_0_0_0 + 0.533333333333332*G0_0_1_0_0_1 - 0.533333333333332*G0_0_1_1_0_0 + 1.06666666666666*G0_0_1_2_0_1 + 1.06666666666666*G0_0_1_3_0_0 - 0.533333333333331*G0_0_1_3_0_1 - 1.06666666666666*G0_0_1_4_0_0 - 1.59999999999999*G0_0_1_4_0_1 + 0.533333333333332*G0_0_1_5_0_1 + 0.533333333333332*G0_0_1_6_1_0 + 0.533333333333332*G0_0_1_6_1_1 - 0.533333333333332*G0_0_1_7_1_0 + 1.06666666666666*G0_0_1_8_1_1 + 1.06666666666666*G0_0_1_9_1_0 - 0.533333333333331*G0_0_1_9_1_1 - 1.06666666666666*G0_0_1_10_1_0 - 1.59999999999999*G0_0_1_10_1_1 + 0.533333333333332*G0_0_1_11_1_1 - 0.533333333333332*G0_1_0_0_0_0 - 0.533333333333332*G0_1_0_0_0_1 + 0.533333333333331*G0_1_0_1_0_0 - 1.06666666666666*G0_1_0_2_0_1 - 1.06666666666666*G0_1_0_3_0_0 + 0.533333333333331*G0_1_0_3_0_1 + 1.06666666666666*G0_1_0_4_0_0 + 1.59999999999999*G0_1_0_4_0_1 - 0.533333333333331*G0_1_0_5_0_1 - 0.533333333333332*G0_1_0_6_1_0 - 0.533333333333332*G0_1_0_6_1_1 + 0.533333333333331*G0_1_0_7_1_0 - 1.06666666666666*G0_1_0_8_1_1 - 1.06666666666666*G0_1_0_9_1_0 + 0.533333333333331*G0_1_0_9_1_1 + 1.06666666666666*G0_1_0_10_1_0 + 1.59999999999999*G0_1_0_10_1_1 - 0.533333333333331*G0_1_0_11_1_1; + A[53] = -A[129] + 0.266666666666668*G0_0_0_0_0_0 + 0.266666666666668*G0_0_0_0_0_1 + 0.8*G0_0_0_1_0_0 - 1.86666666666666*G0_0_0_2_0_1 - 3.19999999999999*G0_0_0_3_0_0 - 0.533333333333332*G0_0_0_3_0_1 + 3.19999999999999*G0_0_0_4_0_0 + 1.59999999999999*G0_0_0_4_0_1 - 1.06666666666667*G0_0_0_5_0_0 + 0.533333333333332*G0_0_0_5_0_1 + 0.266666666666668*G0_0_0_6_1_0 + 0.266666666666668*G0_0_0_6_1_1 + 0.8*G0_0_0_7_1_0 - 1.86666666666666*G0_0_0_8_1_1 - 3.19999999999999*G0_0_0_9_1_0 - 0.533333333333332*G0_0_0_9_1_1 + 3.19999999999999*G0_0_0_10_1_0 + 1.59999999999999*G0_0_0_10_1_1 - 1.06666666666667*G0_0_0_11_1_0 + 0.533333333333332*G0_0_0_11_1_1 - 1.6*G0_1_0_0_0_0 - 1.6*G0_1_0_0_0_1 - 1.59999999999999*G0_1_0_2_0_1 - 1.59999999999999*G0_1_0_3_0_0 + 1.59999999999999*G0_1_0_4_0_0 + 3.19999999999999*G0_1_0_4_0_1 + 1.6*G0_1_0_5_0_0 - 1.6*G0_1_0_6_1_0 - 1.6*G0_1_0_6_1_1 - 1.59999999999999*G0_1_0_8_1_1 - 1.59999999999999*G0_1_0_9_1_0 + 1.59999999999999*G0_1_0_10_1_0 + 3.19999999999999*G0_1_0_10_1_1 + 1.6*G0_1_0_11_1_0; + A[41] = -A[53] - 1.6*G0_1_0_0_0_0 - 1.6*G0_1_0_0_0_1 - 1.59999999999999*G0_1_0_1_0_0 - 1.59999999999999*G0_1_0_3_0_1 + 1.59999999999999*G0_1_0_4_0_1 + 3.19999999999999*G0_1_0_5_0_0 + 1.59999999999999*G0_1_0_5_0_1 - 1.6*G0_1_0_6_1_0 - 1.6*G0_1_0_6_1_1 - 1.59999999999999*G0_1_0_7_1_0 - 1.59999999999999*G0_1_0_9_1_1 + 1.59999999999999*G0_1_0_10_1_1 + 3.19999999999999*G0_1_0_11_1_0 + 1.59999999999999*G0_1_0_11_1_1 + 0.266666666666668*G0_1_1_0_0_0 + 0.266666666666668*G0_1_1_0_0_1 - 1.86666666666666*G0_1_1_1_0_0 + 0.799999999999999*G0_1_1_2_0_1 - 0.533333333333332*G0_1_1_3_0_0 - 3.19999999999999*G0_1_1_3_0_1 + 0.533333333333332*G0_1_1_4_0_0 - 1.06666666666667*G0_1_1_4_0_1 + 1.59999999999999*G0_1_1_5_0_0 + 3.19999999999999*G0_1_1_5_0_1 + 0.266666666666668*G0_1_1_6_1_0 + 0.266666666666668*G0_1_1_6_1_1 - 1.86666666666666*G0_1_1_7_1_0 + 0.799999999999999*G0_1_1_8_1_1 - 0.533333333333332*G0_1_1_9_1_0 - 3.19999999999999*G0_1_1_9_1_1 + 0.533333333333332*G0_1_1_10_1_0 - 1.06666666666667*G0_1_1_10_1_1 + 1.59999999999999*G0_1_1_11_1_0 + 3.19999999999999*G0_1_1_11_1_1; + A[130] = -A[40] + 0.533333333333332*G0_1_0_0_0_0 + 0.533333333333332*G0_1_0_0_0_1 - 0.533333333333331*G0_1_0_1_0_0 + 1.06666666666666*G0_1_0_2_0_1 + 1.06666666666666*G0_1_0_3_0_0 - 0.533333333333331*G0_1_0_3_0_1 - 1.06666666666666*G0_1_0_4_0_0 - 1.59999999999999*G0_1_0_4_0_1 + 0.533333333333331*G0_1_0_5_0_1 + 0.533333333333332*G0_1_0_6_1_0 + 0.533333333333332*G0_1_0_6_1_1 - 0.533333333333331*G0_1_0_7_1_0 + 1.06666666666666*G0_1_0_8_1_1 + 1.06666666666666*G0_1_0_9_1_0 - 0.533333333333331*G0_1_0_9_1_1 - 1.06666666666666*G0_1_0_10_1_0 - 1.59999999999999*G0_1_0_10_1_1 + 0.533333333333331*G0_1_0_11_1_1 - 1.33333333333333*G0_1_1_0_0_0 - 1.33333333333333*G0_1_1_0_0_1 - 0.266666666666664*G0_1_1_1_0_0 + 0.266666666666664*G0_1_1_2_0_1 + 1.59999999999999*G0_1_1_3_0_0 + 1.06666666666667*G0_1_1_3_0_1 - 1.59999999999999*G0_1_1_4_0_0 + 1.06666666666667*G0_1_1_4_0_1 + 1.59999999999999*G0_1_1_5_0_0 - 1.06666666666667*G0_1_1_5_0_1 - 1.33333333333333*G0_1_1_6_1_0 - 1.33333333333333*G0_1_1_6_1_1 - 0.266666666666664*G0_1_1_7_1_0 + 0.266666666666664*G0_1_1_8_1_1 + 1.59999999999999*G0_1_1_9_1_0 + 1.06666666666667*G0_1_1_9_1_1 - 1.59999999999999*G0_1_1_10_1_0 + 1.06666666666667*G0_1_1_10_1_1 + 1.59999999999999*G0_1_1_11_1_0 - 1.06666666666667*G0_1_1_11_1_1; + A[119] = A[41]; + A[28] = A[106]; + A[100] = 0.0; + A[69] = 0.0; + A[55] = 0.0; + A[131] = A[53]; + A[109] = 0.0; + A[78] = A[105] - 0.699999999999998*G0_0_0_0_0_0 - 0.699999999999998*G0_0_0_0_0_1 - 0.1*G0_0_0_1_0_0 - 0.1*G0_0_0_2_0_1 + 0.4*G0_0_0_3_0_0 + 0.4*G0_0_0_3_0_1 - 0.4*G0_0_0_4_0_0 + 0.799999999999998*G0_0_0_4_0_1 + 0.799999999999998*G0_0_0_5_0_0 - 0.4*G0_0_0_5_0_1 - 0.699999999999998*G0_0_0_6_1_0 - 0.699999999999998*G0_0_0_6_1_1 - 0.1*G0_0_0_7_1_0 - 0.1*G0_0_0_8_1_1 + 0.4*G0_0_0_9_1_0 + 0.4*G0_0_0_9_1_1 - 0.4*G0_0_0_10_1_0 + 0.799999999999998*G0_0_0_10_1_1 + 0.799999999999998*G0_0_0_11_1_0 - 0.4*G0_0_0_11_1_1 - 0.699999999999998*G0_0_1_0_0_0 - 0.699999999999998*G0_0_1_0_0_1 - 0.1*G0_0_1_1_0_0 - 0.1*G0_0_1_2_0_1 + 0.4*G0_0_1_3_0_0 + 0.4*G0_0_1_3_0_1 - 0.4*G0_0_1_4_0_0 + 0.799999999999998*G0_0_1_4_0_1 + 0.799999999999998*G0_0_1_5_0_0 - 0.4*G0_0_1_5_0_1 - 0.699999999999998*G0_0_1_6_1_0 - 0.699999999999998*G0_0_1_6_1_1 - 0.1*G0_0_1_7_1_0 - 0.1*G0_0_1_8_1_1 + 0.4*G0_0_1_9_1_0 + 0.4*G0_0_1_9_1_1 - 0.4*G0_0_1_10_1_0 + 0.799999999999998*G0_0_1_10_1_1 + 0.799999999999998*G0_0_1_11_1_0 - 0.4*G0_0_1_11_1_1 - 0.966666666666664*G0_1_0_0_0_0 - 0.966666666666664*G0_1_0_0_0_1 + 0.166666666666666*G0_1_0_1_0_0 - 1.3*G0_1_0_2_0_1 - 1.46666666666666*G0_1_0_3_0_0 + 1.46666666666666*G0_1_0_4_0_0 + 2.26666666666666*G0_1_0_4_0_1 + 0.799999999999998*G0_1_0_5_0_0 - 0.966666666666664*G0_1_0_6_1_0 - 0.966666666666664*G0_1_0_6_1_1 + 0.166666666666666*G0_1_0_7_1_0 - 1.3*G0_1_0_8_1_1 - 1.46666666666666*G0_1_0_9_1_0 + 1.46666666666666*G0_1_0_10_1_0 + 2.26666666666666*G0_1_0_10_1_1 + 0.799999999999998*G0_1_0_11_1_0 - 0.833333333333332*G0_1_1_0_0_0 - 0.833333333333332*G0_1_1_0_0_1 + 0.166666666666666*G0_1_1_1_0_0 - 0.499999999999999*G0_1_1_2_0_1 + 0.666666666666665*G0_1_1_3_0_1 + 1.33333333333333*G0_1_1_4_0_1 + 0.666666666666666*G0_1_1_5_0_0 - 0.666666666666665*G0_1_1_5_0_1 - 0.833333333333332*G0_1_1_6_1_0 - 0.833333333333332*G0_1_1_6_1_1 + 0.166666666666666*G0_1_1_7_1_0 - 0.499999999999999*G0_1_1_8_1_1 + 0.666666666666665*G0_1_1_9_1_1 + 1.33333333333333*G0_1_1_10_1_1 + 0.666666666666666*G0_1_1_11_1_0 - 0.666666666666665*G0_1_1_11_1_1; + A[66] = 0.0; + A[134] = 0.0; + A[126] = A[48]; + A[91] = A[13]; + A[3] = A[81]; + A[14] = A[92]; + A[57] = 0.0; + A[39] = A[117]; + A[33] = 0.0; + A[97] = 0.0; + A[52] = A[130]; + A[75] = 0.0; + A[133] = 0.0; + A[94] = A[16]; + A[0] = A[78]; + A[107] = A[29]; + A[34] = 0.0; + A[118] = A[40]; + A[121] = 0.0; + A[93] = A[15]; + A[44] = 0.0; + A[24] = A[102]; + A[20] = 0.0; + A[104] = A[26]; + A[51] = A[129]; + A[113] = 0.0; + A[62] = A[140]; + A[138] = A[60]; + A[122] = 0.0; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p2_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q2_tensor_finite_element_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q2_tensor_finite_element_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q2_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q2_tensor_dofmap_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q2_tensor_dofmap_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q2_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q2_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q3_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q3_excafe.h new file mode 100644 index 0000000..7b91a95 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q3_excafe.h @@ -0,0 +1,874 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 5 minutes and 47.20 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][0]; + const double var_1 = x[1][0] + var_0; + const double var_2 = -x[0][1]; + const double var_3 = x[1][1] + var_2; + const double var_4 = var_1*var_1 + var_3*var_3; + const double var_5 = var_3*w[0][4] + -var_1*w[0][10]; + const double var_6 = var_4*var_5; + const double var_7 = x[2][1] + var_2; + const double var_8 = x[2][0] + var_0; + const double var_9 = var_3*var_3*var_7*w[0][3] + -var_1*var_1*var_8*w[0][9]; + const double var_10 = var_8*w[0][3] + -var_7*w[0][9]; + const double var_11 = var_7*w[0][11] + -var_8*w[0][5]; + const double var_12 = var_10 + var_11; + const double var_13 = var_1*var_12*var_3; + const double var_14 = 0.6000000000000000888178420*var_13 + var_9; + const double var_15 = var_14 + var_6; + const double var_16 = var_1*w[0][5] + -var_3*w[0][11]; + const double var_17 = var_3*w[0][0] + -var_1*w[0][6]; + const double var_18 = var_3*var_3*var_8*w[0][6] + var_17*var_4 + -var_1*var_1*var_7*w[0][0]; + const double var_19 = var_1*w[0][8] + -var_3*w[0][2]; + const double var_20 = var_8*var_8 + var_7*var_7; + const double var_21 = var_7*w[0][0] + -var_8*w[0][6]; + const double var_22 = var_1*var_7*var_7*w[0][6] + -var_3*var_8*var_8*w[0][0] + var_20*var_21; + const double var_23 = var_1*var_8*var_8*w[0][9] + -var_3*var_7*var_7*w[0][3]; + const double var_24 = -w[0][4] + w[0][3]; + const double var_25 = -w[0][9] + w[0][10]; + const double var_26 = var_1*var_1*var_24*var_7 + var_25*var_3*var_3*var_8; + const double var_27 = w[0][5] + -w[0][3]; + const double var_28 = w[0][9] + -w[0][11]; + const double var_29 = var_27*var_3*var_8*var_8 + var_1*var_28*var_7*var_7; + const double var_30 = -var_1*var_8*var_8*w[0][10] + var_3*var_7*var_7*w[0][4]; + const double var_31 = -var_1*var_7*var_7*w[0][10] + var_3*var_8*var_8*w[0][4]; + const double var_32 = var_3*var_7*var_7*w[0][0] + -var_1*var_8*var_8*w[0][6]; + const double var_33 = -var_3*var_3*var_7*w[0][4] + var_1*var_1*var_8*w[0][10]; + const double var_34 = var_1*var_1*var_8*w[0][6] + -var_3*var_3*var_7*w[0][0]; + const double var_35 = -var_3*var_3*var_8*w[0][11] + var_1*var_1*var_7*w[0][5]; + const double var_36 = -var_1*w[0][5] + var_3*w[0][11]; + const double var_37 = var_7*w[0][10] + -var_8*w[0][4]; + const double var_38 = var_1*var_3*var_37; + const double var_39 = var_3*w[0][9] + -var_1*w[0][3]; + const double var_40 = -var_3*w[0][10] + var_1*w[0][4] + var_39; + const double var_41 = var_40*var_7*var_8; + const double var_42 = var_3*var_7 + var_1*var_8; + const double var_43 = -var_1*w[0][8] + var_3*w[0][2]; + const double var_44 = var_42*var_43; + const double var_45 = -var_8*w[0][7] + var_7*w[0][1]; + const double var_46 = var_42*var_45; + const double var_47 = var_20*var_45; + const double var_48 = var_24*var_7 + var_25*var_8; + const double var_49 = var_20*var_48; + const double var_50 = 0.4625000000000000222044605*var_19*var_20 + 0.5500000000000000444089210*var_49; + const double var_51 = 1.1500000000000001332267630*var_1*var_12*var_3; + const double var_52 = var_3*w[0][6]; + const double var_53 = var_8*w[0][0]; + const double var_54 = var_52 + var_53; + const double var_55 = var_7*w[0][6]; + const double var_56 = var_1*w[0][0]; + const double var_57 = var_55 + var_56; + const double var_58 = var_1*var_54*var_7 + -var_3*var_57*var_8; + const double var_59 = 0.0678571428571428519882502*var_58; + const double var_60 = var_8*w[0][11] + -var_7*w[0][5]; + const double var_61 = var_20*var_60; + const double var_62 = var_8*w[0][7] + -var_7*w[0][1]; + const double var_63 = var_27*var_3 + var_1*var_28; + const double var_64 = var_4*var_63; + const double var_65 = 0.7500000000000000000000000*var_4*var_62 + var_64; + const double var_66 = var_61 + var_65; + const double var_67 = var_1*w[0][10] + -var_3*w[0][4]; + const double var_68 = var_4*var_67; + const double var_69 = -var_3*var_7*var_7*w[0][5] + var_1*var_8*var_8*w[0][11]; + const double var_70 = -var_1*var_1*var_8*w[0][11] + var_3*var_3*var_7*w[0][5]; + const double var_71 = var_70 + var_69; + const double var_72 = var_68 + var_71; + const double var_73 = 0.1250000000000000000000000*var_31 + 0.0714285714285714246063463*var_51 + 0.0053571428571428571924207*var_47 + 0.0589285714285714273819039*var_22 + 0.1750000000000000166533454*var_35 + 0.1464285714285714357085766*var_26 + 0.0178571428571428561515866*var_29 + 0.0428571428571428575393654*var_46 + 0.2428571428571428547638078*var_23 + 0.2285714285714285642914234*var_9 + 0.0321428571428571396850771*var_38 + 0.1428571428571428492126927*var_50 + 0.1267857142857142793701541*var_18 + 0.0642857142857142793701541*var_66 + 0.1946428571428571452361922*var_34 + 0.1000000000000000055511151*var_44 + 0.1785714285714285753936537*var_33 + 0.0339285714285714259941251*var_19*var_4 + 0.1107142857142857095276156*var_36*var_7*var_8 + 0.2250000000000000055511151*var_41 + 0.0089285714285714280757933*var_32 + 0.0928571428571428603149229*var_72 + 0.3500000000000000333066907*var_30 + var_59; + const double var_74 = var_1*var_7 + -var_3*var_8; + const double var_75 = var_74; + const double var_76 = std::abs(var_75); + const double var_77 = var_74; + const double var_78 = -var_1*var_7*var_7*w[0][9] + var_3*var_8*var_8*w[0][3]; + const double var_79 = -var_3*var_8*var_8*w[0][5] + var_1*var_7*var_7*w[0][11]; + const double var_80 = var_78 + var_79; + const double var_81 = var_20*var_62; + const double var_82 = var_16*var_7*var_8; + const double var_83 = var_33 + 0.5000000000000000000000000*var_82; + const double var_84 = var_1*w[0][6] + -var_3*w[0][0]; + const double var_85 = var_1*var_1*var_7*w[0][0] + -var_3*var_3*var_8*w[0][6] + var_4*var_84; + const double var_86 = -var_1*var_1*var_7*w[0][5] + var_3*var_3*var_8*w[0][11]; + const double var_87 = var_19*var_4; + const double var_88 = var_26 + var_87; + const double var_89 = var_86 + var_88 + var_85; + const double var_90 = var_6 + 0.5000000000000000000000000*var_89; + const double var_91 = var_1*var_1*var_8*w[0][11] + -var_3*var_3*var_7*w[0][5]; + const double var_92 = var_91 + var_9; + const double var_93 = var_42*var_62; + const double var_94 = 0.0375000000000000055511151*var_93; + const double var_95 = 0.0500000000000000027755576*var_90 + 0.1250000000000000000000000*var_13 + 0.1500000000000000222044605*var_92 + var_94; + const double var_96 = -var_1*var_54*var_7 + var_3*var_57*var_8; + const double var_97 = 0.0125000000000000006938894*var_96; + const double var_98 = 0.0428571428571428575393654*var_49 + 0.0303571428571428568454760*var_19*var_20; + const double var_99 = 0.0196428571428571424606346*var_42*var_43; + const double var_100 = -var_3*var_7*var_7*w[0][0] + var_1*var_8*var_8*w[0][6]; + const double var_101 = var_3*var_7*var_7*w[0][5] + -var_1*var_8*var_8*w[0][11]; + const double var_102 = var_7*w[0][5] + -var_8*w[0][11]; + const double var_103 = var_102*var_20; + const double var_104 = var_101 + var_103 + var_100; + const double var_105 = var_38 + var_41; + const double var_106 = -var_1*var_1*var_8*w[0][6] + var_3*var_3*var_7*w[0][0]; + const double var_107 = 0.5000000000000000000000000*var_106 + var_31; + const double var_108 = var_107 + var_105; + const double var_109 = 0.0142857142857142852682140*var_104 + var_98 + var_99 + 0.0017857142857142856585267*var_22 + 0.0357142857142857123031732*var_83 + 0.0642857142857142793701541*var_30 + 0.0160714285714285698425385*var_81 + 0.0035714285714285713170535*var_80 + var_97 + 0.0285714285714285705364279*var_23 + 0.1428571428571428492126927*var_95 + 0.0321428571428571396850771*var_108; + A[66] = 27.0000000000000000000000000*var_109*var_76/(var_77*var_77*var_77); + A[276] = A[66]; + A[31] = 0.0000000000000000000000000; + const double var_110 = var_4*var_45; + const double var_111 = var_93 + var_110; + const double var_112 = var_18 + var_87; + const double var_113 = 0.2000000000000000111022302*var_86 + 0.6000000000000000888178420*var_64 + 0.0500000000000000027755576*var_112 + 0.2500000000000000000000000*var_111 + var_14; + const double var_114 = var_19*var_20; + const double var_115 = var_44 + var_114; + const double var_116 = var_8*w[0][6] + -var_7*w[0][0]; + const double var_117 = -var_1*var_7*var_7*w[0][6] + var_3*var_8*var_8*w[0][0] + var_116*var_20; + const double var_118 = var_47 + var_117; + const double var_119 = 0.6000000000000000888178420*var_41 + var_23; + const double var_120 = 0.0500000000000000027755576*var_118 + 0.6000000000000000888178420*var_49 + 0.2500000000000000000000000*var_115 + 0.2000000000000000111022302*var_31 + var_119; + const double var_121 = var_100 + var_106; + const double var_122 = var_26 + var_29; + const double var_123 = var_82 + var_38; + const double var_124 = var_122 + var_123; + const double var_125 = var_30 + var_91; + const double var_126 = var_101 + var_33; + const double var_127 = var_126 + var_125; + const double var_128 = 0.4000000000000000222044605*var_124 + var_120 + 0.1500000000000000222044605*var_96 + var_113 + 0.1000000000000000055511151*var_121 + 0.8000000000000000444089210*var_127; + A[189] = 11.5714285714285711748061658*var_128*var_76/(var_77*var_77*var_77); + const double var_129 = var_1*var_7*var_7*w[0][10] + -var_3*var_8*var_8*w[0][4]; + const double var_130 = var_35 + var_129; + const double var_131 = var_7*w[0][4] + -var_8*w[0][10]; + const double var_132 = -var_7*w[0][3] + var_131 + var_8*w[0][9]; + const double var_133 = var_132*var_20; + const double var_134 = 1.3000000000000000444089210*var_133 + 1.4750000000000000888178420*var_20*var_43; + const double var_135 = 1.1500000000000001332267630*var_40*var_7*var_8; + const double var_136 = -var_3*w[0][5] + var_1*w[0][11]; + const double var_137 = -var_1*w[0][9] + var_3*w[0][3] + var_136; + const double var_138 = var_137*var_42; + const double var_139 = -var_1*w[0][0] + var_52; + const double var_140 = var_17*var_42 + var_139*var_7*var_8; + const double var_141 = var_19*var_42; + const double var_142 = var_141 + var_140; + const double var_143 = 11.0000000000000000000000000*var_138 + 12.5000000000000000000000000*var_101 + 0.5000000000000000000000000*var_30 + 0.8250000000000000666133815*var_22 + var_134 + 7.6750000000000007105427358*var_42*var_62 + 9.8500000000000014210854715*var_16*var_7*var_8 + 2.4750000000000000888178420*var_20*var_45 + 2.6500000000000003552713679*var_29 + 3.3000000000000002664535259*var_61 + 3.8000000000000002664535259*var_23 + 0.6500000000000000222044605*var_129 + 3.0000000000000000000000000*var_100 + var_135 + 2.1750000000000002664535259*var_142; + A[23] = 0.2142857142857142738190390*var_143*var_76/(var_77*var_77*var_77); + const double var_144 = -var_1*var_1*var_7*w[0][3] + var_3*var_3*var_8*w[0][9]; + const double var_145 = var_1*var_1*var_7*w[0][4] + -var_3*var_3*var_8*w[0][10] + var_144; + const double var_146 = var_4*var_43; + const double var_147 = var_101 + 0.5000000000000000000000000*var_38; + const double var_148 = var_29 + var_47; + const double var_149 = var_31 + var_22 + var_148; + const double var_150 = var_61 + 0.5000000000000000000000000*var_149; + const double var_151 = var_30 + var_23; + const double var_152 = 0.0375000000000000055511151*var_44; + const double var_153 = 0.1500000000000000222044605*var_151 + 0.1250000000000000000000000*var_41 + var_152 + 0.0500000000000000027755576*var_150; + const double var_154 = 0.0428571428571428575393654*var_64 + 0.0303571428571428568454760*var_4*var_45; + const double var_155 = 0.0196428571428571424606346*var_42*var_62; + const double var_156 = var_106 + var_68 + var_33; + const double var_157 = var_13 + var_82; + const double var_158 = 0.5000000000000000000000000*var_100 + var_86; + const double var_159 = var_158 + var_157; + const double var_160 = var_154 + 0.1428571428571428492126927*var_153 + var_97 + 0.0160714285714285698425385*var_146 + 0.0357142857142857123031732*var_147 + 0.0017857142857142856585267*var_85 + 0.0285714285714285705364279*var_9 + var_155 + 0.0642857142857142793701541*var_91 + 0.0142857142857142852682140*var_156 + 0.0035714285714285713170535*var_145 + 0.0321428571428571396850771*var_159; + A[88] = 27.0000000000000000000000000*var_160*var_76/(var_77*var_77*var_77); + A[374] = A[88]; + const double var_161 = var_27*var_3*var_7*var_7 + var_1*var_28*var_8*var_8 + 2.0625000000000000000000000*var_20*var_45; + const double var_162 = var_116 + var_17; + const double var_163 = -var_8*w[0][0] + var_55; + const double var_164 = var_21*var_42 + var_1*var_163*var_3; + const double var_165 = var_8*w[0][4] + -var_7*w[0][10]; + const double var_166 = var_1*var_165*var_3; + const double var_167 = var_27*var_8 + var_28*var_7; + const double var_168 = var_1*var_167*var_3; + const double var_169 = var_166 + var_168 + var_164 + var_46; + const double var_170 = var_1*var_1*var_25*var_8 + 2.0625000000000000000000000*var_19*var_4 + var_24*var_3*var_3*var_7; + const double var_171 = 0.0178571428571428561515866*var_169 + 0.0357142857142857123031732*var_42*var_60 + 0.0285714285714285705364279*var_170 + 0.0464285714285714301574615*var_26; + const double var_172 = var_137*var_4; + const double var_173 = 0.0232142857142857150787307*var_4*var_62 + 0.0357142857142857123031732*var_172; + const double var_174 = 0.1071428571428571369095195*var_6 + var_173 + var_171 + 0.0482142857142857095276156*var_85 + 0.0303571428571428568454760*var_106 + 0.0071428571428571426341070*var_91 + 0.0250000000000000013877788*var_86; + A[47] = 3.0000000000000000000000000*var_174*var_76/(var_77*var_77*var_77); + const double var_175 = 0.5000000000000000000000000*var_1*var_165*var_3; + const double var_176 = var_175 + var_69; + A[271] = A[23]; + A[202] = 0.0000000000000000000000000; + const double var_177 = -var_1*var_8*var_8*w[0][9] + var_3*var_7*var_7*w[0][3]; + const double var_178 = var_146 + var_85; + const double var_179 = var_3*var_3*var_7*w[0][4] + -var_1*var_1*var_8*w[0][10]; + const double var_180 = var_1*var_8*var_8*w[0][10] + -var_3*var_7*var_7*w[0][4]; + const double var_181 = var_180 + var_179; + const double var_182 = 0.0160714285714285698425385*var_117; + const double var_183 = -var_3*var_3*var_7*w[0][3] + var_1*var_1*var_8*w[0][9]; + const double var_184 = 0.1142857142857142821457117*var_183; + const double var_185 = 0.0714285714285714246063463*var_103; + const double var_186 = var_25*var_3 + var_1*var_24; + const double var_187 = var_172 + var_168; + const double var_188 = var_58 + var_80 + var_82; + const double var_189 = var_166 + 0.5000000000000000000000000*var_129; + const double var_190 = 0.3750000000000000000000000*var_188 + 0.0625000000000000000000000*var_47 + 4.6250000000000000000000000*var_186*var_7*var_8 + var_91 + 2.0000000000000000000000000*var_86 + 1.0625000000000000000000000*var_20*var_43 + 2.8750000000000000000000000*var_19*var_42 + 1.5000000000000000000000000*var_133 + 3.0000000000000000000000000*var_145 + 0.7500000000000000000000000*var_111 + 3.2500000000000000000000000*var_189 + var_187; + const double var_191 = 0.2000000000000000111022302*var_185 + var_184 + var_182 + 0.0267857142857142842273799*var_32 + 0.0285714285714285705364279*var_190 + 0.0357142857142857123031732*var_178 + 0.1428571428571428492126927*var_177 + 0.0250000000000000013877788*var_106 + 0.1785714285714285753936537*var_181; + A[106] = 27.0000000000000000000000000*var_191*var_76/(var_77*var_77*var_77); + A[335] = A[106]; + const double var_192 = var_22 + var_81; + const double var_193 = var_9 + var_31; + const double var_194 = var_82 + 4.5625000000000000000000000*var_19*var_20 + 6.7500000000000000000000000*var_20*var_48 + 1.1875000000000000000000000*var_192 + 2.0000000000000000000000000*var_101 + var_29 + 5.7500000000000000000000000*var_193; + const double var_195 = var_19 + var_45; + const double var_196 = 0.2500000000000000000000000*var_42*var_45; + const double var_197 = 0.2375000000000000166533454*var_96; + const double var_198 = var_6 + var_86; + const double var_199 = var_64 + var_26; + const double var_200 = 0.7125000000000000222044605*var_42*var_43 + 2.3000000000000002664535259*var_30 + 0.4250000000000000444089210*var_106 + 0.2000000000000000111022302*var_194 + 1.7000000000000001776356839*var_33 + 0.9500000000000000666133815*var_38 + 0.1875000000000000000000000*var_85 + 0.4000000000000000222044605*var_13 + 0.1500000000000000222044605*var_196 + 1.1500000000000001332267630*var_41 + 0.3125000000000000000000000*var_195*var_4 + 0.4750000000000000333066907*var_100 + 0.9000000000000000222044605*var_91 + 0.5000000000000000000000000*var_198 + 1.3500000000000000888178420*var_23 + var_197 + 0.7500000000000000000000000*var_199; + A[192] = 0.0000000000000000000000000; + A[136] = 0.0000000000000000000000000; + A[6] = 3.0000000000000000000000000*var_73*var_76/(var_77*var_77*var_77); + const double var_201 = var_23 + var_86; + const double var_202 = 1.1875000000000000000000000*var_178 + 2.0000000000000000000000000*var_33 + 6.7500000000000000000000000*var_4*var_63 + var_26 + var_38 + 4.5625000000000000000000000*var_4*var_45 + 5.7500000000000000000000000*var_201; + const double var_203 = 0.2500000000000000000000000*var_19*var_42; + const double var_204 = var_61 + var_31; + const double var_205 = var_49 + var_29; + const double var_206 = 0.5000000000000000000000000*var_204 + 0.1500000000000000222044605*var_203 + 0.7500000000000000000000000*var_205 + 0.7125000000000000222044605*var_42*var_62 + 1.3500000000000000888178420*var_9 + 2.3000000000000002664535259*var_91 + 1.1500000000000001332267630*var_13 + 0.4250000000000000444089210*var_100 + 0.4000000000000000222044605*var_41 + 1.7000000000000001776356839*var_101 + 0.9000000000000000222044605*var_30 + 0.1875000000000000000000000*var_22 + 0.4750000000000000333066907*var_106 + 0.9500000000000000666133815*var_82 + 0.3125000000000000000000000*var_195*var_20 + 0.2000000000000000111022302*var_202 + var_197; + const double var_207 = var_29 + var_203; + const double var_208 = 0.0071428571428571426341070*var_166; + const double var_209 = 0.1857142857142857206298459*var_101; + const double var_210 = 0.7500000000000000000000000*var_20*var_43 + var_49; + const double var_211 = 0.0357142857142857123031732*var_210; + const double var_212 = var_103 + var_180; + const double var_213 = var_64 + var_82; + const double var_214 = var_1*var_10*var_3 + var_136*var_42; + const double var_215 = var_110 + var_18; + const double var_216 = 0.0714285714285714246063463*var_68; + const double var_217 = 0.1071428571428571369095195*var_213 + 0.0160714285714285698425385*var_20*var_45 + 0.0607142857142857136909520*var_32 + 0.0428571428571428575393654*var_41 + 0.1214285714285714273819039*var_23 + 0.1928571428571428381104624*var_9 + var_211 + var_216 + 0.0285714285714285705364279*var_33 + 0.0946428571428571396850771*var_42*var_62 + 0.0785714285714285698425385*var_207 + var_208 + 0.0732142857142857178542883*var_117 + 0.0267857142857142842273799*var_146 + 0.1000000000000000055511151*var_129 + var_209 + 0.0446428571428571438484134*var_215 + var_97 + 0.1571428571428571396850771*var_214 + 0.0357142857142857123031732*var_26 + 0.0321428571428571396850771*var_34 + 0.0571428571428571410728559*var_212; + A[147] = 27.0000000000000000000000000*var_217*var_76/(var_77*var_77*var_77); + const double var_218 = var_84 + var_21; + const double var_219 = var_218 + var_62; + const double var_220 = 8.5666666666666664298190881*var_48 + 6.9000000000000003552713679*var_5 + 1.6666666666666665186369300*var_63 + 5.5916666666666667850904560*var_19 + 1.3083333333333333481363070*var_219; + A[42] = 0.1428571428571428492126927*var_220*var_4*var_76/(var_77*var_77*var_77); + A[252] = A[42]; + const double var_221 = var_13 + var_41; + const double var_222 = var_44 + var_93; + const double var_223 = var_22 + var_85; + const double var_224 = var_222 + var_223 + var_221; + const double var_225 = var_88 + var_148; + const double var_226 = var_86 + var_31; + const double var_227 = var_23 + var_9; + const double var_228 = var_61 + var_6; + const double var_229 = var_227 + var_228; + const double var_230 = var_123 + var_121; + const double var_231 = var_49 + var_114; + const double var_232 = var_64 + var_110; + const double var_233 = var_231 + var_232; + const double var_234 = 0.1214285714285714273819039*var_226 + 0.0785714285714285698425385*var_224 + 0.0357142857142857123031732*var_225 + 0.1571428571428571396850771*var_96 + 0.2714285714285714079530010*var_126 + 0.0428571428571428575393654*var_233 + 0.2000000000000000111022302*var_125 + 0.2357142857142857095276156*var_230 + 0.1142857142857142821457117*var_229; + A[9] = 9.0000000000000000000000000*var_234*var_76/(var_77*var_77*var_77); + A[390] = A[9]; + const double var_235 = 1.3000000000000000444089210*var_172 + 1.4750000000000000888178420*var_4*var_62; + const double var_236 = 0.0964285714285714190552312*var_19*var_20; + const double var_237 = 0.0928571428571428603149229*var_16*var_7*var_8; + const double var_238 = 0.4125000000000000333066907*var_146 + 0.3250000000000000111022302*var_145; + const double var_239 = 0.1946428571428571452361922*var_96; + const double var_240 = 0.1857142857142857206298459*var_33; + const double var_241 = 0.1285714285714285587403083*var_133; + const double var_242 = var_186*var_7*var_8; + const double var_243 = var_80 + var_242; + const double var_244 = 0.2357142857142857095276156*var_68 + 0.0553571428571428547638078*var_42*var_45 + 0.0357142857142857123031732*var_69 + 0.2928571428571428714171532*var_30 + 0.2678571428571428492126927*var_1*var_167*var_3 + 0.5500000000000000444089210*var_70 + 0.0500000000000000027755576*var_47 + 0.0178571428571428561515866*var_106 + 0.3714285714285714412596917*var_22 + 0.2821428571428571396850771*var_35 + 0.3500000000000000333066907*var_177 + 0.1428571428571428492126927*var_238 + 0.3142857142857142793701541*var_183 + 0.4214285714285714301574615*var_61 + 1.5000000000000000000000000*var_237 + 0.5660714285714285587403083*var_100 + 0.2321428571428571230317317*var_38 + 0.0714285714285714246063463*var_235 + var_236 + 0.4678571428571428603149229*var_31 + 0.1767857142857142682679239*var_18 + var_239 + var_240 + var_152 + var_241 + 0.1750000000000000166533454*var_243; + A[7] = 3.0000000000000000000000000*var_244*var_76/(var_77*var_77*var_77); + A[217] = A[7]; + const double var_245 = var_26 + var_147; + const double var_246 = var_97 + 0.0375000000000000055511151*var_100 + 0.1500000000000000222044605*var_83 + 0.2000000000000000111022302*var_91 + 0.2500000000000000000000000*var_113 + 0.1000000000000000055511151*var_245 + var_153; + A[87] = 3.8571428571428567622092487*var_246*var_76/(var_77*var_77*var_77); + A[333] = A[66]; + A[264] = 0.0000000000000000000000000; + A[346] = 0.0000000000000000000000000; + A[17] = 0.0000000000000000000000000; + const double var_247 = 0.5000000000000000000000000*var_36*var_7*var_8; + const double var_248 = var_70 + var_247; + const double var_249 = 0.0071428571428571426341070*var_231; + const double var_250 = var_80 + var_81; + const double var_251 = 1.6875000000000000000000000*var_58; + const double var_252 = var_4*var_62; + const double var_253 = var_252 + var_46; + const double var_254 = 2.0000000000000000000000000*var_181 + var_251 + 5.7500000000000000000000000*var_35 + 2.8750000000000000000000000*var_34 + var_250 + 0.7500000000000000000000000*var_117 + 2.4375000000000000000000000*var_32 + 1.1875000000000000000000000*var_112 + 1.5000000000000000000000000*var_242 + 7.7500000000000000000000000*var_183 + 7.2500000000000000000000000*var_69 + var_145 + var_189 + 6.7500000000000000000000000*var_187 + 4.5625000000000000000000000*var_253; + const double var_255 = 0.3571428571428571507873073*var_248 + var_99 + 0.0714285714285714246063463*var_177 + 0.0500000000000000027755576*var_103 + var_249 + 0.0285714285714285705364279*var_254; + A[68] = 27.0000000000000000000000000*var_255*var_76/(var_77*var_77*var_77); + A[373] = A[68]; + const double var_256 = -var_7*w[0][6] + var_53; + const double var_257 = var_116*var_42 + var_1*var_256*var_3; + const double var_258 = 0.1500000000000000222044605*var_42*var_60; + const double var_259 = 0.0125000000000000006938894*var_34; + const double var_260 = var_132*var_42; + const double var_261 = var_260 + var_9; + const double var_262 = 61.0000000000000000000000000*var_37 + 13.0000000000000000000000000*var_12; + const double var_263 = 2.0000000000000000000000000*var_261 + var_258 + 0.2375000000000000166533454*var_18 + 0.3750000000000000000000000*var_46 + 0.5750000000000000666133815*var_35 + 0.0250000000000000013877788*var_1*var_262*var_3 + 1.6750000000000000444089210*var_26 + 1.3000000000000000444089210*var_44 + 3.2000000000000001776356839*var_33 + 0.2250000000000000055511151*var_257 + 0.8875000000000000666133815*var_19*var_4 + 0.2500000000000000000000000*var_70 + 0.6500000000000000222044605*var_6 + 0.4500000000000000111022302*var_65 + var_259; + A[45] = 0.4285714285714285476380780*var_263*var_76/(var_77*var_77*var_77); + A[95] = 0.0000000000000000000000000; + const double var_264 = 0.5500000000000000444089210*var_64 + 0.4625000000000000222044605*var_4*var_45; + const double var_265 = var_6 + var_210; + const double var_266 = var_103 + var_181; + const double var_267 = 0.0053571428571428571924207*var_87 + 0.1000000000000000055511151*var_93 + 0.1946428571428571452361922*var_32 + 0.1428571428571428492126927*var_264 + var_59 + 0.0642857142857142793701541*var_265 + 0.0714285714285714246063463*var_135 + 0.1464285714285714357085766*var_29 + 0.0178571428571428561515866*var_26 + 0.1785714285714285753936537*var_101 + 0.0321428571428571396850771*var_82 + 0.1107142857142857095276156*var_1*var_165*var_3 + 0.0428571428571428575393654*var_141 + 0.0089285714285714280757933*var_34 + 0.2250000000000000055511151*var_13 + 0.3500000000000000333066907*var_91 + 0.2428571428571428547638078*var_9 + 0.2285714285714285642914234*var_23 + 0.1250000000000000000000000*var_86 + 0.1750000000000000166533454*var_129 + 0.1267857142857142793701541*var_117 + 0.0589285714285714273819039*var_85 + 0.0339285714285714259941251*var_20*var_45 + 0.0928571428571428603149229*var_266; + A[8] = 3.0000000000000000000000000*var_267*var_76/(var_77*var_77*var_77); + A[218] = A[8]; + const double var_268 = 0.0660714285714285726180961*var_4*var_62 + 0.0785714285714285698425385*var_172; + const double var_269 = var_268 + var_171 + 0.0607142857142857136909520*var_35 + 0.0785714285714285698425385*var_70 + 0.0642857142857142793701541*var_4*var_5 + 0.0053571428571428571924207*var_85 + var_259; + const double var_270 = var_20*var_43; + const double var_271 = var_270 + var_133; + const double var_272 = 0.0035714285714285713170535*var_58; + const double var_273 = 0.0142857142857142852682140*var_271 + var_272; + const double var_274 = var_148 + var_41; + const double var_275 = var_90 + var_166; + const double var_276 = var_237 + var_273 + 0.0857142857142857150787307*var_61 + 0.0142857142857142852682140*var_179 + 0.0500000000000000027755576*var_274 + 0.1000000000000000055511151*var_23 + 0.1714285714285714301574615*var_1*var_12*var_3 + 0.0250000000000000013877788*var_141 + 0.0714285714285714246063463*var_30 + 0.1428571428571428492126927*var_101 + 0.1857142857142857206298459*var_92 + 0.0357142857142857123031732*var_22 + 0.0964285714285714190552312*var_42*var_62 + 0.0321428571428571396850771*var_100 + 0.0214285714285714287696827*var_107 + 0.0285714285714285705364279*var_275; + A[15] = 0.0000000000000000000000000; + A[50] = 0.0000000000000000000000000; + A[94] = 0.0000000000000000000000000; + A[209] = 0.0000000000000000000000000; + A[341] = 0.0000000000000000000000000; + A[249] = 0.0000000000000000000000000; + A[226] = 0.0000000000000000000000000; + const double var_277 = var_36*var_7*var_8; + const double var_278 = 0.0535714285714285684547598*var_20*var_43 + var_241; + const double var_279 = 0.1071428571428571369095195*var_242 + 0.1214285714285714273819039*var_80; + const double var_280 = -w[0][10] + var_28; + const double var_281 = w[0][4] + var_27; + const double var_282 = var_280*var_3*var_3*var_8 + var_18 + var_146 + var_1*var_1*var_281*var_7; + const double var_283 = var_68 + 0.5000000000000000000000000*var_282; + const double var_284 = 0.0321428571428571396850771*var_19*var_42; + const double var_285 = 0.0321428571428571396850771*var_42*var_45; + const double var_286 = 0.0535714285714285684547598*var_58; + const double var_287 = var_129 + var_32; + const double var_288 = var_27*var_3*var_3*var_7 + var_1*var_1*var_28*var_8; + const double var_289 = var_288 + var_180; + const double var_290 = var_284 + var_286 + 0.0785714285714285698425385*var_287 + 0.1714285714285714301574615*var_1*var_167*var_3 + var_279 + 0.1857142857142857206298459*var_289 + 0.0250000000000000013877788*var_117 + 0.0857142857142857150787307*var_166 + 0.1000000000000000055511151*var_179 + 0.2285714285714285642914234*var_177 + 0.0464285714285714301574615*var_20*var_62 + 0.0678571428571428519882502*var_34 + 0.2714285714285714079530010*var_69 + 0.1500000000000000222044605*var_277 + 3.0000000000000000000000000*var_285 + 0.0285714285714285705364279*var_283 + var_278 + var_185; + A[69] = 27.0000000000000000000000000*var_290*var_76/(var_77*var_77*var_77); + A[393] = A[69]; + A[340] = 0.0000000000000000000000000; + A[201] = 0.0000000000000000000000000; + const double var_291 = 0.1500000000000000222044605*var_42*var_5; + const double var_292 = 0.0125000000000000006938894*var_32; + const double var_293 = var_23 + var_138; + const double var_294 = 61.0000000000000000000000000*var_16 + 13.0000000000000000000000000*var_40; + const double var_295 = 2.0000000000000000000000000*var_293 + 0.6500000000000000222044605*var_61 + 3.2000000000000001776356839*var_101 + 1.3000000000000000444089210*var_93 + 0.2250000000000000055511151*var_140 + 0.8875000000000000666133815*var_20*var_45 + 1.6750000000000000444089210*var_29 + 0.2500000000000000000000000*var_180 + 0.5750000000000000666133815*var_129 + var_291 + 0.2375000000000000166533454*var_117 + var_292 + 0.3750000000000000000000000*var_141 + 0.4500000000000000111022302*var_210 + 0.0250000000000000013877788*var_294*var_7*var_8; + A[27] = 0.4285714285714285476380780*var_295*var_76/(var_77*var_77*var_77); + A[237] = A[27]; + A[360] = 0.0000000000000000000000000; + const double var_296 = var_39*var_7*var_8 + var_131*var_42; + const double var_297 = var_42*var_48; + const double var_298 = var_179 + var_297; + const double var_299 = var_34 + var_32; + const double var_300 = 0.0071428571428571426341070*var_232; + const double var_301 = var_179 + var_69; + const double var_302 = var_221 + var_301; + const double var_303 = var_166 + var_277; + const double var_304 = var_303 + var_227; + const double var_305 = 0.0571428571428571410728559*var_302 + 0.0928571428571428603149229*var_125 + 0.0357142857142857123031732*var_226 + 0.0500000000000000027755576*var_228 + 0.0785714285714285698425385*var_304 + var_300 + 0.0285714285714285705364279*var_223 + 0.0214285714285714287696827*var_225 + 0.0732142857142857178542883*var_58 + var_249 + 0.0446428571428571438484134*var_299 + 0.0053571428571428571924207*var_195*var_42; + A[107] = 27.0000000000000000000000000*var_305*var_76/(var_77*var_77*var_77); + A[145] = A[107]; + A[118] = 0.0000000000000000000000000; + A[229] = 0.0000000000000000000000000; + const double var_306 = var_24*var_3*var_7*var_7 + var_1*var_25*var_8*var_8; + A[349] = 0.0000000000000000000000000; + A[383] = 0.0000000000000000000000000; + const double var_307 = var_145 + var_146; + const double var_308 = var_18 + var_70 + var_179 + var_147; + const double var_309 = 0.0071428571428571426341070*var_35; + const double var_310 = var_81 + var_24*var_3*var_8*var_8 + var_1*var_25*var_7*var_7 + var_117 + var_79; + const double var_311 = var_103 + 0.5000000000000000000000000*var_310; + const double var_312 = var_203 + var_306; + const double var_313 = 0.2000000000000000111022302*var_311 + 0.5000000000000000000000000*var_242 + 0.0500000000000000027755576*var_34 + 0.6000000000000000888178420*var_312; + const double var_314 = var_68 + var_313; + const double var_315 = var_309 + var_300 + 0.0142857142857142852682140*var_308 + 0.0053571428571428571924207*var_42*var_62 + 0.0178571428571428561515866*var_82 + var_97 + 0.0285714285714285705364279*var_183 + 0.0089285714285714280757933*var_100 + 0.0071428571428571426341070*var_168 + 0.0214285714285714287696827*var_307 + 0.0357142857142857123031732*var_314; + A[127] = 27.0000000000000000000000000*var_315*var_76/(var_77*var_77*var_77); + A[146] = A[127]; + A[356] = A[127]; + A[37] = 0.0000000000000000000000000; + A[328] = 0.0000000000000000000000000; + const double var_316 = var_43 + var_62; + const double var_317 = var_67 + var_102; + const double var_318 = var_132 + var_137; + const double var_319 = 0.7500000000000000000000000*var_317 + 0.4541666666666666629659233*var_316 + 1.0666666666666666518636930*var_318 + 0.2958333333333333370340767*var_162; + A[22] = 0.1428571428571428492126927*var_319*var_42*var_76/(var_77*var_77*var_77); + const double var_320 = var_130 + var_103 + var_68; + const double var_321 = var_49 + var_64 + var_122; + const double var_322 = var_252 + var_270; + const double var_323 = var_146 + var_322 + var_81; + const double var_324 = var_18 + var_117; + const double var_325 = var_58 + 0.5000000000000000000000000*var_324; + const double var_326 = var_180 + var_70; + const double var_327 = 0.2380952380952380820211545*var_321 + 0.7142857142857143015746146*var_227 + 1.7333333333333333925452280*var_301 + 0.4761904761904761640423089*var_221 + 2.3964285714285713524418497*var_299 + 1.5976190476190477163243031*var_325 + 0.3738095238095238692643818*var_195*var_42 + 1.9714285714285713080329288*var_303 + 0.9857142857142856540164644*var_320 + 0.1869047619047619346321909*var_323 + 0.5095238095238096009964579*var_326; + A[0] = var_327*var_76/(var_77*var_77*var_77); + A[302] = 0.0000000000000000000000000; + A[13] = 0.0000000000000000000000000; + const double var_328 = var_42*var_67; + const double var_329 = var_179 + var_183; + const double var_330 = var_24*var_8 + var_25*var_7 + var_11; + const double var_331 = var_93 + var_86 + var_257 + var_1*var_3*var_330 + 11.0000000000000000000000000*var_307; + const double var_332 = var_45 + var_63; + const double var_333 = var_102*var_42; + const double var_334 = var_333 + var_91; + const double var_335 = 0.3000000000000000444089210*var_332*var_4 + 0.5000000000000000000000000*var_329 + 0.8000000000000000444089210*var_4*var_67 + 0.2000000000000000111022302*var_34 + 0.2500000000000000000000000*var_18 + 0.0500000000000000027755576*var_331 + 0.1000000000000000055511151*var_334; + A[49] = 1.2857142857142855874030829*var_335*var_76/(var_77*var_77*var_77); + A[182] = A[49]; + const double var_336 = -var_3*w[0][6] + var_56; + const double var_337 = var_42*var_84 + var_336*var_7*var_8; + const double var_338 = var_337 + var_277 + var_242 + var_141; + const double var_339 = 0.0178571428571428561515866*var_338 + 0.0357142857142857123031732*var_42*var_5 + 0.0464285714285714301574615*var_29 + 0.0285714285714285705364279*var_161; + const double var_340 = 0.0660714285714285726180961*var_20*var_43 + 0.0785714285714285698425385*var_133; + const double var_341 = var_340 + 0.0607142857142857136909520*var_129 + 0.0053571428571428571924207*var_22 + 0.0785714285714285698425385*var_180 + 0.0642857142857142793701541*var_20*var_60 + var_339 + var_292; + A[26] = 3.0000000000000000000000000*var_341*var_76/(var_77*var_77*var_77); + A[331] = A[26]; + const double var_342 = var_218 + var_43; + const double var_343 = 6.9000000000000003552713679*var_60 + 1.6666666666666665186369300*var_48 + 8.5666666666666664298190881*var_63 + 5.5916666666666667850904560*var_45 + 1.3083333333333333481363070*var_342; + const double var_344 = var_133 + var_242; + const double var_345 = var_140 + var_46 + var_192; + const double var_346 = var_42*var_63; + const double var_347 = var_136*var_20 + var_346 + var_78; + const double var_348 = var_328 + var_31; + const double var_349 = 0.3166666666666666518636930*var_344 + 0.4333333333333333481363070*var_30 + 0.4541666666666666629659233*var_345 + 1.3833333333333333037273860*var_177 + 0.9083333333333333259318465*var_100 + 1.0666666666666666518636930*var_347 + 0.2958333333333333370340767*var_115 + 0.7500000000000000000000000*var_348; + A[1] = 0.1428571428571428492126927*var_349*var_76/(var_77*var_77*var_77); + A[173] = 0.0000000000000000000000000; + const double var_350 = var_114 + var_117; + const double var_351 = var_1*var_281 + var_280*var_3; + const double var_352 = var_140 + var_44 + 11.0000000000000000000000000*var_250 + var_351*var_7*var_8 + var_31; + const double var_353 = var_69 + var_177; + const double var_354 = var_19 + var_48; + const double var_355 = var_30 + var_328; + const double var_356 = 0.8000000000000000444089210*var_102*var_20 + 0.1000000000000000055511151*var_355 + 0.2500000000000000000000000*var_117 + 0.0500000000000000027755576*var_352 + 0.2000000000000000111022302*var_32 + 0.3000000000000000444089210*var_20*var_354 + 0.5000000000000000000000000*var_353; + A[29] = 1.2857142857142855874030829*var_356*var_76/(var_77*var_77*var_77); + A[391] = A[29]; + const double var_357 = var_38 + var_49; + const double var_358 = 0.1767857142857142682679239*var_299 + 0.1178571428571428547638078*var_325; + const double var_359 = 0.1214285714285714273819039*var_145 + 0.1071428571428571369095195*var_168; + const double var_360 = var_247 + var_179; + const double var_361 = var_358 + 0.1357142857142857039765005*var_70 + 0.0482142857142857095276156*var_4*var_43 + var_340 + 0.1571428571428571396850771*var_177 + 0.0178571428571428561515866*var_80 + 0.1250000000000000000000000*var_129 + 0.0642857142857142793701541*var_103 + 0.2321428571428571230317317*var_166 + 0.2642857142857142904723844*var_180 + 0.1392857142857142904723844*var_186*var_7*var_8 + 0.0821428571428571424606346*var_35 + 0.1642857142857142849212693*var_69 + 0.5000000000000000000000000*var_359 + 0.1071428571428571369095195*var_68 + 0.0285714285714285705364279*var_46 + var_184 + 0.0053571428571428571924207*var_81 + 0.1142857142857142821457117*var_141 + var_173 + 0.2928571428571428714171532*var_360; + A[317] = A[107]; + const double var_362 = var_38 + var_58 + var_145; + const double var_363 = 0.5000000000000000000000000*var_35 + var_277; + const double var_364 = 3.2500000000000000000000000*var_363 + 3.0000000000000000000000000*var_80 + var_30 + 2.8750000000000000000000000*var_42*var_45 + 0.0625000000000000000000000*var_87 + 4.6250000000000000000000000*var_1*var_167*var_3 + var_344 + 2.0000000000000000000000000*var_31 + 1.5000000000000000000000000*var_172 + 0.3750000000000000000000000*var_362 + 0.7500000000000000000000000*var_115 + 1.0625000000000000000000000*var_4*var_62; + A[261] = 0.0000000000000000000000000; + A[287] = 0.0000000000000000000000000; + A[39] = 0.0000000000000000000000000; + const double var_365 = 0.0375000000000000055511151*var_96; + const double var_366 = 0.0464285714285714301574615*var_31; + const double var_367 = var_100 + var_41; + const double var_368 = var_61 + var_88; + const double var_369 = 0.0357142857142857123031732*var_15 + var_366 + var_300 + 0.0285714285714285705364279*var_86 + 0.0214285714285714287696827*var_85 + 0.0535714285714285684547598*var_367 + 0.0642857142857142793701541*var_23 + 0.0500000000000000027755576*var_91 + var_365 + 0.0785714285714285698425385*var_38 + 0.0160714285714285698425385*var_22 + 0.0089285714285714280757933*var_93 + var_98 + 0.0589285714285714273819039*var_106 + 0.0410714285714285712303173*var_42*var_43 + 0.0928571428571428603149229*var_83 + 0.1000000000000000055511151*var_30 + 0.0107142857142857143848413*var_29 + 0.0571428571428571410728559*var_101 + 0.0017857142857142856585267*var_81 + 0.0142857142857142852682140*var_368; + A[85] = 27.0000000000000000000000000*var_369*var_76/(var_77*var_77*var_77); + A[295] = A[85]; + A[21] = 0.1428571428571428492126927*var_20*var_343*var_76/(var_77*var_77*var_77); + A[231] = A[21]; + A[251] = A[22]; + const double var_370 = var_69 + var_117 + var_180 + var_83; + const double var_371 = 0.0071428571428571426341070*var_129; + const double var_372 = var_288 + var_196; + const double var_373 = 0.2000000000000000111022302*var_283 + 0.6000000000000000888178420*var_372 + 0.0500000000000000027755576*var_32 + 0.5000000000000000000000000*var_168; + const double var_374 = var_103 + var_373; + const double var_375 = 0.0178571428571428561515866*var_38 + var_249 + var_371 + var_97 + 0.0053571428571428571924207*var_42*var_43 + 0.0071428571428571426341070*var_242 + 0.0357142857142857123031732*var_374 + 0.0285714285714285705364279*var_177 + 0.0089285714285714280757933*var_106 + 0.0142857142857142852682140*var_370 + 0.0214285714285714287696827*var_250; + A[108] = 27.0000000000000000000000000*var_375*var_76/(var_77*var_77*var_77); + A[375] = A[108]; + A[266] = 0.0000000000000000000000000; + const double var_376 = 0.0232142857142857150787307*var_20*var_43 + 0.0357142857142857123031732*var_133; + const double var_377 = 0.0071428571428571426341070*var_30 + 0.0482142857142857095276156*var_22 + 0.0250000000000000013877788*var_31 + var_376 + 0.0303571428571428568454760*var_100 + 0.1071428571428571369095195*var_61 + var_339; + A[111] = 0.0000000000000000000000000; + A[132] = 0.0000000000000000000000000; + A[260] = 0.0000000000000000000000000; + A[307] = 0.0000000000000000000000000; + A[96] = 0.0000000000000000000000000; + A[211] = A[1]; + A[171] = 0.0000000000000000000000000; + A[399] = A[189]; + A[134] = 0.0000000000000000000000000; + A[169] = 27.0000000000000000000000000*var_276*var_76/(var_77*var_77*var_77); + const double var_378 = 0.3250000000000000111022302*var_80 + 0.4125000000000000333066907*var_81; + const double var_379 = 19.0000000000000000000000000*var_186 + 67.0000000000000000000000000*var_36; + const double var_380 = var_346 + var_69; + const double var_381 = 0.0250000000000000013877788*var_379*var_7*var_8 + 1.3000000000000000444089210*var_46 + 0.2250000000000000055511151*var_42*var_43 + 0.0500000000000000027755576*var_180 + var_291 + 0.3750000000000000000000000*var_337 + 0.4125000000000000333066907*var_32 + var_378 + 0.4500000000000000111022302*var_103 + 0.8000000000000000444089210*var_177 + var_50 + 0.0375000000000000055511151*var_117 + 0.4250000000000000444089210*var_31 + 2.0000000000000000000000000*var_380; + A[24] = 0.4285714285714285476380780*var_381*var_76/(var_77*var_77*var_77); + A[234] = A[24]; + const double var_382 = var_26 + var_196; + const double var_383 = 0.0160714285714285698425385*var_18; + const double var_384 = 0.0625000000000000000000000*var_96; + const double var_385 = 0.0357142857142857123031732*var_65; + const double var_386 = var_13 + var_194; + const double var_387 = 0.0964285714285714190552312*var_100 + 0.1589285714285714190552312*var_42*var_43 + var_385 + 0.3857142857142856762209249*var_30 + 0.0428571428571428575393654*var_35 + 0.3571428571428571507873073*var_33 + 0.0732142857142857178542883*var_19*var_4 + 0.0142857142857142852682140*var_70 + 0.2214285714285714190552312*var_105 + 0.0464285714285714301574615*var_106 + var_383 + 0.2500000000000000000000000*var_23 + var_384 + 0.0571428571428571410728559*var_4*var_5 + 0.1357142857142857039765005*var_382 + 0.0285714285714285705364279*var_386; + A[219] = A[9]; + A[221] = 0.0000000000000000000000000; + const double var_388 = 0.2000000000000000111022302*var_301 + var_373 + var_313 + 0.0500000000000000027755576*var_96 + 0.1000000000000000055511151*var_303; + A[388] = 0.0000000000000000000000000; + const double var_389 = var_252 + var_172; + const double var_390 = 0.0464285714285714301574615*var_86; + const double var_391 = var_13 + var_106; + const double var_392 = var_119 + var_61; + const double var_393 = var_6 + var_148; + const double var_394 = var_249 + 0.0089285714285714280757933*var_44 + var_390 + 0.0107142857142857143848413*var_26 + 0.0589285714285714273819039*var_100 + 0.0357142857142857123031732*var_392 + 0.0785714285714285698425385*var_82 + 0.0285714285714285705364279*var_31 + 0.0410714285714285712303173*var_42*var_62 + 0.0160714285714285698425385*var_85 + 0.0500000000000000027755576*var_30 + 0.0928571428571428603149229*var_147 + 0.0017857142857142856585267*var_146 + var_154 + 0.0214285714285714287696827*var_22 + var_365 + 0.1000000000000000055511151*var_91 + 0.0642857142857142793701541*var_9 + 0.0571428571428571410728559*var_33 + 0.0535714285714285684547598*var_391 + 0.0142857142857142852682140*var_393; + A[67] = 27.0000000000000000000000000*var_394*var_76/(var_77*var_77*var_77); + A[143] = A[67]; + A[392] = A[49]; + A[48] = 3.0000000000000000000000000*var_269*var_76/(var_77*var_77*var_77); + A[258] = A[48]; + A[36] = 0.0000000000000000000000000; + A[380] = 0.0000000000000000000000000; + A[20] = A[1]; + const double var_395 = 0.0142857142857142852682140*var_389 + var_272; + const double var_396 = 0.0928571428571428603149229*var_1*var_3*var_37; + const double var_397 = var_13 + var_88; + const double var_398 = var_150 + var_277; + const double var_399 = var_396 + 0.0857142857142857150787307*var_6 + 0.0500000000000000027755576*var_397 + 0.0250000000000000013877788*var_46 + var_395 + 0.1000000000000000055511151*var_9 + 0.0142857142857142852682140*var_69 + 0.0964285714285714190552312*var_42*var_43 + 0.0214285714285714287696827*var_158 + 0.1714285714285714301574615*var_40*var_7*var_8 + 0.0357142857142857123031732*var_85 + 0.1428571428571428492126927*var_33 + 0.0321428571428571396850771*var_106 + 0.1857142857142857206298459*var_151 + 0.0285714285714285705364279*var_398 + 0.0714285714285714246063463*var_91; + A[129] = 27.0000000000000000000000000*var_399*var_76/(var_77*var_77*var_77); + const double var_400 = var_180 + var_175; + A[284] = 0.0000000000000000000000000; + A[303] = 0.0000000000000000000000000; + A[300] = 0.0000000000000000000000000; + const double var_401 = var_202 + var_41; + A[138] = 0.0000000000000000000000000; + const double var_402 = 197.0000000000000000000000000*var_36 + 23.0000000000000000000000000*var_186; + const double var_403 = var_337 + var_44; + const double var_404 = var_236 + 0.5482142857142856540164644*var_42*var_45 + 1.3000000000000000444089210*var_69 + 0.5964285714285714190552312*var_80 + 0.0357142857142857123031732*var_180 + 0.2053571428571428492126927*var_32 + 0.0500000000000000027755576*var_117 + 0.7857142857142856984253854*var_42*var_63 + 0.6785714285714284921269268*var_177 + 0.0035714285714285713170535*var_402*var_7*var_8 + 0.1285714285714285587403083*var_132*var_20 + var_366 + 0.4214285714285714301574615*var_102*var_20 + 0.3714285714285714412596917*var_81 + 0.1553571428571428603149229*var_403; + A[28] = 3.0000000000000000000000000*var_404*var_76/(var_77*var_77*var_77); + A[238] = A[28]; + A[102] = A[45]; + A[144] = A[87]; + const double var_405 = 19.0000000000000000000000000*var_167 + 67.0000000000000000000000000*var_165; + const double var_406 = 0.0375000000000000055511151*var_18 + 0.0500000000000000027755576*var_70 + 0.4250000000000000444089210*var_86 + 0.3750000000000000000000000*var_164 + 1.3000000000000000444089210*var_141 + 0.4125000000000000333066907*var_34 + 0.2250000000000000055511151*var_42*var_62 + 0.8000000000000000444089210*var_183 + var_258 + var_238 + 2.0000000000000000000000000*var_298 + 0.0250000000000000013877788*var_1*var_3*var_405 + 0.4500000000000000111022302*var_68 + var_264; + A[43] = 0.4285714285714285476380780*var_406*var_76/(var_77*var_77*var_77); + A[62] = A[43]; + const double var_407 = 0.0964285714285714190552312*var_4*var_45; + A[268] = 0.0000000000000000000000000; + A[117] = 0.0000000000000000000000000; + A[104] = A[85]; + A[53] = 0.0000000000000000000000000; + A[288] = 0.0000000000000000000000000; + A[262] = 0.0000000000000000000000000; + A[320] = 0.0000000000000000000000000; + A[70] = 0.0000000000000000000000000; + const double var_408 = var_121 + var_87 + var_47; + const double var_409 = var_133 + var_126 + var_172; + const double var_410 = var_125 + var_228; + const double var_411 = 0.0035714285714285713170535*var_324 + 0.1000000000000000055511151*var_227 + 0.0428571428571428575393654*var_222 + 0.0321428571428571396850771*var_408 + 0.0357142857142857123031732*var_96 + 0.0071428571428571426341070*var_122 + 0.0928571428571428603149229*var_221 + 0.0607142857142857136909520*var_322 + 0.0857142857142857150787307*var_409 + 0.0785714285714285698425385*var_123 + 0.0642857142857142793701541*var_130 + 0.0285714285714285705364279*var_410; + A[64] = 13.5000000000000000000000000*var_411*var_76/(var_77*var_77*var_77); + const double var_412 = 0.1142857142857142821457117*var_177; + const double var_413 = 0.1642857142857142849212693*var_179 + var_268 + 0.1571428571428571396850771*var_183 + 0.2321428571428571230317317*var_277 + 0.1250000000000000000000000*var_35 + 0.0642857142857142793701541*var_68 + 0.1142857142857142821457117*var_46 + 0.1357142857142857039765005*var_180 + var_412 + 0.0821428571428571424606346*var_129 + 0.0053571428571428571924207*var_146 + var_376 + 0.0482142857142857095276156*var_20*var_62 + 0.2928571428571428714171532*var_176 + 0.0178571428571428561515866*var_145 + var_358 + 0.1392857142857142904723844*var_1*var_167*var_3 + 0.2642857142857142904723844*var_70 + 0.1071428571428571369095195*var_103 + 0.0285714285714285705364279*var_141 + 0.5000000000000000000000000*var_279; + A[3] = 3.0000000000000000000000000*var_413*var_76/(var_77*var_77*var_77); + A[270] = A[3]; + const double var_414 = var_46 + var_257; + const double var_415 = var_235 + 9.8500000000000014210854715*var_1*var_3*var_37 + 3.3000000000000002664535259*var_6 + 3.8000000000000002664535259*var_9 + 0.8250000000000000666133815*var_85 + 2.6500000000000003552713679*var_26 + 3.0000000000000000000000000*var_106 + 2.4750000000000000888178420*var_19*var_4 + 12.5000000000000000000000000*var_33 + 0.5000000000000000000000000*var_91 + 0.6500000000000000222044605*var_35 + 7.6750000000000007105427358*var_42*var_43 + 11.0000000000000000000000000*var_260 + var_51 + 2.1750000000000002664535259*var_414; + A[44] = 0.2142857142857142738190390*var_415*var_76/(var_77*var_77*var_77); + A[292] = A[44]; + A[361] = 0.0000000000000000000000000; + A[330] = A[6]; + A[230] = A[1]; + const double var_416 = var_257 + var_178 + var_141; + const double var_417 = var_131*var_4 + var_144 + var_297; + const double var_418 = var_333 + var_86; + const double var_419 = 1.0666666666666666518636930*var_417 + 0.4333333333333333481363070*var_91 + 0.3166666666666666518636930*var_187 + 1.3833333333333333037273860*var_183 + 0.7500000000000000000000000*var_418 + 0.9083333333333333259318465*var_106 + 0.2958333333333333370340767*var_111 + 0.4541666666666666629659233*var_416; + A[158] = 0.0000000000000000000000000; + A[309] = 0.0000000000000000000000000; + A[120] = A[6]; + A[25] = 3.0000000000000000000000000*var_377*var_76/(var_77*var_77*var_77); + A[235] = A[25]; + A[207] = 0.0000000000000000000000000; + A[345] = 0.0000000000000000000000000; + const double var_420 = 0.1285714285714285587403083*var_172; + const double var_421 = 0.0535714285714285684547598*var_4*var_62 + var_420; + const double var_422 = var_145 + var_117; + const double var_423 = 0.1142857142857142821457117*var_353 + 0.0714285714285714246063463*var_6 + 0.0250000000000000013877788*var_87 + var_273 + 0.0035714285714285713170535*var_141 + 0.3000000000000000444089210*var_196 + 0.0535714285714285684547598*var_32 + 0.0571428571428571410728559*var_179 + 0.1571428571428571396850771*var_248 + 0.1428571428571428492126927*var_180 + 0.0785714285714285698425385*var_186*var_7*var_8 + 0.1500000000000000222044605*var_168 + var_309 + 0.0428571428571428575393654*var_106 + var_208 + 0.0857142857142857150787307*var_103 + 0.0357142857142857123031732*var_250 + 0.0464285714285714301574615*var_85 + 0.2000000000000000111022302*var_183 + 0.0642857142857142793701541*var_129 + var_421 + 0.0500000000000000027755576*var_422; + A[149] = 27.0000000000000000000000000*var_423*var_76/(var_77*var_77*var_77); + A[187] = A[149]; + A[2] = 0.1428571428571428492126927*var_419*var_76/(var_77*var_77*var_77); + A[63] = 3.8571428571428567622092487*var_206*var_76/(var_77*var_77*var_77); + A[273] = A[63]; + A[174] = 0.0000000000000000000000000; + A[188] = A[169]; + A[116] = 0.0000000000000000000000000; + A[79] = 0.0000000000000000000000000; + const double var_424 = var_270 + var_141; + const double var_425 = var_251 + 0.7500000000000000000000000*var_18 + 7.2500000000000000000000000*var_179 + 7.7500000000000000000000000*var_177 + var_80 + 5.7500000000000000000000000*var_129 + 2.8750000000000000000000000*var_32 + var_363 + 2.0000000000000000000000000*var_71 + 6.7500000000000000000000000*var_344 + 1.5000000000000000000000000*var_168 + 2.4375000000000000000000000*var_34 + 1.1875000000000000000000000*var_118 + var_307 + 4.5625000000000000000000000*var_424; + A[163] = A[68]; + const double var_426 = var_145 + var_168; + const double var_427 = var_182 + 0.3571428571428571507873073*var_101 + 0.2214285714285714190552312*var_157 + var_211 + 0.0571428571428571410728559*var_20*var_60 + 0.1589285714285714190552312*var_42*var_62 + 0.1357142857142857039765005*var_207 + 0.2500000000000000000000000*var_9 + var_384 + 0.0285714285714285705364279*var_401 + 0.0464285714285714301574615*var_100 + 0.0428571428571428575393654*var_129 + 0.0142857142857142852682140*var_180 + 0.3857142857142856762209249*var_91 + 0.0964285714285714190552312*var_106 + 0.0732142857142857178542883*var_20*var_45; + A[168] = 27.0000000000000000000000000*var_427*var_76/(var_77*var_77*var_77); + A[378] = A[168]; + const double var_428 = 197.0000000000000000000000000*var_165 + 23.0000000000000000000000000*var_167; + A[314] = A[85]; + const double var_429 = var_35 + var_34; + const double var_430 = 0.2000000000000000111022302*var_216 + 0.0285714285714285705364279*var_364 + 0.1428571428571428492126927*var_183 + 0.0357142857142857123031732*var_192 + var_383 + 0.0267857142857142842273799*var_34 + 0.0250000000000000013877788*var_100 + var_412 + 0.1785714285714285753936537*var_71; + A[148] = 27.0000000000000000000000000*var_430*var_76/(var_77*var_77*var_77); + A[358] = A[148]; + A[357] = A[147]; + A[265] = 0.0000000000000000000000000; + const double var_431 = var_164 + var_93; + A[263] = 0.0000000000000000000000000; + A[81] = A[24]; + A[354] = A[87]; + A[283] = 0.0000000000000000000000000; + A[351] = A[27]; + A[128] = 0.9642857142857141905523122*var_388*var_76/(var_77*var_77*var_77); + const double var_432 = 0.0071428571428571426341070*var_277; + const double var_433 = var_70 + var_68; + const double var_434 = 0.1071428571428571369095195*var_357 + 0.0160714285714285698425385*var_19*var_4 + 0.0571428571428571410728559*var_433 + var_240 + var_385 + 0.0267857142857142842273799*var_81 + 0.1571428571428571396850771*var_296 + 0.0321428571428571396850771*var_32 + 0.0446428571428571438484134*var_350 + var_97 + 0.1000000000000000055511151*var_35 + var_432 + 0.0428571428571428575393654*var_13 + 0.0607142857142857136909520*var_34 + 0.0357142857142857123031732*var_29 + 0.0285714285714285705364279*var_101 + 0.0732142857142857178542883*var_18 + 0.0785714285714285698425385*var_382 + 0.1214285714285714273819039*var_9 + 0.1928571428571428381104624*var_23 + 0.0946428571428571396850771*var_42*var_43 + var_185; + A[10] = 0.0000000000000000000000000; + A[368] = 0.0000000000000000000000000; + const double var_435 = var_70 + var_306; + A[338] = A[128]; + A[59] = 0.0000000000000000000000000; + A[179] = 0.0000000000000000000000000; + const double var_436 = 0.0035714285714285713170535*var_1*var_3*var_428 + 0.5482142857142856540164644*var_19*var_42 + var_407 + 0.5964285714285714190552312*var_145 + 1.3000000000000000444089210*var_179 + 0.6785714285714284921269268*var_183 + 0.2053571428571428492126927*var_34 + 0.3714285714285714412596917*var_146 + 0.7857142857142856984253854*var_42*var_48 + 0.4214285714285714301574615*var_4*var_67 + 0.0500000000000000027755576*var_18 + 0.0357142857142857123031732*var_70 + var_390 + 0.1285714285714285587403083*var_137*var_4 + 0.1553571428571428603149229*var_431; + A[46] = 3.0000000000000000000000000*var_436*var_76/(var_77*var_77*var_77); + A[122] = A[46]; + A[243] = 0.0000000000000000000000000; + A[342] = 0.0000000000000000000000000; + A[248] = 0.0000000000000000000000000; + A[156] = 0.0000000000000000000000000; + A[194] = 0.0000000000000000000000000; + A[186] = A[129]; + A[304] = 0.0000000000000000000000000; + const double var_437 = var_155 + 0.3571428571428571507873073*var_400 + 0.0500000000000000027755576*var_68 + 0.0714285714285714246063463*var_183 + var_300 + 0.0285714285714285705364279*var_425; + A[86] = 27.0000000000000000000000000*var_437*var_76/(var_77*var_77*var_77); + A[359] = A[149]; + A[170] = 0.0000000000000000000000000; + A[74] = 0.0000000000000000000000000; + A[272] = A[43]; + A[297] = A[87]; + A[166] = A[128]; + A[140] = A[7]; + A[200] = 0.0000000000000000000000000; + A[239] = A[29]; + A[176] = 0.0000000000000000000000000; + A[371] = A[28]; + A[329] = 0.0000000000000000000000000; + A[4] = 3.0000000000000000000000000*var_361*var_76/(var_77*var_77*var_77); + A[214] = A[4]; + A[348] = 0.0000000000000000000000000; + A[155] = 0.0000000000000000000000000; + A[212] = A[2]; + A[105] = 27.0000000000000000000000000*var_434*var_76/(var_77*var_77*var_77); + A[315] = A[105]; + A[162] = A[48]; + A[223] = 0.0000000000000000000000000; + A[121] = A[26]; + A[372] = A[48]; + A[337] = A[127]; + A[385] = 0.0000000000000000000000000; + A[286] = 0.0000000000000000000000000; + A[386] = 0.0000000000000000000000000; + A[245] = 0.0000000000000000000000000; + A[222] = 0.0000000000000000000000000; + A[57] = 0.0000000000000000000000000; + const double var_438 = 0.0714285714285714246063463*var_134 + 0.2928571428571428714171532*var_91 + 0.0178571428571428561515866*var_100 + var_420 + 0.3142857142857142793701541*var_177 + 0.0357142857142857123031732*var_179 + var_209 + 0.3500000000000000333066907*var_183 + var_407 + var_94 + 1.5000000000000000000000000*var_396 + 0.0500000000000000027755576*var_87 + 0.4214285714285714301574615*var_6 + 0.2357142857142857095276156*var_103 + 0.1767857142857142682679239*var_117 + 0.5660714285714285587403083*var_106 + 0.2678571428571428492126927*var_186*var_7*var_8 + 0.0553571428571428547638078*var_19*var_42 + 0.5500000000000000444089210*var_180 + 0.1428571428571428492126927*var_378 + 0.4678571428571428603149229*var_86 + 0.2821428571428571396850771*var_129 + 0.3714285714285714412596917*var_85 + 0.2321428571428571230317317*var_82 + var_239 + 0.1750000000000000166533454*var_426; + A[5] = 3.0000000000000000000000000*var_438*var_76/(var_77*var_77*var_77); + A[215] = A[5]; + A[114] = 0.0000000000000000000000000; + A[152] = 0.0000000000000000000000000; + A[92] = 0.0000000000000000000000000; + A[363] = 0.0000000000000000000000000; + A[352] = A[47]; + const double var_439 = var_83 + var_29; + const double var_440 = 0.1500000000000000222044605*var_147 + var_97 + 0.1000000000000000055511151*var_439 + 0.0375000000000000055511151*var_106 + 0.2000000000000000111022302*var_30 + 0.2500000000000000000000000*var_120 + var_95; + A[65] = 3.8571428571428567622092487*var_440*var_76/(var_77*var_77*var_77); + A[275] = A[65]; + A[285] = 0.0000000000000000000000000; + A[313] = A[65]; + A[71] = 0.0000000000000000000000000; + A[289] = 0.0000000000000000000000000; + A[344] = 0.0000000000000000000000000; + A[281] = 0.0000000000000000000000000; + A[327] = 0.0000000000000000000000000; + A[255] = A[45]; + A[181] = A[29]; + A[131] = 0.0000000000000000000000000; + A[56] = 0.0000000000000000000000000; + A[366] = 0.0000000000000000000000000; + A[259] = A[49]; + A[203] = 0.0000000000000000000000000; + A[369] = 0.0000000000000000000000000; + A[60] = A[3]; + A[83] = A[64]; + A[195] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[38] = 0.0000000000000000000000000; + A[316] = A[106]; + A[99] = 0.0000000000000000000000000; + A[175] = 0.0000000000000000000000000; + A[253] = A[43]; + A[398] = A[169]; + A[274] = A[64]; + A[61] = A[23]; + A[227] = 0.0000000000000000000000000; + A[242] = 0.0000000000000000000000000; + A[339] = A[129]; + A[161] = A[28]; + A[97] = 0.0000000000000000000000000; + A[193] = 0.0000000000000000000000000; + A[224] = 0.0000000000000000000000000; + A[164] = A[88]; + A[233] = A[23]; + A[32] = 0.0000000000000000000000000; + const double var_441 = var_80 + var_18; + const double var_442 = 0.1142857142857142821457117*var_329 + 0.1571428571428571396850771*var_400 + 0.0428571428571428575393654*var_100 + var_432 + 0.0250000000000000013877788*var_47 + var_278 + 0.1500000000000000222044605*var_242 + 0.0642857142857142793701541*var_35 + 0.0464285714285714301574615*var_22 + 0.0857142857142857150787307*var_68 + 0.0035714285714285713170535*var_46 + 0.0357142857142857123031732*var_307 + 0.0571428571428571410728559*var_69 + 0.0785714285714285698425385*var_1*var_167*var_3 + 0.1428571428571428492126927*var_70 + 0.2000000000000000111022302*var_177 + 0.3000000000000000444089210*var_203 + 0.0714285714285714246063463*var_61 + var_371 + var_395 + 0.0535714285714285684547598*var_34 + 0.0500000000000000027755576*var_441; + A[109] = 27.0000000000000000000000000*var_442*var_76/(var_77*var_77*var_77); + A[185] = A[109]; + A[362] = 0.0000000000000000000000000; + A[318] = A[108]; + A[165] = A[108]; + A[41] = A[22]; + A[112] = 0.0000000000000000000000000; + A[279] = A[69]; + A[76] = 0.0000000000000000000000000; + A[370] = A[8]; + A[113] = 0.0000000000000000000000000; + A[247] = 0.0000000000000000000000000; + A[282] = 0.0000000000000000000000000; + A[353] = A[67]; + A[236] = A[26]; + A[135] = 0.0000000000000000000000000; + A[395] = A[109]; + A[225] = 0.0000000000000000000000000; + A[397] = A[149]; + const double var_443 = 0.1857142857142857206298459*var_435 + 0.0464285714285714301574615*var_4*var_43 + 3.0000000000000000000000000*var_284 + var_359 + 0.0250000000000000013877788*var_18 + 0.0785714285714285698425385*var_429 + 0.1000000000000000055511151*var_69 + 0.2714285714285714079530010*var_179 + 0.0678571428571428519882502*var_32 + 0.2285714285714285642914234*var_183 + 0.1500000000000000222044605*var_166 + 0.1714285714285714301574615*var_186*var_7*var_8 + var_286 + var_285 + var_421 + var_216 + 0.0857142857142857150787307*var_277 + 0.0285714285714285705364279*var_311; + A[89] = 27.0000000000000000000000000*var_443*var_76/(var_77*var_77*var_77); + A[299] = A[89]; + A[11] = 0.0000000000000000000000000; + A[139] = 0.0000000000000000000000000; + A[326] = 0.0000000000000000000000000; + A[159] = 0.0000000000000000000000000; + A[387] = 0.0000000000000000000000000; + A[130] = 0.0000000000000000000000000; + A[52] = 0.0000000000000000000000000; + A[84] = 3.8571428571428567622092487*var_200*var_76/(var_77*var_77*var_77); + A[220] = 0.0000000000000000000000000; + A[54] = 0.0000000000000000000000000; + A[322] = 0.0000000000000000000000000; + A[350] = A[7]; + A[364] = 0.0000000000000000000000000; + A[208] = 0.0000000000000000000000000; + A[298] = A[88]; + A[332] = A[46]; + A[35] = 0.0000000000000000000000000; + A[305] = 0.0000000000000000000000000; + A[257] = A[47]; + A[101] = A[25]; + A[198] = 0.0000000000000000000000000; + A[290] = A[4]; + A[183] = A[69]; + A[379] = A[169]; + A[256] = A[46]; + A[381] = 0.0000000000000000000000000; + A[190] = 0.0000000000000000000000000; + A[115] = 0.0000000000000000000000000; + A[124] = A[86]; + A[100] = A[5]; + A[291] = A[24]; + A[141] = A[27]; + A[75] = 0.0000000000000000000000000; + A[250] = A[2]; + A[197] = 0.0000000000000000000000000; + A[78] = 0.0000000000000000000000000; + A[178] = 0.0000000000000000000000000; + A[204] = 0.0000000000000000000000000; + A[126] = 27.0000000000000000000000000*var_387*var_76/(var_77*var_77*var_77); + A[347] = 0.0000000000000000000000000; + A[267] = 0.0000000000000000000000000; + A[157] = 0.0000000000000000000000000; + A[103] = A[65]; + A[367] = 0.0000000000000000000000000; + A[40] = A[2]; + A[206] = 0.0000000000000000000000000; + A[160] = A[8]; + A[184] = A[89]; + A[310] = A[5]; + A[72] = 0.0000000000000000000000000; + A[80] = A[4]; + A[205] = 0.0000000000000000000000000; + A[240] = 0.0000000000000000000000000; + A[91] = 0.0000000000000000000000000; + A[312] = A[45]; + A[232] = A[22]; + A[172] = 0.0000000000000000000000000; + A[319] = A[109]; + A[137] = 0.0000000000000000000000000; + A[241] = 0.0000000000000000000000000; + A[355] = A[107]; + A[280] = 0.0000000000000000000000000; + A[296] = A[86]; + A[246] = 0.0000000000000000000000000; + A[377] = A[148]; + A[277] = A[67]; + A[210] = A[0]; + A[73] = 0.0000000000000000000000000; + A[82] = A[44]; + A[16] = 0.0000000000000000000000000; + A[389] = 0.0000000000000000000000000; + A[336] = A[126]; + A[382] = 0.0000000000000000000000000; + A[343] = 0.0000000000000000000000000; + A[213] = A[3]; + A[125] = A[106]; + A[90] = 0.0000000000000000000000000; + A[394] = A[89]; + A[308] = 0.0000000000000000000000000; + A[278] = A[68]; + A[153] = 0.0000000000000000000000000; + A[19] = 0.0000000000000000000000000; + A[30] = 0.0000000000000000000000000; + A[396] = A[129]; + A[228] = 0.0000000000000000000000000; + A[93] = 0.0000000000000000000000000; + A[77] = 0.0000000000000000000000000; + A[376] = A[128]; + A[12] = 0.0000000000000000000000000; + A[334] = A[86]; + A[323] = 0.0000000000000000000000000; + A[167] = A[148]; + A[51] = 0.0000000000000000000000000; + A[98] = 0.0000000000000000000000000; + A[324] = 0.0000000000000000000000000; + A[123] = A[66]; + A[269] = 0.0000000000000000000000000; + A[244] = 0.0000000000000000000000000; + A[180] = A[9]; + A[133] = 0.0000000000000000000000000; + A[199] = 0.0000000000000000000000000; + A[254] = A[44]; + A[293] = A[64]; + A[196] = 0.0000000000000000000000000; + A[110] = 0.0000000000000000000000000; + A[294] = A[84]; + A[325] = 0.0000000000000000000000000; + A[216] = A[6]; + A[150] = 0.0000000000000000000000000; + A[33] = 0.0000000000000000000000000; + A[177] = 0.0000000000000000000000000; + A[34] = 0.0000000000000000000000000; + A[191] = 0.0000000000000000000000000; + A[384] = 0.0000000000000000000000000; + A[365] = 0.0000000000000000000000000; + A[301] = 0.0000000000000000000000000; + A[58] = 0.0000000000000000000000000; + A[14] = 0.0000000000000000000000000; + A[151] = 0.0000000000000000000000000; + A[321] = 0.0000000000000000000000000; + A[142] = A[47]; + A[311] = A[25]; + A[306] = 0.0000000000000000000000000; + A[119] = 0.0000000000000000000000000; + A[55] = 0.0000000000000000000000000; + A[154] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q3_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q3_quadrature.h new file mode 100644 index 0000000..7744d0f --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q3_quadrature.h @@ -0,0 +1,14349 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P2_Q3_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P2_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q3_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q3_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q3_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q3_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q3_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q3_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p2_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W7[7] = {0.1125, 0.0629695902724136, 0.0629695902724136, 0.0629695902724136, 0.0661970763942531, 0.0661970763942531, 0.0661970763942531}; + // Quadrature points on the UFC reference element: (0.333333333333333, 0.333333333333333), (0.797426985353087, 0.101286507323456), (0.101286507323456, 0.797426985353087), (0.101286507323456, 0.101286507323456), (0.0597158717897698, 0.470142064105115), (0.470142064105115, 0.0597158717897698), (0.470142064105115, 0.470142064105115) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[7][5] = \ + {{-0.333333333333333, 0.333333333333334, 1.33333333333333, 0.0, -1.33333333333333}, + {0.594853970706174, -0.594853970706174, 3.18970794141235, 0.0, -3.18970794141235}, + {0.594853970706175, 2.18970794141235, 0.405146029293824, -2.78456191211852, -0.405146029293825}, + {-2.18970794141235, -0.594853970706174, 0.405146029293825, 2.78456191211852, -0.405146029293825}, + {-0.880568256420461, 0.88056825642046, 0.238863487159079, 0.0, -0.238863487159079}, + {-0.88056825642046, -0.761136512840921, 1.88056825642046, 1.64170476926138, -1.88056825642046}, + {0.761136512840921, 0.88056825642046, 1.88056825642046, -1.64170476926138, -1.88056825642046}}; + + // Array of non-zero columns + static const unsigned int nzc4[5] = {6, 8, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc1[5] = {0, 2, 3, 4, 5}; + + static const double FE0_C0_D10[7][5] = \ + {{-0.333333333333333, 0.333333333333333, 1.33333333333333, -1.33333333333333, 0.0}, + {0.594853970706174, 2.18970794141235, 0.405146029293824, -0.405146029293824, -2.78456191211852}, + {0.594853970706175, -0.594853970706175, 3.18970794141235, -3.18970794141235, 0.0}, + {-2.18970794141235, -0.594853970706175, 0.405146029293824, -0.405146029293824, 2.78456191211852}, + {-0.880568256420461, -0.761136512840922, 1.88056825642046, -1.88056825642046, 1.64170476926138}, + {-0.88056825642046, 0.88056825642046, 0.238863487159078, -0.238863487159078, 0.0}, + {0.761136512840921, 0.88056825642046, 1.88056825642046, -1.88056825642046, -1.64170476926138}}; + + // Array of non-zero columns + static const unsigned int nzc5[5] = {6, 7, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc2[5] = {0, 1, 3, 4, 5}; + + static const double FE1_C0_D01[7][9] = \ + {{0.5, -0.5, 0.0, 1.5, -1.5, 1.5, -1.5, 0.0, 0.0}, + {-0.226917347726984, 0.226917347726984, 4.99609082499683, -1.40766939090794, -0.138495913638092, 0.138495913638091, 1.40766939090794, -4.99609082499683, 0.0}, + {-0.226917347726985, 2.40766939090794, -0.317293369317461, 1.7249627602254, 1.09037602159048, -3.27112806477143, 0.178797455679371, 0.317293369317461, -1.90376021590477}, + {-2.40766939090794, 0.226917347726985, -0.317293369317461, -0.178797455679372, 3.27112806477143, -1.09037602159048, -1.7249627602254, 0.317293369317461, 1.90376021590477}, + {0.247325510992291, -0.247325510992291, -0.220580620915199, 0.489302043969162, -2.98395306595374, 2.98395306595375, -0.489302043969162, 0.2205806209152, 0.0}, + {0.24732551099229, 0.510697956030836, 0.868313777480728, -1.35761582144989, 0.379011733511564, -1.13703520053469, -3.85226684343447, -0.868313777480728, 5.20988266488437}, + {-0.510697956030836, -0.247325510992291, 0.868313777480726, 3.85226684343447, 1.13703520053469, -0.379011733511561, 1.35761582144989, -0.868313777480726, -5.20988266488436}}; + + // Array of non-zero columns + static const unsigned int nzc10[9] = {10, 12, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc7[9] = {0, 2, 3, 4, 5, 6, 7, 8, 9}; + + static const double FE1_C0_D10[7][9] = \ + {{0.5, -0.5, 1.5, 0.0, -1.5, 0.0, -1.5, 1.5, 0.0}, + {-0.226917347726985, 2.40766939090794, 1.7249627602254, -0.317293369317461, 0.178797455679369, 0.317293369317462, 1.09037602159047, -3.27112806477143, -1.90376021590477}, + {-0.226917347726985, 0.226917347726985, -1.40766939090794, 4.99609082499683, 1.40766939090794, -4.99609082499683, -0.138495913638092, 0.13849591363809, 0.0}, + {-2.40766939090794, 0.226917347726985, -0.178797455679371, -0.317293369317462, -1.7249627602254, 0.317293369317462, 3.27112806477143, -1.09037602159048, 1.90376021590477}, + {0.24732551099229, 0.510697956030837, -1.35761582144989, 0.868313777480726, -3.85226684343447, -0.868313777480727, 0.379011733511565, -1.13703520053469, 5.20988266488436}, + {0.247325510992291, -0.247325510992291, 0.489302043969163, -0.2205806209152, -0.489302043969163, 0.2205806209152, -2.98395306595375, 2.98395306595375, 0.0}, + {-0.510697956030836, -0.247325510992291, 3.85226684343447, 0.86831377748073, 1.35761582144989, -0.868313777480728, 1.13703520053469, -0.379011733511563, -5.20988266488436}}; + + // Array of non-zero columns + static const unsigned int nzc11[9] = {10, 11, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc8[9] = {0, 1, 3, 4, 5, 6, 7, 8, 9}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 400; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 60. + double G[12]; + G[0] = K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 14056 + for (unsigned int ip = 0; ip < 7; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 40 + for (unsigned int r = 0; r < 5; r++) + { + F0 += FE0_C0_D10[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D10[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 24 + double I[3]; + // Number of operations: 8 + I[0] = W7[ip]*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 8 + I[1] = W7[ip]*(F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 8 + I[2] = W7[ip]*(F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 1944 + for (unsigned int j = 0; j < 9; j++) + { + for (unsigned int k = 0; k < 9; k++) + { + // Number of operations to compute entry: 3 + A[nzc10[j]*20 + nzc10[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc10[j]*20 + nzc11[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*20 + nzc10[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*20 + nzc11[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc7[j]*20 + nzc7[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc7[j]*20 + nzc8[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*20 + nzc7[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*20 + nzc8[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p2_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q3_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q3_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q3_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q3_tensor.h new file mode 100644 index 0000000..6e4daf6 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q3_tensor.h @@ -0,0 +1,14686 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P2_Q3_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P2_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q3_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q3_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q3_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q3_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q3_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q3_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p2_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 240 + // Number of operations (multiply-add pairs) for tensor contraction: 3959 + // Total number of operations (multiply-add pairs): 4210 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0 = det*(w[0][3]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1 = det*(w[0][3]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0 = det*(w[0][4]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1 = det*(w[0][4]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0 = det*(w[0][5]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1 = det*(w[0][5]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0 = det*(w[0][6]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1 = det*(w[0][6]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0 = det*(w[0][7]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1 = det*(w[0][8]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0 = det*(w[0][9]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1 = det*(w[0][9]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0 = det*(w[0][10]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1 = det*(w[0][10]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0 = det*(w[0][11]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1 = det*(w[0][11]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0 = det*(w[0][3]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1 = det*(w[0][3]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0 = det*(w[0][4]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1 = det*(w[0][4]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0 = det*(w[0][5]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1 = det*(w[0][5]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0 = det*(w[0][6]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1 = det*(w[0][6]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0 = det*(w[0][7]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1 = det*(w[0][8]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0 = det*(w[0][9]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1 = det*(w[0][9]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0 = det*(w[0][10]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1 = det*(w[0][10]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0 = det*(w[0][11]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1 = det*(w[0][11]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0 = det*(w[0][3]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1 = det*(w[0][3]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0 = det*(w[0][4]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1 = det*(w[0][4]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0 = det*(w[0][5]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1 = det*(w[0][5]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0 = det*(w[0][6]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1 = det*(w[0][6]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0 = det*(w[0][7]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1 = det*(w[0][8]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0 = det*(w[0][9]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1 = det*(w[0][9]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0 = det*(w[0][10]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1 = det*(w[0][10]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0 = det*(w[0][11]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1 = det*(w[0][11]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0 = det*(w[0][3]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1 = det*(w[0][3]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0 = det*(w[0][4]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1 = det*(w[0][4]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0 = det*(w[0][5]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1 = det*(w[0][5]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0 = det*(w[0][6]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1 = det*(w[0][6]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0 = det*(w[0][7]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1 = det*(w[0][8]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0 = det*(w[0][9]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1 = det*(w[0][9]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0 = det*(w[0][10]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1 = det*(w[0][10]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0 = det*(w[0][11]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1 = det*(w[0][11]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[143] = 0.578571428571428*G0_0_0_0_0_0 + 0.578571428571429*G0_0_0_0_0_1 + 0.385714285714285*G0_0_0_1_0_0 + 0.192857142857143*G0_0_0_2_0_1 + 0.192857142857142*G0_0_0_3_0_0 + 0.385714285714283*G0_0_0_3_0_1 - 0.192857142857142*G0_0_0_4_0_0 - 0.771428571428571*G0_0_0_4_0_1 - 0.964285714285713*G0_0_0_5_0_0 - 0.385714285714284*G0_0_0_5_0_1 + 0.578571428571428*G0_0_0_6_1_0 + 0.578571428571429*G0_0_0_6_1_1 + 0.385714285714285*G0_0_0_7_1_0 + 0.192857142857143*G0_0_0_8_1_1 + 0.192857142857142*G0_0_0_9_1_0 + 0.385714285714283*G0_0_0_9_1_1 - 0.192857142857142*G0_0_0_10_1_0 - 0.771428571428571*G0_0_0_10_1_1 - 0.964285714285713*G0_0_0_11_1_0 - 0.385714285714284*G0_0_0_11_1_1 + 0.554464285714284*G0_0_1_0_0_0 + 0.554464285714284*G0_0_1_0_0_1 + 0.699107142857139*G0_0_1_1_0_0 + 0.0241071428571434*G0_0_1_2_0_1 + 0.192857142857142*G0_0_1_3_0_0 + 0.867857142857138*G0_0_1_3_0_1 - 0.192857142857142*G0_0_1_4_0_0 - 0.578571428571428*G0_0_1_4_0_1 - 1.25357142857142*G0_0_1_5_0_0 - 0.867857142857138*G0_0_1_5_0_1 + 0.554464285714284*G0_0_1_6_1_0 + 0.554464285714284*G0_0_1_6_1_1 + 0.699107142857139*G0_0_1_7_1_0 + 0.0241071428571434*G0_0_1_8_1_1 + 0.192857142857142*G0_0_1_9_1_0 + 0.867857142857138*G0_0_1_9_1_1 - 0.192857142857142*G0_0_1_10_1_0 - 0.578571428571428*G0_0_1_10_1_1 - 1.25357142857142*G0_0_1_11_1_0 - 0.867857142857138*G0_0_1_11_1_1 + 0.458035714285713*G0_1_0_0_0_0 + 0.458035714285713*G0_1_0_0_0_1 + 0.409821428571427*G0_1_0_1_0_0 + 0.216964285714285*G0_1_0_2_0_1 + 0.385714285714284*G0_1_0_3_0_0 + 0.578571428571426*G0_1_0_3_0_1 - 0.385714285714284*G0_1_0_4_0_0 - 0.674999999999998*G0_1_0_4_0_1 - 0.86785714285714*G0_1_0_5_0_0 - 0.578571428571426*G0_1_0_5_0_1 + 0.458035714285713*G0_1_0_6_1_0 + 0.458035714285713*G0_1_0_6_1_1 + 0.409821428571427*G0_1_0_7_1_0 + 0.216964285714285*G0_1_0_8_1_1 + 0.385714285714284*G0_1_0_9_1_0 + 0.578571428571426*G0_1_0_9_1_1 - 0.385714285714284*G0_1_0_10_1_0 - 0.674999999999998*G0_1_0_10_1_1 - 0.86785714285714*G0_1_0_11_1_0 - 0.578571428571426*G0_1_0_11_1_1 + 0.433928571428571*G0_1_1_0_0_0 + 0.433928571428571*G0_1_1_0_0_1 + 0.819642857142854*G0_1_1_1_0_0 - 0.0482142857142849*G0_1_1_2_0_1 + 0.289285714285713*G0_1_1_3_0_0 + 1.15714285714285*G0_1_1_3_0_1 - 0.289285714285713*G0_1_1_4_0_0 - 0.385714285714286*G0_1_1_4_0_1 - 1.25357142857142*G0_1_1_5_0_0 - 1.15714285714285*G0_1_1_5_0_1 + 0.433928571428571*G0_1_1_6_1_0 + 0.433928571428571*G0_1_1_6_1_1 + 0.819642857142854*G0_1_1_7_1_0 - 0.0482142857142849*G0_1_1_8_1_1 + 0.289285714285713*G0_1_1_9_1_0 + 1.15714285714285*G0_1_1_9_1_1 - 0.289285714285713*G0_1_1_10_1_0 - 0.385714285714286*G0_1_1_10_1_1 - 1.25357142857142*G0_1_1_11_1_0 - 1.15714285714285*G0_1_1_11_1_1; + A[329] = 0.0; + A[384] = 0.0; + A[207] = 0.0; + A[17] = 0.0; + A[281] = 0.0; + A[304] = 0.0; + A[320] = 0.0; + A[353] = A[143]; + A[172] = 0.0; + A[178] = 0.0; + A[235] = 0.144642857142857*G0_0_0_0_0_0 + 0.144642857142857*G0_0_0_0_0_1 + 0.176785714285714*G0_0_0_1_0_0 - 0.0696428571428569*G0_0_0_2_0_1 - 0.107142857142857*G0_0_0_3_0_0 + 0.139285714285714*G0_0_0_3_0_1 + 0.107142857142857*G0_0_0_4_0_0 - 0.0750000000000003*G0_0_0_4_0_1 - 0.321428571428571*G0_0_0_5_0_0 - 0.139285714285714*G0_0_0_5_0_1 + 0.144642857142857*G0_0_0_6_1_0 + 0.144642857142857*G0_0_0_6_1_1 + 0.176785714285714*G0_0_0_7_1_0 - 0.0696428571428569*G0_0_0_8_1_1 - 0.107142857142857*G0_0_0_9_1_0 + 0.139285714285714*G0_0_0_9_1_1 + 0.107142857142857*G0_0_0_10_1_0 - 0.0750000000000003*G0_0_0_10_1_1 - 0.321428571428571*G0_0_0_11_1_0 - 0.139285714285714*G0_0_0_11_1_1 - 0.0535714285714287*G0_0_1_0_0_0 - 0.0535714285714286*G0_0_1_0_0_1 - 0.0535714285714285*G0_0_1_2_0_1 - 0.0535714285714285*G0_0_1_3_0_0 + 0.0535714285714285*G0_0_1_4_0_0 + 0.107142857142857*G0_0_1_4_0_1 + 0.0535714285714287*G0_0_1_5_0_0 - 0.0535714285714287*G0_0_1_6_1_0 - 0.0535714285714286*G0_0_1_6_1_1 - 0.0535714285714285*G0_0_1_8_1_1 - 0.0535714285714285*G0_0_1_9_1_0 + 0.0535714285714285*G0_0_1_10_1_0 + 0.107142857142857*G0_0_1_10_1_1 + 0.0535714285714287*G0_0_1_11_1_0; + A[199] = 0.0; + A[288] = 0.0; + A[248] = 0.0; + A[313] = A[143] - 0.626785714285715*G0_0_0_0_0_0 - 0.626785714285715*G0_0_0_0_0_1 - 0.3375*G0_0_0_1_0_0 + 0.0482142857142855*G0_0_0_2_0_1 + 0.385714285714286*G0_0_0_3_0_0 - 0.385714285714286*G0_0_0_4_0_0 + 0.57857142857143*G0_0_0_4_0_1 + 0.964285714285716*G0_0_0_5_0_0 - 0.626785714285715*G0_0_0_6_1_0 - 0.626785714285715*G0_0_0_6_1_1 - 0.3375*G0_0_0_7_1_0 + 0.0482142857142855*G0_0_0_8_1_1 + 0.385714285714286*G0_0_0_9_1_0 - 0.385714285714286*G0_0_0_10_1_0 + 0.57857142857143*G0_0_0_10_1_1 + 0.964285714285716*G0_0_0_11_1_0 - 0.578571428571427*G0_0_1_0_0_0 - 0.578571428571427*G0_0_1_0_0_1 - 0.578571428571426*G0_0_1_1_0_0 - 0.578571428571425*G0_0_1_3_0_1 + 0.578571428571427*G0_0_1_4_0_1 + 1.15714285714285*G0_0_1_5_0_0 + 0.578571428571426*G0_0_1_5_0_1 - 0.578571428571427*G0_0_1_6_1_0 - 0.578571428571427*G0_0_1_6_1_1 - 0.578571428571426*G0_0_1_7_1_0 - 0.578571428571425*G0_0_1_9_1_1 + 0.578571428571427*G0_0_1_10_1_1 + 1.15714285714285*G0_0_1_11_1_0 + 0.578571428571426*G0_0_1_11_1_1 - 0.385714285714285*G0_1_0_0_0_0 - 0.385714285714285*G0_1_0_0_0_1 - 0.385714285714285*G0_1_0_1_0_0 - 0.385714285714285*G0_1_0_3_0_1 + 0.385714285714284*G0_1_0_4_0_1 + 0.771428571428569*G0_1_0_5_0_0 + 0.385714285714285*G0_1_0_5_0_1 - 0.385714285714285*G0_1_0_6_1_0 - 0.385714285714285*G0_1_0_6_1_1 - 0.385714285714285*G0_1_0_7_1_0 - 0.385714285714285*G0_1_0_9_1_1 + 0.385714285714284*G0_1_0_10_1_1 + 0.771428571428569*G0_1_0_11_1_0 + 0.385714285714285*G0_1_0_11_1_1 - 0.3375*G0_1_1_0_0_0 - 0.3375*G0_1_1_0_0_1 - 0.819642857142854*G0_1_1_1_0_0 + 0.144642857142856*G0_1_1_2_0_1 - 0.192857142857142*G0_1_1_3_0_0 - 1.15714285714285*G0_1_1_3_0_1 + 0.192857142857142*G0_1_1_4_0_0 + 0.192857142857144*G0_1_1_4_0_1 + 1.15714285714285*G0_1_1_5_0_0 + 1.15714285714285*G0_1_1_5_0_1 - 0.3375*G0_1_1_6_1_0 - 0.3375*G0_1_1_6_1_1 - 0.819642857142854*G0_1_1_7_1_0 + 0.144642857142856*G0_1_1_8_1_1 - 0.192857142857142*G0_1_1_9_1_0 - 1.15714285714285*G0_1_1_9_1_1 + 0.192857142857142*G0_1_1_10_1_0 + 0.192857142857144*G0_1_1_10_1_1 + 1.15714285714285*G0_1_1_11_1_0 + 1.15714285714285*G0_1_1_11_1_1; + A[58] = 0.0; + A[14] = 0.0; + A[71] = 0.0; + A[35] = 0.0; + A[92] = 0.0; + A[52] = 0.0; + A[101] = A[235] + 0.0535714285714288*G0_0_1_0_0_0 + 0.0535714285714288*G0_0_1_0_0_1 + 0.0535714285714284*G0_0_1_2_0_1 + 0.0535714285714282*G0_0_1_3_0_0 - 0.0535714285714282*G0_0_1_4_0_0 - 0.107142857142857*G0_0_1_4_0_1 - 0.053571428571429*G0_0_1_5_0_0 + 0.0535714285714288*G0_0_1_6_1_0 + 0.0535714285714288*G0_0_1_6_1_1 + 0.0535714285714284*G0_0_1_8_1_1 + 0.0535714285714282*G0_0_1_9_1_0 - 0.0535714285714282*G0_0_1_10_1_0 - 0.107142857142857*G0_0_1_10_1_1 - 0.053571428571429*G0_0_1_11_1_0 - 0.0535714285714288*G0_1_0_0_0_0 - 0.0535714285714288*G0_1_0_0_0_1 - 0.0535714285714284*G0_1_0_2_0_1 - 0.0535714285714282*G0_1_0_3_0_0 + 0.0535714285714282*G0_1_0_4_0_0 + 0.107142857142857*G0_1_0_4_0_1 + 0.053571428571429*G0_1_0_5_0_0 - 0.0535714285714288*G0_1_0_6_1_0 - 0.0535714285714288*G0_1_0_6_1_1 - 0.0535714285714284*G0_1_0_8_1_1 - 0.0535714285714282*G0_1_0_9_1_0 + 0.0535714285714282*G0_1_0_10_1_0 + 0.107142857142857*G0_1_0_10_1_1 + 0.053571428571429*G0_1_0_11_1_0; + A[77] = 0.0; + A[327] = 0.0; + A[134] = 0.0; + A[346] = 0.0; + A[155] = 0.0; + A[365] = 0.0; + A[209] = 0.0; + A[224] = 0.0; + A[247] = 0.0; + A[266] = 0.0; + A[91] = 0.0; + A[110] = 0.0; + A[121] = A[101] - 0.128571428571429*G0_0_0_0_0_0 - 0.128571428571429*G0_0_0_0_0_1 - 0.128571428571429*G0_0_0_2_0_1 - 0.128571428571429*G0_0_0_3_0_0 + 0.128571428571429*G0_0_0_4_0_0 + 0.257142857142858*G0_0_0_4_0_1 + 0.128571428571428*G0_0_0_5_0_0 - 0.128571428571429*G0_0_0_6_1_0 - 0.128571428571429*G0_0_0_6_1_1 - 0.128571428571429*G0_0_0_8_1_1 - 0.128571428571429*G0_0_0_9_1_0 + 0.128571428571429*G0_0_0_10_1_0 + 0.257142857142858*G0_0_0_10_1_1 + 0.128571428571428*G0_0_0_11_1_0; + A[97] = 0.0; + A[381] = 0.0; + A[239] = -0.321428571428571*G0_0_0_0_0_0 - 0.321428571428572*G0_0_0_0_0_1 - 0.707142857142856*G0_0_0_1_0_0 + 0.385714285714285*G0_0_0_2_0_1 + 0.385714285714286*G0_0_0_3_0_0 - 0.707142857142856*G0_0_0_3_0_1 - 0.385714285714286*G0_0_0_4_0_0 - 0.0642857142857143*G0_0_0_4_0_1 + 1.02857142857143*G0_0_0_5_0_0 + 0.707142857142856*G0_0_0_5_0_1 - 0.321428571428571*G0_0_0_6_1_0 - 0.321428571428572*G0_0_0_6_1_1 - 0.707142857142856*G0_0_0_7_1_0 + 0.385714285714285*G0_0_0_8_1_1 + 0.385714285714286*G0_0_0_9_1_0 - 0.707142857142856*G0_0_0_9_1_1 - 0.385714285714286*G0_0_0_10_1_0 - 0.0642857142857143*G0_0_0_10_1_1 + 1.02857142857143*G0_0_0_11_1_0 + 0.707142857142856*G0_0_0_11_1_1 + 0.0642857142857144*G0_0_1_0_0_0 + 0.0642857142857144*G0_0_1_0_0_1 + 0.0642857142857138*G0_0_1_2_0_1 + 0.0642857142857143*G0_0_1_3_0_0 - 0.0642857142857143*G0_0_1_4_0_0 - 0.128571428571428*G0_0_1_4_0_1 - 0.0642857142857154*G0_0_1_5_0_0 + 0.0642857142857144*G0_0_1_6_1_0 + 0.0642857142857144*G0_0_1_6_1_1 + 0.0642857142857138*G0_0_1_8_1_1 + 0.0642857142857143*G0_0_1_9_1_0 - 0.0642857142857143*G0_0_1_10_1_0 - 0.128571428571428*G0_0_1_10_1_1 - 0.0642857142857154*G0_0_1_11_1_0; + A[379] = -A[239] + 0.642857142857142*G0_0_0_0_0_0 + 0.642857142857143*G0_0_0_0_0_1 + 0.642857142857142*G0_0_0_1_0_0 + 0.64285714285714*G0_0_0_3_0_1 - 0.642857142857142*G0_0_0_4_0_1 - 1.28571428571428*G0_0_0_5_0_0 - 0.64285714285714*G0_0_0_5_0_1 + 0.642857142857142*G0_0_0_6_1_0 + 0.642857142857143*G0_0_0_6_1_1 + 0.642857142857142*G0_0_0_7_1_0 + 0.64285714285714*G0_0_0_9_1_1 - 0.642857142857142*G0_0_0_10_1_1 - 1.28571428571428*G0_0_0_11_1_0 - 0.64285714285714*G0_0_0_11_1_1 - 0.46607142857143*G0_0_1_0_0_0 - 0.46607142857143*G0_0_1_0_0_1 + 1.10892857142857*G0_0_1_1_0_0 - 0.562500000000001*G0_0_1_2_0_1 + 0.449999999999999*G0_0_1_3_0_0 + 2.12142857142857*G0_0_1_3_0_1 - 0.449999999999999*G0_0_1_4_0_0 + 1.02857142857143*G0_0_1_4_0_1 - 0.642857142857142*G0_0_1_5_0_0 - 2.12142857142857*G0_0_1_5_0_1 - 0.46607142857143*G0_0_1_6_1_0 - 0.46607142857143*G0_0_1_6_1_1 + 1.10892857142857*G0_0_1_7_1_0 - 0.562500000000001*G0_0_1_8_1_1 + 0.449999999999999*G0_0_1_9_1_0 + 2.12142857142857*G0_0_1_9_1_1 - 0.449999999999999*G0_0_1_10_1_0 + 1.02857142857143*G0_0_1_10_1_1 - 0.642857142857142*G0_0_1_11_1_0 - 2.12142857142857*G0_0_1_11_1_1 + 0.43392857142857*G0_1_0_0_0_0 + 0.43392857142857*G0_1_0_0_0_1 + 1.49464285714285*G0_1_0_1_0_0 - 0.0482142857142853*G0_1_0_2_0_1 + 0.964285714285713*G0_1_0_3_0_0 + 2.50714285714285*G0_1_0_3_0_1 - 0.964285714285713*G0_1_0_4_0_0 - 0.385714285714284*G0_1_0_4_0_1 - 1.92857142857142*G0_1_0_5_0_0 - 2.50714285714285*G0_1_0_5_0_1 + 0.43392857142857*G0_1_0_6_1_0 + 0.43392857142857*G0_1_0_6_1_1 + 1.49464285714285*G0_1_0_7_1_0 - 0.0482142857142853*G0_1_0_8_1_1 + 0.964285714285713*G0_1_0_9_1_0 + 2.50714285714285*G0_1_0_9_1_1 - 0.964285714285713*G0_1_0_10_1_0 - 0.385714285714284*G0_1_0_10_1_1 - 1.92857142857142*G0_1_0_11_1_0 - 2.50714285714285*G0_1_0_11_1_1 + 0.385714285714285*G0_1_1_0_0_0 + 0.385714285714285*G0_1_1_0_0_1 + 0.385714285714286*G0_1_1_2_0_1 + 0.385714285714285*G0_1_1_3_0_0 - 0.385714285714285*G0_1_1_4_0_0 - 0.771428571428572*G0_1_1_4_0_1 - 0.385714285714282*G0_1_1_5_0_0 + 0.385714285714285*G0_1_1_6_1_0 + 0.385714285714285*G0_1_1_6_1_1 + 0.385714285714286*G0_1_1_8_1_1 + 0.385714285714285*G0_1_1_9_1_0 - 0.385714285714285*G0_1_1_10_1_0 - 0.771428571428572*G0_1_1_10_1_1 - 0.385714285714282*G0_1_1_11_1_0; + A[331] = A[121]; + A[138] = 0.0; + A[386] = 0.0; + A[205] = 0.0; + A[228] = 0.0; + A[19] = 0.0; + A[287] = 0.0; + A[259] = 0.0642857142857146*G0_1_0_0_0_0 + 0.0642857142857147*G0_1_0_0_0_1 + 0.0642857142857142*G0_1_0_1_0_0 + 0.0642857142857145*G0_1_0_3_0_1 - 0.0642857142857154*G0_1_0_4_0_1 - 0.128571428571429*G0_1_0_5_0_0 - 0.0642857142857145*G0_1_0_5_0_1 + 0.0642857142857146*G0_1_0_6_1_0 + 0.0642857142857147*G0_1_0_6_1_1 + 0.0642857142857142*G0_1_0_7_1_0 + 0.0642857142857145*G0_1_0_9_1_1 - 0.0642857142857154*G0_1_0_10_1_1 - 0.128571428571429*G0_1_0_11_1_0 - 0.0642857142857145*G0_1_0_11_1_1 - 0.321428571428572*G0_1_1_0_0_0 - 0.321428571428572*G0_1_1_0_0_1 + 0.385714285714286*G0_1_1_1_0_0 - 0.707142857142857*G0_1_1_2_0_1 - 0.707142857142857*G0_1_1_3_0_0 + 0.385714285714286*G0_1_1_3_0_1 + 0.707142857142857*G0_1_1_4_0_0 + 1.02857142857143*G0_1_1_4_0_1 - 0.0642857142857143*G0_1_1_5_0_0 - 0.385714285714286*G0_1_1_5_0_1 - 0.321428571428572*G0_1_1_6_1_0 - 0.321428571428572*G0_1_1_6_1_1 + 0.385714285714286*G0_1_1_7_1_0 - 0.707142857142857*G0_1_1_8_1_1 - 0.707142857142857*G0_1_1_9_1_0 + 0.385714285714286*G0_1_1_9_1_1 + 0.707142857142857*G0_1_1_10_1_0 + 1.02857142857143*G0_1_1_10_1_1 - 0.0642857142857143*G0_1_1_11_1_0 - 0.385714285714286*G0_1_1_11_1_1; + A[186] = -A[259] + 0.385714285714285*G0_0_0_0_0_0 + 0.385714285714285*G0_0_0_0_0_1 + 0.385714285714287*G0_0_0_1_0_0 + 0.385714285714286*G0_0_0_3_0_1 - 0.385714285714283*G0_0_0_4_0_1 - 0.771428571428572*G0_0_0_5_0_0 - 0.385714285714286*G0_0_0_5_0_1 + 0.385714285714285*G0_0_0_6_1_0 + 0.385714285714285*G0_0_0_6_1_1 + 0.385714285714287*G0_0_0_7_1_0 + 0.385714285714286*G0_0_0_9_1_1 - 0.385714285714283*G0_0_0_10_1_1 - 0.771428571428572*G0_0_0_11_1_0 - 0.385714285714286*G0_0_0_11_1_1 - 0.530357142857144*G0_0_1_0_0_0 - 0.530357142857145*G0_0_1_0_0_1 - 0.626785714285715*G0_0_1_1_0_0 + 1.10892857142857*G0_0_1_2_0_1 + 2.12142857142857*G0_0_1_3_0_0 + 0.385714285714284*G0_0_1_3_0_1 - 2.12142857142857*G0_0_1_4_0_0 - 0.578571428571424*G0_0_1_4_0_1 + 1.15714285714286*G0_0_1_5_0_0 - 0.385714285714283*G0_0_1_5_0_1 - 0.530357142857144*G0_0_1_6_1_0 - 0.530357142857145*G0_0_1_6_1_1 - 0.626785714285715*G0_0_1_7_1_0 + 1.10892857142857*G0_0_1_8_1_1 + 2.12142857142857*G0_0_1_9_1_0 + 0.385714285714284*G0_0_1_9_1_1 - 2.12142857142857*G0_0_1_10_1_0 - 0.578571428571424*G0_0_1_10_1_1 + 1.15714285714286*G0_0_1_11_1_0 - 0.385714285714283*G0_0_1_11_1_1 + 0.498214285714286*G0_1_0_0_0_0 + 0.498214285714286*G0_1_0_0_0_1 + 0.0160714285714286*G0_1_0_1_0_0 + 1.49464285714286*G0_1_0_2_0_1 + 2.50714285714286*G0_1_0_3_0_0 + 1.02857142857143*G0_1_0_3_0_1 - 2.50714285714286*G0_1_0_4_0_0 - 1.99285714285714*G0_1_0_4_0_1 - 0.514285714285714*G0_1_0_5_0_0 - 1.02857142857143*G0_1_0_5_0_1 + 0.498214285714286*G0_1_0_6_1_0 + 0.498214285714286*G0_1_0_6_1_1 + 0.0160714285714286*G0_1_0_7_1_0 + 1.49464285714286*G0_1_0_8_1_1 + 2.50714285714286*G0_1_0_9_1_0 + 1.02857142857143*G0_1_0_9_1_1 - 2.50714285714286*G0_1_0_10_1_0 - 1.99285714285714*G0_1_0_10_1_1 - 0.514285714285714*G0_1_0_11_1_0 - 1.02857142857143*G0_1_0_11_1_1 + 0.642857142857143*G0_1_1_0_0_0 + 0.642857142857143*G0_1_1_0_0_1 + 0.642857142857142*G0_1_1_2_0_1 + 0.642857142857141*G0_1_1_3_0_0 - 0.642857142857141*G0_1_1_4_0_0 - 1.28571428571428*G0_1_1_4_0_1 - 0.642857142857142*G0_1_1_5_0_0 + 0.642857142857143*G0_1_1_6_1_0 + 0.642857142857143*G0_1_1_6_1_1 + 0.642857142857142*G0_1_1_8_1_1 + 0.642857142857141*G0_1_1_9_1_0 - 0.642857142857141*G0_1_1_10_1_0 - 1.28571428571428*G0_1_1_10_1_1 - 0.642857142857142*G0_1_1_11_1_0; + A[310] = A[186] - 0.916071428571428*G0_0_0_0_0_0 - 0.916071428571428*G0_0_0_0_0_1 - 0.562500000000001*G0_0_0_1_0_0 - 0.316071428571426*G0_0_0_2_0_1 - 0.278571428571426*G0_0_0_3_0_0 - 0.525*G0_0_0_3_0_1 + 0.278571428571426*G0_0_0_4_0_0 + 1.23214285714285*G0_0_0_4_0_1 + 1.47857142857143*G0_0_0_5_0_0 + 0.525*G0_0_0_5_0_1 - 0.916071428571428*G0_0_0_6_1_0 - 0.916071428571428*G0_0_0_6_1_1 - 0.562500000000001*G0_0_0_7_1_0 - 0.316071428571426*G0_0_0_8_1_1 - 0.278571428571426*G0_0_0_9_1_0 - 0.525*G0_0_0_9_1_1 + 0.278571428571426*G0_0_0_10_1_0 + 1.23214285714285*G0_0_0_10_1_1 + 1.47857142857143*G0_0_0_11_1_0 + 0.525*G0_0_0_11_1_1 + 0.450000000000001*G0_0_1_1_0_0 - 1.425*G0_0_1_2_0_1 - 2.4*G0_0_1_3_0_0 - 0.524999999999997*G0_0_1_3_0_1 + 2.4*G0_0_1_4_0_0 + 1.425*G0_0_1_4_0_1 - 0.450000000000003*G0_0_1_5_0_0 + 0.524999999999997*G0_0_1_5_0_1 + 0.450000000000001*G0_0_1_7_1_0 - 1.425*G0_0_1_8_1_1 - 2.4*G0_0_1_9_1_0 - 0.524999999999997*G0_0_1_9_1_1 + 2.4*G0_0_1_10_1_0 + 1.425*G0_0_1_10_1_1 - 0.450000000000003*G0_0_1_11_1_0 + 0.524999999999997*G0_0_1_11_1_1 + 0.680357142857143*G0_1_0_0_0_0 + 0.680357142857143*G0_1_0_0_0_1 + 0.3375*G0_1_0_1_0_0 - 1.34464285714286*G0_1_0_2_0_1 - 3.03214285714286*G0_1_0_3_0_0 - 1.35*G0_1_0_3_0_1 + 3.03214285714286*G0_1_0_4_0_0 + 0.664285714285713*G0_1_0_4_0_1 - 1.01785714285714*G0_1_0_5_0_0 + 1.35*G0_1_0_5_0_1 + 0.680357142857143*G0_1_0_6_1_0 + 0.680357142857143*G0_1_0_6_1_1 + 0.3375*G0_1_0_7_1_0 - 1.34464285714286*G0_1_0_8_1_1 - 3.03214285714286*G0_1_0_9_1_0 - 1.35*G0_1_0_9_1_1 + 3.03214285714286*G0_1_0_10_1_0 + 0.664285714285713*G0_1_0_10_1_1 - 1.01785714285714*G0_1_0_11_1_0 + 1.35*G0_1_0_11_1_1 + 0.15*G0_1_1_0_0_0 + 0.15*G0_1_1_0_0_1 + 0.675000000000001*G0_1_1_1_0_0 - 1.2*G0_1_1_2_0_1 - 1.875*G0_1_1_3_0_0 + 1.875*G0_1_1_4_0_0 + 1.05*G0_1_1_4_0_1 - 0.825000000000002*G0_1_1_5_0_0 + 0.15*G0_1_1_6_1_0 + 0.15*G0_1_1_6_1_1 + 0.675000000000001*G0_1_1_7_1_0 - 1.2*G0_1_1_8_1_1 - 1.875*G0_1_1_9_1_0 + 1.875*G0_1_1_10_1_0 + 1.05*G0_1_1_10_1_1 - 0.825000000000002*G0_1_1_11_1_0; + A[180] = -A[310] + 0.176785714285714*G0_0_0_0_0_0 + 0.176785714285714*G0_0_0_0_0_1 + 0.144642857142857*G0_0_0_1_0_0 + 0.0696428571428568*G0_0_0_2_0_1 + 0.107142857142856*G0_0_0_3_0_0 + 0.182142857142857*G0_0_0_3_0_1 - 0.107142857142856*G0_0_0_4_0_0 - 0.246428571428571*G0_0_0_4_0_1 - 0.321428571428571*G0_0_0_5_0_0 - 0.182142857142856*G0_0_0_5_0_1 + 0.176785714285714*G0_0_0_6_1_0 + 0.176785714285714*G0_0_0_6_1_1 + 0.144642857142857*G0_0_0_7_1_0 + 0.0696428571428568*G0_0_0_8_1_1 + 0.107142857142856*G0_0_0_9_1_0 + 0.182142857142857*G0_0_0_9_1_1 - 0.107142857142856*G0_0_0_10_1_0 - 0.246428571428571*G0_0_0_10_1_1 - 0.321428571428571*G0_0_0_11_1_0 - 0.182142857142856*G0_0_0_11_1_1 + 0.176785714285714*G0_0_1_0_0_0 + 0.176785714285714*G0_0_1_0_0_1 + 0.144642857142857*G0_0_1_1_0_0 + 0.0696428571428568*G0_0_1_2_0_1 + 0.107142857142857*G0_0_1_3_0_0 + 0.182142857142856*G0_0_1_3_0_1 - 0.107142857142857*G0_0_1_4_0_0 - 0.246428571428571*G0_0_1_4_0_1 - 0.321428571428571*G0_0_1_5_0_0 - 0.182142857142856*G0_0_1_5_0_1 + 0.176785714285714*G0_0_1_6_1_0 + 0.176785714285714*G0_0_1_6_1_1 + 0.144642857142857*G0_0_1_7_1_0 + 0.0696428571428568*G0_0_1_8_1_1 + 0.107142857142857*G0_0_1_9_1_0 + 0.182142857142856*G0_0_1_9_1_1 - 0.107142857142857*G0_0_1_10_1_0 - 0.246428571428571*G0_0_1_10_1_1 - 0.321428571428571*G0_0_1_11_1_0 - 0.182142857142856*G0_0_1_11_1_1 + 1.82142857142857*G0_1_0_0_0_0 + 1.82142857142857*G0_1_0_0_0_1 + 0.675*G0_1_0_1_0_0 + 0.471428571428571*G0_1_0_2_0_1 - 0.203571428571429*G0_1_0_3_0_0 + 0.203571428571429*G0_1_0_4_0_0 - 2.29285714285714*G0_1_0_4_0_1 - 2.49642857142857*G0_1_0_5_0_0 + 1.82142857142857*G0_1_0_6_1_0 + 1.82142857142857*G0_1_0_6_1_1 + 0.675*G0_1_0_7_1_0 + 0.471428571428571*G0_1_0_8_1_1 - 0.203571428571429*G0_1_0_9_1_0 + 0.203571428571429*G0_1_0_10_1_0 - 2.29285714285714*G0_1_0_10_1_1 - 2.49642857142857*G0_1_0_11_1_0 + 1.82142857142857*G0_1_1_0_0_0 + 1.82142857142857*G0_1_1_0_0_1 + 0.675*G0_1_1_1_0_0 + 0.471428571428572*G0_1_1_2_0_1 - 0.203571428571429*G0_1_1_3_0_0 + 0.203571428571429*G0_1_1_4_0_0 - 2.29285714285714*G0_1_1_4_0_1 - 2.49642857142857*G0_1_1_5_0_0 + 1.82142857142857*G0_1_1_6_1_0 + 1.82142857142857*G0_1_1_6_1_1 + 0.675*G0_1_1_7_1_0 + 0.471428571428572*G0_1_1_8_1_1 - 0.203571428571429*G0_1_1_9_1_0 + 0.203571428571429*G0_1_1_10_1_0 - 2.29285714285714*G0_1_1_10_1_1 - 2.49642857142857*G0_1_1_11_1_0; + A[219] = A[180] + 0.0642857142857148*G0_0_1_1_0_0 - 0.0642857142857141*G0_0_1_2_0_1 - 0.0642857142857143*G0_0_1_3_0_0 + 0.0642857142857146*G0_0_1_3_0_1 + 0.0642857142857143*G0_0_1_4_0_0 + 0.0642857142857134*G0_0_1_4_0_1 - 0.0642857142857156*G0_0_1_5_0_0 - 0.0642857142857146*G0_0_1_5_0_1 + 0.0642857142857148*G0_0_1_7_1_0 - 0.0642857142857141*G0_0_1_8_1_1 - 0.0642857142857143*G0_0_1_9_1_0 + 0.0642857142857146*G0_0_1_9_1_1 + 0.0642857142857143*G0_0_1_10_1_0 + 0.0642857142857134*G0_0_1_10_1_1 - 0.0642857142857156*G0_0_1_11_1_0 - 0.0642857142857146*G0_0_1_11_1_1 - 0.0642857142857148*G0_1_0_1_0_0 + 0.0642857142857142*G0_1_0_2_0_1 + 0.0642857142857144*G0_1_0_3_0_0 - 0.0642857142857144*G0_1_0_3_0_1 - 0.0642857142857144*G0_1_0_4_0_0 - 0.0642857142857134*G0_1_0_4_0_1 + 0.0642857142857154*G0_1_0_5_0_0 + 0.0642857142857145*G0_1_0_5_0_1 - 0.0642857142857148*G0_1_0_7_1_0 + 0.0642857142857142*G0_1_0_8_1_1 + 0.0642857142857144*G0_1_0_9_1_0 - 0.0642857142857144*G0_1_0_9_1_1 - 0.0642857142857144*G0_1_0_10_1_0 - 0.0642857142857134*G0_1_0_10_1_1 + 0.0642857142857154*G0_1_0_11_1_0 + 0.0642857142857145*G0_1_0_11_1_1; + A[5] = A[310] + 1.64464285714286*G0_0_1_0_0_0 + 1.64464285714286*G0_0_1_0_0_1 + 0.466071428571429*G0_0_1_1_0_0 + 0.466071428571429*G0_0_1_2_0_1 - 0.246428571428571*G0_0_1_3_0_0 - 0.246428571428571*G0_0_1_3_0_1 + 0.246428571428571*G0_0_1_4_0_0 - 2.11071428571429*G0_0_1_4_0_1 - 2.11071428571429*G0_0_1_5_0_0 + 0.246428571428572*G0_0_1_5_0_1 + 1.64464285714286*G0_0_1_6_1_0 + 1.64464285714286*G0_0_1_6_1_1 + 0.466071428571429*G0_0_1_7_1_0 + 0.466071428571429*G0_0_1_8_1_1 - 0.246428571428571*G0_0_1_9_1_0 - 0.246428571428571*G0_0_1_9_1_1 + 0.246428571428571*G0_0_1_10_1_0 - 2.11071428571429*G0_0_1_10_1_1 - 2.11071428571429*G0_0_1_11_1_0 + 0.246428571428572*G0_0_1_11_1_1 - 1.64464285714286*G0_1_0_0_0_0 - 1.64464285714286*G0_1_0_0_0_1 - 0.466071428571429*G0_1_0_1_0_0 - 0.466071428571429*G0_1_0_2_0_1 + 0.246428571428571*G0_1_0_3_0_0 + 0.246428571428571*G0_1_0_3_0_1 - 0.246428571428571*G0_1_0_4_0_0 + 2.11071428571429*G0_1_0_4_0_1 + 2.11071428571429*G0_1_0_5_0_0 - 0.246428571428572*G0_1_0_5_0_1 - 1.64464285714286*G0_1_0_6_1_0 - 1.64464285714286*G0_1_0_6_1_1 - 0.466071428571429*G0_1_0_7_1_0 - 0.466071428571429*G0_1_0_8_1_1 + 0.246428571428571*G0_1_0_9_1_0 + 0.246428571428571*G0_1_0_9_1_1 - 0.246428571428571*G0_1_0_10_1_0 + 2.11071428571429*G0_1_0_10_1_1 + 2.11071428571429*G0_1_0_11_1_0 - 0.246428571428572*G0_1_0_11_1_1; + A[38] = 0.0; + A[306] = 0.0; + A[278] = -A[143] - 0.385714285714285*G0_0_0_1_0_0 + 0.385714285714285*G0_0_0_2_0_1 + 0.385714285714286*G0_0_0_3_0_0 - 0.385714285714285*G0_0_0_3_0_1 - 0.385714285714286*G0_0_0_4_0_0 - 0.385714285714286*G0_0_0_4_0_1 + 0.385714285714285*G0_0_0_5_0_0 + 0.385714285714286*G0_0_0_5_0_1 - 0.385714285714285*G0_0_0_7_1_0 + 0.385714285714285*G0_0_0_8_1_1 + 0.385714285714286*G0_0_0_9_1_0 - 0.385714285714285*G0_0_0_9_1_1 - 0.385714285714286*G0_0_0_10_1_0 - 0.385714285714286*G0_0_0_10_1_1 + 0.385714285714285*G0_0_0_11_1_0 + 0.385714285714286*G0_0_0_11_1_1 + 0.0964285714285711*G0_0_1_0_0_0 + 0.0964285714285709*G0_0_1_0_0_1 - 0.675000000000002*G0_0_1_1_0_0 + 0.0964285714285721*G0_0_1_2_0_1 - 0.578571428571428*G0_0_1_3_0_0 - 1.35*G0_0_1_3_0_1 + 0.578571428571428*G0_0_1_4_0_0 - 0.192857142857144*G0_0_1_4_0_1 + 0.578571428571431*G0_0_1_5_0_0 + 1.35*G0_0_1_5_0_1 + 0.0964285714285711*G0_0_1_6_1_0 + 0.0964285714285709*G0_0_1_6_1_1 - 0.675000000000002*G0_0_1_7_1_0 + 0.0964285714285721*G0_0_1_8_1_1 - 0.578571428571428*G0_0_1_9_1_0 - 1.35*G0_0_1_9_1_1 + 0.578571428571428*G0_0_1_10_1_0 - 0.192857142857144*G0_0_1_10_1_1 + 0.578571428571431*G0_0_1_11_1_0 + 1.35*G0_0_1_11_1_1 - 0.385714285714285*G0_1_0_0_0_0 - 0.385714285714285*G0_1_0_0_0_1 - 1.73571428571428*G0_1_0_1_0_0 + 0.674999999999998*G0_1_0_2_0_1 - 2.41071428571428*G0_1_0_3_0_1 - 0.289285714285714*G0_1_0_4_0_1 + 2.12142857142857*G0_1_0_5_0_0 + 2.41071428571428*G0_1_0_5_0_1 - 0.385714285714285*G0_1_0_6_1_0 - 0.385714285714285*G0_1_0_6_1_1 - 1.73571428571428*G0_1_0_7_1_0 + 0.674999999999998*G0_1_0_8_1_1 - 2.41071428571428*G0_1_0_9_1_1 - 0.289285714285714*G0_1_0_10_1_1 + 2.12142857142857*G0_1_0_11_1_0 + 2.41071428571428*G0_1_0_11_1_1 - 0.482142857142856*G0_1_1_0_0_0 - 0.482142857142856*G0_1_1_0_0_1 - 2.7*G0_1_1_1_0_0 + 0.867857142857142*G0_1_1_2_0_1 - 0.482142857142856*G0_1_1_3_0_0 - 4.05*G0_1_1_3_0_1 + 0.482142857142856*G0_1_1_4_0_0 - 0.385714285714288*G0_1_1_4_0_1 + 3.18214285714285*G0_1_1_5_0_0 + 4.05*G0_1_1_5_0_1 - 0.482142857142856*G0_1_1_6_1_0 - 0.482142857142856*G0_1_1_6_1_1 - 2.7*G0_1_1_7_1_0 + 0.867857142857142*G0_1_1_8_1_1 - 0.482142857142856*G0_1_1_9_1_0 - 4.05*G0_1_1_9_1_1 + 0.482142857142856*G0_1_1_10_1_0 - 0.385714285714288*G0_1_1_10_1_1 + 3.18214285714285*G0_1_1_11_1_0 + 4.05*G0_1_1_11_1_1; + A[189] = A[278] + 1.34999999999999*G0_0_0_1_0_0 + 2.7*G0_0_0_2_0_1 + 6.74999999999999*G0_0_0_3_0_0 + 5.39999999999999*G0_0_0_3_0_1 - 6.74999999999999*G0_0_0_4_0_0 - 2.69999999999999*G0_0_0_4_0_1 - 1.34999999999999*G0_0_0_5_0_0 - 5.39999999999999*G0_0_0_5_0_1 + 1.34999999999999*G0_0_0_7_1_0 + 2.7*G0_0_0_8_1_1 + 6.74999999999999*G0_0_0_9_1_0 + 5.39999999999999*G0_0_0_9_1_1 - 6.74999999999999*G0_0_0_10_1_0 - 2.69999999999999*G0_0_0_10_1_1 - 1.34999999999999*G0_0_0_11_1_0 - 5.39999999999999*G0_0_0_11_1_1 + 1.32589285714285*G0_0_1_0_0_0 + 1.32589285714285*G0_0_1_0_0_1 + 2.82053571428571*G0_0_1_1_0_0 + 1.37410714285714*G0_0_1_2_0_1 + 4.24285714285713*G0_0_1_3_0_0 + 5.68928571428571*G0_0_1_3_0_1 - 4.24285714285713*G0_0_1_4_0_0 - 2.69999999999999*G0_0_1_4_0_1 - 4.14642857142856*G0_0_1_5_0_0 - 5.68928571428571*G0_0_1_5_0_1 + 1.32589285714285*G0_0_1_6_1_0 + 1.32589285714285*G0_0_1_6_1_1 + 2.82053571428571*G0_0_1_7_1_0 + 1.37410714285714*G0_0_1_8_1_1 + 4.24285714285713*G0_0_1_9_1_0 + 5.68928571428571*G0_0_1_9_1_1 - 4.24285714285713*G0_0_1_10_1_0 - 2.69999999999999*G0_0_1_10_1_1 - 4.14642857142856*G0_0_1_11_1_0 - 5.68928571428571*G0_0_1_11_1_1 + 1.71160714285714*G0_1_0_0_0_0 + 1.71160714285714*G0_1_0_0_0_1 + 3.59196428571428*G0_1_0_1_0_0 + 0.988392857142855*G0_1_0_2_0_1 + 3.85714285714285*G0_1_0_3_0_0 + 6.46071428571427*G0_1_0_3_0_1 - 3.85714285714285*G0_1_0_4_0_0 - 2.69999999999999*G0_1_0_4_0_1 - 5.30357142857141*G0_1_0_5_0_0 - 6.46071428571427*G0_1_0_5_0_1 + 1.71160714285714*G0_1_0_6_1_0 + 1.71160714285714*G0_1_0_6_1_1 + 3.59196428571428*G0_1_0_7_1_0 + 0.988392857142855*G0_1_0_8_1_1 + 3.85714285714285*G0_1_0_9_1_0 + 6.46071428571427*G0_1_0_9_1_1 - 3.85714285714285*G0_1_0_10_1_0 - 2.69999999999999*G0_1_0_10_1_1 - 5.30357142857141*G0_1_0_11_1_0 - 6.46071428571427*G0_1_0_11_1_1 + 0.337499999999993*G0_1_1_0_0_0 + 0.337499999999994*G0_1_1_0_0_1 + 6.4125*G0_1_1_1_0_0 - 0.337500000000002*G0_1_1_2_0_1 + 5.39999999999999*G0_1_1_3_0_0 + 12.15*G0_1_1_3_0_1 - 5.39999999999999*G0_1_1_4_0_0 - 6.74999999999999*G0_1_1_5_0_0 - 12.15*G0_1_1_5_0_1 + 0.337499999999993*G0_1_1_6_1_0 + 0.337499999999994*G0_1_1_6_1_1 + 6.4125*G0_1_1_7_1_0 - 0.337500000000002*G0_1_1_8_1_1 + 5.39999999999999*G0_1_1_9_1_0 + 12.15*G0_1_1_9_1_1 - 5.39999999999999*G0_1_1_10_1_0 - 6.74999999999999*G0_1_1_11_1_0 - 12.15*G0_1_1_11_1_1; + A[273] = -A[278] + 0.144642857142857*G0_0_0_0_0_0 + 0.144642857142856*G0_0_0_0_0_1 + 0.433928571428571*G0_0_0_1_0_0 + 1.39821428571428*G0_0_0_2_0_1 + 3.08571428571428*G0_0_0_3_0_0 + 2.12142857142857*G0_0_0_3_0_1 - 3.08571428571428*G0_0_0_4_0_0 - 1.54285714285714*G0_0_0_4_0_1 - 0.578571428571427*G0_0_0_5_0_0 - 2.12142857142857*G0_0_0_5_0_1 + 0.144642857142857*G0_0_0_6_1_0 + 0.144642857142856*G0_0_0_6_1_1 + 0.433928571428571*G0_0_0_7_1_0 + 1.39821428571428*G0_0_0_8_1_1 + 3.08571428571428*G0_0_0_9_1_0 + 2.12142857142857*G0_0_0_9_1_1 - 3.08571428571428*G0_0_0_10_1_0 - 1.54285714285714*G0_0_0_10_1_1 - 0.578571428571427*G0_0_0_11_1_0 - 2.12142857142857*G0_0_0_11_1_1 - 0.385714285714285*G0_1_0_0_0_0 - 0.385714285714285*G0_1_0_0_0_1 - 0.771428571428568*G0_1_0_1_0_0 + 0.385714285714284*G0_1_0_2_0_1 + 0.385714285714286*G0_1_0_3_0_0 - 0.771428571428565*G0_1_0_3_0_1 - 0.385714285714286*G0_1_0_4_0_0 + 1.15714285714285*G0_1_0_5_0_0 + 0.771428571428567*G0_1_0_5_0_1 - 0.385714285714285*G0_1_0_6_1_0 - 0.385714285714285*G0_1_0_6_1_1 - 0.771428571428568*G0_1_0_7_1_0 + 0.385714285714284*G0_1_0_8_1_1 + 0.385714285714286*G0_1_0_9_1_0 - 0.771428571428565*G0_1_0_9_1_1 - 0.385714285714286*G0_1_0_10_1_0 + 1.15714285714285*G0_1_0_11_1_0 + 0.771428571428567*G0_1_0_11_1_1; + A[9] = A[219]; + A[322] = 0.0; + A[343] = 0.0; + A[156] = 0.0; + A[368] = 0.0; + A[174] = 0.0; + A[195] = 0.0; + A[221] = 0.0; + A[197] = 0.0; + A[56] = 0.0; + A[73] = 0.0; + A[33] = 0.0; + A[94] = 0.0; + A[50] = 0.0; + A[115] = 0.0; + A[79] = 0.0; + A[132] = 0.0; + A[344] = 0.0; + A[363] = 0.0; + A[226] = 0.0; + A[241] = 0.0; + A[264] = 0.0; + A[26] = A[235] - 0.128571428571429*G0_0_0_0_0_0 - 0.128571428571429*G0_0_0_0_0_1 - 0.128571428571429*G0_0_0_2_0_1 - 0.128571428571429*G0_0_0_3_0_0 + 0.128571428571429*G0_0_0_4_0_0 + 0.257142857142858*G0_0_0_4_0_1 + 0.128571428571428*G0_0_0_5_0_0 - 0.128571428571429*G0_0_0_6_1_0 - 0.128571428571429*G0_0_0_6_1_1 - 0.128571428571429*G0_0_0_8_1_1 - 0.128571428571429*G0_0_0_9_1_0 + 0.128571428571429*G0_0_0_10_1_0 + 0.257142857142858*G0_0_0_10_1_1 + 0.128571428571428*G0_0_0_11_1_0; + A[45] = 0.0964285714285712*G0_1_0_0_0_0 + 0.0964285714285711*G0_1_0_0_0_1 - 0.160714285714286*G0_1_0_1_0_0 + 0.557142857142856*G0_1_0_2_0_1 + 0.857142857142856*G0_1_0_3_0_0 + 0.139285714285714*G0_1_0_3_0_1 - 0.857142857142856*G0_1_0_4_0_0 - 0.653571428571427*G0_1_0_4_0_1 + 0.0642857142857146*G0_1_0_5_0_0 - 0.139285714285714*G0_1_0_5_0_1 + 0.0964285714285712*G0_1_0_6_1_0 + 0.0964285714285711*G0_1_0_6_1_1 - 0.160714285714286*G0_1_0_7_1_0 + 0.557142857142856*G0_1_0_8_1_1 + 0.857142857142856*G0_1_0_9_1_0 + 0.139285714285714*G0_1_0_9_1_1 - 0.857142857142856*G0_1_0_10_1_0 - 0.653571428571427*G0_1_0_10_1_1 + 0.0642857142857146*G0_1_0_11_1_0 - 0.139285714285714*G0_1_0_11_1_1 - 0.101785714285714*G0_1_1_0_0_0 - 0.101785714285714*G0_1_1_0_0_1 - 0.144642857142857*G0_1_1_1_0_0 + 0.380357142857142*G0_1_1_2_0_1 + 0.717857142857142*G0_1_1_3_0_0 + 0.192857142857143*G0_1_1_3_0_1 - 0.717857142857142*G0_1_1_4_0_0 - 0.278571428571428*G0_1_1_4_0_1 + 0.246428571428572*G0_1_1_5_0_0 - 0.192857142857143*G0_1_1_5_0_1 - 0.101785714285714*G0_1_1_6_1_0 - 0.101785714285714*G0_1_1_6_1_1 - 0.144642857142857*G0_1_1_7_1_0 + 0.380357142857142*G0_1_1_8_1_1 + 0.717857142857142*G0_1_1_9_1_0 + 0.192857142857143*G0_1_1_9_1_1 - 0.717857142857142*G0_1_1_10_1_0 - 0.278571428571428*G0_1_1_10_1_1 + 0.246428571428572*G0_1_1_11_1_0 - 0.192857142857143*G0_1_1_11_1_1; + A[108] = -A[313] - 0.433928571428573*G0_0_0_0_0_0 - 0.433928571428573*G0_0_0_0_0_1 - 0.530357142857144*G0_0_0_1_0_0 + 0.433928571428571*G0_0_0_2_0_1 + 0.771428571428571*G0_0_0_3_0_0 - 0.192857142857143*G0_0_0_3_0_1 - 0.771428571428571*G0_0_0_4_0_0 + 0.964285714285717*G0_0_0_5_0_0 + 0.192857142857143*G0_0_0_5_0_1 - 0.433928571428573*G0_0_0_6_1_0 - 0.433928571428573*G0_0_0_6_1_1 - 0.530357142857144*G0_0_0_7_1_0 + 0.433928571428571*G0_0_0_8_1_1 + 0.771428571428571*G0_0_0_9_1_0 - 0.192857142857143*G0_0_0_9_1_1 - 0.771428571428571*G0_0_0_10_1_0 + 0.964285714285717*G0_0_0_11_1_0 + 0.192857142857143*G0_0_0_11_1_1 + 0.385714285714285*G0_1_0_0_0_0 + 0.385714285714285*G0_1_0_0_0_1 + 0.385714285714285*G0_1_0_2_0_1 + 0.385714285714285*G0_1_0_3_0_0 - 0.385714285714285*G0_1_0_4_0_0 - 0.77142857142857*G0_1_0_4_0_1 - 0.385714285714284*G0_1_0_5_0_0 + 0.385714285714285*G0_1_0_6_1_0 + 0.385714285714285*G0_1_0_6_1_1 + 0.385714285714285*G0_1_0_8_1_1 + 0.385714285714285*G0_1_0_9_1_0 - 0.385714285714285*G0_1_0_10_1_0 - 0.77142857142857*G0_1_0_10_1_1 - 0.385714285714284*G0_1_0_11_1_0; + A[99] = 0.0; + A[118] = 0.0; + A[383] = 0.0; + A[282] = 0.0; + A[333] = A[313] + 0.0964285714285729*G0_0_0_0_0_0 + 0.0964285714285728*G0_0_0_0_0_1 - 0.482142857142856*G0_0_0_1_0_0 + 0.578571428571429*G0_0_0_2_0_1 + 0.578571428571428*G0_0_0_3_0_0 - 0.482142857142857*G0_0_0_3_0_1 - 0.578571428571428*G0_0_0_4_0_0 - 0.675000000000001*G0_0_0_4_0_1 + 0.385714285714284*G0_0_0_5_0_0 + 0.482142857142856*G0_0_0_5_0_1 + 0.0964285714285729*G0_0_0_6_1_0 + 0.0964285714285728*G0_0_0_6_1_1 - 0.482142857142856*G0_0_0_7_1_0 + 0.578571428571429*G0_0_0_8_1_1 + 0.578571428571428*G0_0_0_9_1_0 - 0.482142857142857*G0_0_0_9_1_1 - 0.578571428571428*G0_0_0_10_1_0 - 0.675000000000001*G0_0_0_10_1_1 + 0.385714285714284*G0_0_0_11_1_0 + 0.482142857142856*G0_0_0_11_1_1 + 0.0964285714285711*G0_0_1_0_0_0 + 0.096428571428571*G0_0_1_0_0_1 + 0.0964285714285704*G0_0_1_2_0_1 + 0.0964285714285705*G0_0_1_3_0_0 - 0.0964285714285705*G0_0_1_4_0_0 - 0.192857142857141*G0_0_1_4_0_1 - 0.0964285714285723*G0_0_1_5_0_0 + 0.0964285714285711*G0_0_1_6_1_0 + 0.096428571428571*G0_0_1_6_1_1 + 0.0964285714285704*G0_0_1_8_1_1 + 0.0964285714285705*G0_0_1_9_1_0 - 0.0964285714285705*G0_0_1_10_1_0 - 0.192857142857141*G0_0_1_10_1_1 - 0.0964285714285723*G0_0_1_11_1_0 + 0.192857142857144*G0_1_0_0_0_0 + 0.192857142857144*G0_1_0_0_0_1 + 0.192857142857144*G0_1_0_2_0_1 + 0.192857142857145*G0_1_0_3_0_0 - 0.192857142857145*G0_1_0_4_0_0 - 0.385714285714287*G0_1_0_4_0_1 - 0.192857142857145*G0_1_0_5_0_0 + 0.192857142857144*G0_1_0_6_1_0 + 0.192857142857144*G0_1_0_6_1_1 + 0.192857142857144*G0_1_0_8_1_1 + 0.192857142857145*G0_1_0_9_1_0 - 0.192857142857145*G0_1_0_10_1_0 - 0.385714285714287*G0_1_0_10_1_1 - 0.192857142857145*G0_1_0_11_1_0; + A[136] = 0.0; + A[388] = 0.0; + A[348] = 0.0; + A[169] = A[379]; + A[184] = -A[186] - 1.54285714285714*G0_0_1_0_0_0 - 1.54285714285714*G0_0_1_0_0_1 - 1.54285714285714*G0_0_1_1_0_0 - 1.54285714285714*G0_0_1_3_0_1 + 1.54285714285714*G0_0_1_4_0_1 + 3.08571428571429*G0_0_1_5_0_0 + 1.54285714285714*G0_0_1_5_0_1 - 1.54285714285714*G0_0_1_6_1_0 - 1.54285714285714*G0_0_1_6_1_1 - 1.54285714285714*G0_0_1_7_1_0 - 1.54285714285714*G0_0_1_9_1_1 + 1.54285714285714*G0_0_1_10_1_1 + 3.08571428571429*G0_0_1_11_1_0 + 1.54285714285714*G0_0_1_11_1_1 + 0.289285714285716*G0_1_1_0_0_0 + 0.289285714285716*G0_1_1_0_0_1 - 1.83214285714286*G0_1_1_1_0_0 + 0.0964285714285718*G0_1_1_2_0_1 - 1.92857142857143*G0_1_1_3_0_0 - 3.85714285714286*G0_1_1_3_0_1 + 1.92857142857143*G0_1_1_4_0_0 - 0.385714285714288*G0_1_1_4_0_1 + 1.54285714285714*G0_1_1_5_0_0 + 3.85714285714286*G0_1_1_5_0_1 + 0.289285714285716*G0_1_1_6_1_0 + 0.289285714285716*G0_1_1_6_1_1 - 1.83214285714286*G0_1_1_7_1_0 + 0.0964285714285718*G0_1_1_8_1_1 - 1.92857142857143*G0_1_1_9_1_0 - 3.85714285714286*G0_1_1_9_1_1 + 1.92857142857143*G0_1_1_10_1_0 - 0.385714285714288*G0_1_1_10_1_1 + 1.54285714285714*G0_1_1_11_1_0 + 3.85714285714286*G0_1_1_11_1_1; + A[299] = A[184] + 0.578571428571426*G0_0_1_0_0_0 + 0.578571428571427*G0_0_1_0_0_1 + 0.964285714285714*G0_0_1_1_0_0 - 0.385714285714289*G0_0_1_2_0_1 - 0.385714285714289*G0_0_1_3_0_0 + 0.964285714285712*G0_0_1_3_0_1 + 0.385714285714289*G0_0_1_4_0_0 - 0.192857142857139*G0_0_1_4_0_1 - 1.54285714285714*G0_0_1_5_0_0 - 0.964285714285711*G0_0_1_5_0_1 + 0.578571428571426*G0_0_1_6_1_0 + 0.578571428571427*G0_0_1_6_1_1 + 0.964285714285714*G0_0_1_7_1_0 - 0.385714285714289*G0_0_1_8_1_1 - 0.385714285714289*G0_0_1_9_1_0 + 0.964285714285712*G0_0_1_9_1_1 + 0.385714285714289*G0_0_1_10_1_0 - 0.192857142857139*G0_0_1_10_1_1 - 1.54285714285714*G0_0_1_11_1_0 - 0.964285714285711*G0_0_1_11_1_1 - 0.578571428571427*G0_1_0_0_0_0 - 0.578571428571427*G0_1_0_0_0_1 - 0.964285714285714*G0_1_0_1_0_0 + 0.385714285714289*G0_1_0_2_0_1 + 0.385714285714289*G0_1_0_3_0_0 - 0.964285714285712*G0_1_0_3_0_1 - 0.385714285714289*G0_1_0_4_0_0 + 0.192857142857139*G0_1_0_4_0_1 + 1.54285714285714*G0_1_0_5_0_0 + 0.964285714285711*G0_1_0_5_0_1 - 0.578571428571427*G0_1_0_6_1_0 - 0.578571428571427*G0_1_0_6_1_1 - 0.964285714285714*G0_1_0_7_1_0 + 0.385714285714289*G0_1_0_8_1_1 + 0.385714285714289*G0_1_0_9_1_0 - 0.964285714285712*G0_1_0_9_1_1 - 0.385714285714289*G0_1_0_10_1_0 + 0.192857142857139*G0_1_0_10_1_1 + 1.54285714285714*G0_1_0_11_1_0 + 0.964285714285711*G0_1_0_11_1_1; + A[203] = 0.0; + A[285] = 0.0; + A[253] = -A[45] - 0.0642857142857146*G0_1_0_0_0_0 - 0.0642857142857146*G0_1_0_0_0_1 - 0.0642857142857142*G0_1_0_1_0_0 - 0.0642857142857145*G0_1_0_3_0_1 + 0.0642857142857153*G0_1_0_4_0_1 + 0.128571428571429*G0_1_0_5_0_0 + 0.0642857142857144*G0_1_0_5_0_1 - 0.0642857142857146*G0_1_0_6_1_0 - 0.0642857142857146*G0_1_0_6_1_1 - 0.0642857142857142*G0_1_0_7_1_0 - 0.0642857142857145*G0_1_0_9_1_1 + 0.0642857142857153*G0_1_0_10_1_1 + 0.128571428571429*G0_1_0_11_1_0 + 0.0642857142857144*G0_1_0_11_1_1 - 0.117857142857143*G0_1_1_0_0_0 - 0.117857142857143*G0_1_1_0_0_1 + 0.053571428571428*G0_1_1_1_0_0 + 0.203571428571429*G0_1_1_2_0_1 + 0.578571428571428*G0_1_1_3_0_0 + 0.428571428571428*G0_1_1_3_0_1 - 0.578571428571428*G0_1_1_4_0_0 - 0.0857142857142854*G0_1_1_4_0_1 + 0.0642857142857151*G0_1_1_5_0_0 - 0.428571428571428*G0_1_1_5_0_1 - 0.117857142857143*G0_1_1_6_1_0 - 0.117857142857143*G0_1_1_6_1_1 + 0.053571428571428*G0_1_1_7_1_0 + 0.203571428571429*G0_1_1_8_1_1 + 0.578571428571428*G0_1_1_9_1_0 + 0.428571428571428*G0_1_1_9_1_1 - 0.578571428571428*G0_1_1_10_1_0 - 0.0857142857142854*G0_1_1_10_1_1 + 0.0642857142857151*G0_1_1_11_1_0 - 0.428571428571428*G0_1_1_11_1_1; + A[36] = 0.0; + A[300] = 0.0; + A[276] = A[333] + 0.192857142857144*G0_0_1_0_0_0 + 0.192857142857144*G0_0_1_0_0_1 - 0.0964285714285711*G0_0_1_1_0_0 + 0.289285714285716*G0_0_1_2_0_1 + 0.289285714285717*G0_0_1_3_0_0 - 0.0964285714285703*G0_0_1_3_0_1 - 0.289285714285717*G0_0_1_4_0_0 - 0.482142857142859*G0_0_1_4_0_1 - 0.0964285714285726*G0_0_1_5_0_0 + 0.0964285714285703*G0_0_1_5_0_1 + 0.192857142857144*G0_0_1_6_1_0 + 0.192857142857144*G0_0_1_6_1_1 - 0.0964285714285711*G0_0_1_7_1_0 + 0.289285714285716*G0_0_1_8_1_1 + 0.289285714285717*G0_0_1_9_1_0 - 0.0964285714285703*G0_0_1_9_1_1 - 0.289285714285717*G0_0_1_10_1_0 - 0.482142857142859*G0_0_1_10_1_1 - 0.0964285714285726*G0_0_1_11_1_0 + 0.0964285714285703*G0_0_1_11_1_1 - 0.192857142857144*G0_1_0_0_0_0 - 0.192857142857144*G0_1_0_0_0_1 + 0.0964285714285711*G0_1_0_1_0_0 - 0.289285714285716*G0_1_0_2_0_1 - 0.289285714285717*G0_1_0_3_0_0 + 0.0964285714285703*G0_1_0_3_0_1 + 0.289285714285717*G0_1_0_4_0_0 + 0.482142857142859*G0_1_0_4_0_1 + 0.0964285714285725*G0_1_0_5_0_0 - 0.0964285714285703*G0_1_0_5_0_1 - 0.192857142857144*G0_1_0_6_1_0 - 0.192857142857144*G0_1_0_6_1_1 + 0.0964285714285711*G0_1_0_7_1_0 - 0.289285714285716*G0_1_0_8_1_1 - 0.289285714285717*G0_1_0_9_1_0 + 0.0964285714285703*G0_1_0_9_1_1 + 0.289285714285717*G0_1_0_10_1_0 + 0.482142857142859*G0_1_0_10_1_1 + 0.0964285714285725*G0_1_0_11_1_0 - 0.0964285714285703*G0_1_0_11_1_1; + A[64] = -A[276] + 0.819642857142857*G0_0_1_0_0_0 + 0.819642857142857*G0_0_1_0_0_1 + 0.723214285714286*G0_0_1_1_0_0 + 1.10892857142857*G0_0_1_2_0_1 + 2.12142857142857*G0_0_1_3_0_0 + 1.73571428571429*G0_0_1_3_0_1 - 2.12142857142857*G0_0_1_4_0_0 - 1.92857142857143*G0_0_1_4_0_1 - 1.54285714285714*G0_0_1_5_0_0 - 1.73571428571429*G0_0_1_5_0_1 + 0.819642857142857*G0_0_1_6_1_0 + 0.819642857142857*G0_0_1_6_1_1 + 0.723214285714286*G0_0_1_7_1_0 + 1.10892857142857*G0_0_1_8_1_1 + 2.12142857142857*G0_0_1_9_1_0 + 1.73571428571429*G0_0_1_9_1_1 - 2.12142857142857*G0_0_1_10_1_0 - 1.92857142857143*G0_0_1_10_1_1 - 1.54285714285714*G0_0_1_11_1_0 - 1.73571428571429*G0_0_1_11_1_1 + 0.0482142857142864*G0_1_1_0_0_0 + 0.0482142857142861*G0_1_1_0_0_1 - 0.819642857142855*G0_1_1_1_0_0 + 0.530357142857142*G0_1_1_2_0_1 + 0.192857142857144*G0_1_1_3_0_0 - 1.15714285714285*G0_1_1_3_0_1 - 0.192857142857144*G0_1_1_4_0_0 - 0.578571428571429*G0_1_1_4_0_1 + 0.771428571428569*G0_1_1_5_0_0 + 1.15714285714285*G0_1_1_5_0_1 + 0.0482142857142864*G0_1_1_6_1_0 + 0.0482142857142861*G0_1_1_6_1_1 - 0.819642857142855*G0_1_1_7_1_0 + 0.530357142857142*G0_1_1_8_1_1 + 0.192857142857144*G0_1_1_9_1_0 - 1.15714285714285*G0_1_1_9_1_1 - 0.192857142857144*G0_1_1_10_1_0 - 0.578571428571429*G0_1_1_10_1_1 + 0.771428571428569*G0_1_1_11_1_0 + 1.15714285714285*G0_1_1_11_1_1; + A[11] = 0.0; + A[66] = A[276]; + A[30] = 0.0; + A[81] = -A[121] - 0.214285714285714*G0_1_0_0_0_0 - 0.214285714285714*G0_1_0_0_0_1 - 0.557142857142856*G0_1_0_1_0_0 + 0.0428571428571425*G0_1_0_2_0_1 - 0.257142857142857*G0_1_0_3_0_0 - 0.857142857142856*G0_1_0_3_0_1 + 0.257142857142857*G0_1_0_4_0_0 + 0.171428571428571*G0_1_0_4_0_1 + 0.77142857142857*G0_1_0_5_0_0 + 0.857142857142856*G0_1_0_5_0_1 - 0.214285714285714*G0_1_0_6_1_0 - 0.214285714285714*G0_1_0_6_1_1 - 0.557142857142856*G0_1_0_7_1_0 + 0.0428571428571425*G0_1_0_8_1_1 - 0.257142857142857*G0_1_0_9_1_0 - 0.857142857142856*G0_1_0_9_1_1 + 0.257142857142857*G0_1_0_10_1_0 + 0.171428571428571*G0_1_0_10_1_1 + 0.77142857142857*G0_1_0_11_1_0 + 0.857142857142856*G0_1_0_11_1_1; + A[324] = 0.0; + A[131] = 0.0; + A[341] = 0.0; + A[158] = 0.0; + A[366] = 0.0; + A[193] = 0.0; + A[223] = 0.0; + A[244] = 0.0; + A[309] = 0.0; + A[269] = 0.0; + A[75] = 0.0; + A[48] = -A[253] - 0.214285714285714*G0_1_0_0_0_0 - 0.214285714285714*G0_1_0_0_0_1 + 0.0428571428571433*G0_1_0_1_0_0 - 0.557142857142858*G0_1_0_2_0_1 - 0.857142857142857*G0_1_0_3_0_0 - 0.257142857142857*G0_1_0_3_0_1 + 0.857142857142857*G0_1_0_4_0_0 + 0.771428571428572*G0_1_0_4_0_1 + 0.171428571428571*G0_1_0_5_0_0 + 0.257142857142857*G0_1_0_5_0_1 - 0.214285714285714*G0_1_0_6_1_0 - 0.214285714285714*G0_1_0_6_1_1 + 0.0428571428571433*G0_1_0_7_1_0 - 0.557142857142858*G0_1_0_8_1_1 - 0.857142857142857*G0_1_0_9_1_0 - 0.257142857142857*G0_1_0_9_1_1 + 0.857142857142857*G0_1_0_10_1_0 + 0.771428571428572*G0_1_0_10_1_1 + 0.171428571428571*G0_1_0_11_1_0 + 0.257142857142857*G0_1_0_11_1_1; + A[257] = A[48] + 0.128571428571428*G0_1_1_0_0_0 + 0.128571428571428*G0_1_1_0_0_1 + 0.128571428571428*G0_1_1_1_0_0 + 0.128571428571428*G0_1_1_3_0_1 - 0.128571428571429*G0_1_1_4_0_1 - 0.257142857142856*G0_1_1_5_0_0 - 0.128571428571428*G0_1_1_5_0_1 + 0.128571428571428*G0_1_1_6_1_0 + 0.128571428571428*G0_1_1_6_1_1 + 0.128571428571428*G0_1_1_7_1_0 + 0.128571428571428*G0_1_1_9_1_1 - 0.128571428571429*G0_1_1_10_1_1 - 0.257142857142856*G0_1_1_11_1_0 - 0.128571428571428*G0_1_1_11_1_1; + A[214] = A[257] - 0.176785714285715*G0_0_0_0_0_0 - 0.176785714285714*G0_0_0_0_0_1 - 0.0160714285714287*G0_0_0_1_0_0 - 0.198214285714286*G0_0_0_2_0_1 - 0.235714285714285*G0_0_0_3_0_0 - 0.0535714285714285*G0_0_0_3_0_1 + 0.235714285714285*G0_0_0_4_0_0 + 0.375*G0_0_0_4_0_1 + 0.192857142857143*G0_0_0_5_0_0 + 0.0535714285714285*G0_0_0_5_0_1 - 0.176785714285715*G0_0_0_6_1_0 - 0.176785714285714*G0_0_0_6_1_1 - 0.0160714285714287*G0_0_0_7_1_0 - 0.198214285714286*G0_0_0_8_1_1 - 0.235714285714285*G0_0_0_9_1_0 - 0.0535714285714285*G0_0_0_9_1_1 + 0.235714285714285*G0_0_0_10_1_0 + 0.375*G0_0_0_10_1_1 + 0.192857142857143*G0_0_0_11_1_0 + 0.0535714285714285*G0_0_0_11_1_1 - 0.176785714285715*G0_0_1_0_0_0 - 0.176785714285715*G0_0_1_0_0_1 - 0.0696428571428571*G0_0_1_1_0_0 - 0.144642857142857*G0_0_1_2_0_1 - 0.182142857142857*G0_0_1_3_0_0 - 0.107142857142857*G0_0_1_3_0_1 + 0.182142857142857*G0_0_1_4_0_0 + 0.321428571428572*G0_0_1_4_0_1 + 0.246428571428572*G0_0_1_5_0_0 + 0.107142857142857*G0_0_1_5_0_1 - 0.176785714285715*G0_0_1_6_1_0 - 0.176785714285715*G0_0_1_6_1_1 - 0.0696428571428571*G0_0_1_7_1_0 - 0.144642857142857*G0_0_1_8_1_1 - 0.182142857142857*G0_0_1_9_1_0 - 0.107142857142857*G0_0_1_9_1_1 + 0.182142857142857*G0_0_1_10_1_0 + 0.321428571428572*G0_0_1_10_1_1 + 0.246428571428572*G0_0_1_11_1_0 + 0.107142857142857*G0_0_1_11_1_1 - 0.123214285714286*G0_1_0_0_0_0 - 0.123214285714286*G0_1_0_0_0_1 + 0.0374999999999999*G0_1_0_1_0_0 - 0.198214285714286*G0_1_0_2_0_1 - 0.235714285714286*G0_1_0_3_0_0 + 0.235714285714286*G0_1_0_4_0_0 + 0.321428571428572*G0_1_0_4_0_1 + 0.0857142857142861*G0_1_0_5_0_0 - 0.123214285714286*G0_1_0_6_1_0 - 0.123214285714286*G0_1_0_6_1_1 + 0.0374999999999999*G0_1_0_7_1_0 - 0.198214285714286*G0_1_0_8_1_1 - 0.235714285714286*G0_1_0_9_1_0 + 0.235714285714286*G0_1_0_10_1_0 + 0.321428571428572*G0_1_0_10_1_1 + 0.0857142857142861*G0_1_0_11_1_0 - 0.321428571428572*G0_1_1_0_0_0 - 0.321428571428572*G0_1_1_0_0_1 - 0.321428571428572*G0_1_1_2_0_1 - 0.321428571428571*G0_1_1_3_0_0 + 0.321428571428571*G0_1_1_4_0_0 + 0.642857142857143*G0_1_1_4_0_1 + 0.321428571428572*G0_1_1_5_0_0 - 0.321428571428572*G0_1_1_6_1_0 - 0.321428571428572*G0_1_1_6_1_1 - 0.321428571428572*G0_1_1_8_1_1 - 0.321428571428571*G0_1_1_9_1_0 + 0.321428571428571*G0_1_1_10_1_0 + 0.642857142857143*G0_1_1_10_1_1 + 0.321428571428572*G0_1_1_11_1_0; + A[47] = A[257]; + A[162] = A[48] - 0.0535714285714287*G0_0_1_0_0_0 - 0.0535714285714287*G0_0_1_0_0_1 - 0.0535714285714282*G0_0_1_1_0_0 - 0.0535714285714284*G0_0_1_3_0_1 + 0.0535714285714294*G0_0_1_4_0_1 + 0.107142857142857*G0_0_1_5_0_0 + 0.0535714285714284*G0_0_1_5_0_1 - 0.0535714285714287*G0_0_1_6_1_0 - 0.0535714285714287*G0_0_1_6_1_1 - 0.0535714285714282*G0_0_1_7_1_0 - 0.0535714285714284*G0_0_1_9_1_1 + 0.0535714285714294*G0_0_1_10_1_1 + 0.107142857142857*G0_0_1_11_1_0 + 0.0535714285714284*G0_0_1_11_1_1 + 0.0535714285714287*G0_1_0_0_0_0 + 0.0535714285714287*G0_1_0_0_0_1 + 0.0535714285714282*G0_1_0_1_0_0 + 0.0535714285714284*G0_1_0_3_0_1 - 0.0535714285714294*G0_1_0_4_0_1 - 0.107142857142857*G0_1_0_5_0_0 - 0.0535714285714284*G0_1_0_5_0_1 + 0.0535714285714287*G0_1_0_6_1_0 + 0.0535714285714287*G0_1_0_6_1_1 + 0.0535714285714282*G0_1_0_7_1_0 + 0.0535714285714284*G0_1_0_9_1_1 - 0.0535714285714294*G0_1_0_10_1_1 - 0.107142857142857*G0_1_0_11_1_0 - 0.0535714285714284*G0_1_0_11_1_1; + A[62] = -A[162] - 0.214285714285714*G0_0_1_0_0_0 - 0.214285714285714*G0_0_1_0_0_1 + 0.0428571428571434*G0_0_1_1_0_0 - 0.557142857142858*G0_0_1_2_0_1 - 0.857142857142857*G0_0_1_3_0_0 - 0.257142857142857*G0_0_1_3_0_1 + 0.857142857142857*G0_0_1_4_0_0 + 0.771428571428572*G0_0_1_4_0_1 + 0.171428571428571*G0_0_1_5_0_0 + 0.257142857142857*G0_0_1_5_0_1 - 0.214285714285714*G0_0_1_6_1_0 - 0.214285714285714*G0_0_1_6_1_1 + 0.0428571428571434*G0_0_1_7_1_0 - 0.557142857142858*G0_0_1_8_1_1 - 0.857142857142857*G0_0_1_9_1_0 - 0.257142857142857*G0_0_1_9_1_1 + 0.857142857142857*G0_0_1_10_1_0 + 0.771428571428572*G0_0_1_10_1_1 + 0.171428571428571*G0_0_1_11_1_0 + 0.257142857142857*G0_0_1_11_1_1; + A[113] = 0.0; + A[151] = 0.0; + A[361] = 0.0; + A[243] = 0.0; + A[262] = 0.0; + A[24] = -A[26] - 0.214285714285714*G0_0_1_0_0_0 - 0.214285714285714*G0_0_1_0_0_1 - 0.557142857142856*G0_0_1_1_0_0 + 0.0428571428571425*G0_0_1_2_0_1 - 0.257142857142857*G0_0_1_3_0_0 - 0.857142857142855*G0_0_1_3_0_1 + 0.257142857142857*G0_0_1_4_0_0 + 0.171428571428571*G0_0_1_4_0_1 + 0.77142857142857*G0_0_1_5_0_0 + 0.857142857142856*G0_0_1_5_0_1 - 0.214285714285714*G0_0_1_6_1_0 - 0.214285714285714*G0_0_1_6_1_1 - 0.557142857142856*G0_0_1_7_1_0 + 0.0428571428571425*G0_0_1_8_1_1 - 0.257142857142857*G0_0_1_9_1_0 - 0.857142857142855*G0_0_1_9_1_1 + 0.257142857142857*G0_0_1_10_1_0 + 0.171428571428571*G0_0_1_10_1_1 + 0.77142857142857*G0_0_1_11_1_0 + 0.857142857142856*G0_0_1_11_1_1; + A[43] = A[253]; + A[116] = 0.0; + A[328] = 0.0; + A[385] = 0.0; + A[378] = -A[278] - 1.0125*G0_0_0_0_0_0 - 1.0125*G0_0_0_0_0_1 + 1.20535714285714*G0_0_0_1_0_0 - 0.530357142857142*G0_0_0_2_0_1 + 1.15714285714286*G0_0_0_3_0_0 + 2.89285714285714*G0_0_0_3_0_1 - 1.15714285714286*G0_0_0_4_0_0 + 1.54285714285714*G0_0_0_4_0_1 - 0.192857142857138*G0_0_0_5_0_0 - 2.89285714285714*G0_0_0_5_0_1 - 1.0125*G0_0_0_6_1_0 - 1.0125*G0_0_0_6_1_1 + 1.20535714285714*G0_0_0_7_1_0 - 0.530357142857142*G0_0_0_8_1_1 + 1.15714285714286*G0_0_0_9_1_0 + 2.89285714285714*G0_0_0_9_1_1 - 1.15714285714286*G0_0_0_10_1_0 + 1.54285714285714*G0_0_0_10_1_1 - 0.192857142857138*G0_0_0_11_1_0 - 2.89285714285714*G0_0_0_11_1_1 + 0.385714285714285*G0_0_1_0_0_0 + 0.385714285714285*G0_0_1_0_0_1 + 0.771428571428568*G0_0_1_1_0_0 - 0.385714285714284*G0_0_1_2_0_1 - 0.385714285714286*G0_0_1_3_0_0 + 0.771428571428566*G0_0_1_3_0_1 + 0.385714285714286*G0_0_1_4_0_0 - 1.15714285714285*G0_0_1_5_0_0 - 0.771428571428567*G0_0_1_5_0_1 + 0.385714285714285*G0_0_1_6_1_0 + 0.385714285714285*G0_0_1_6_1_1 + 0.771428571428568*G0_0_1_7_1_0 - 0.385714285714284*G0_0_1_8_1_1 - 0.385714285714286*G0_0_1_9_1_0 + 0.771428571428566*G0_0_1_9_1_1 + 0.385714285714286*G0_0_1_10_1_0 - 1.15714285714285*G0_0_1_11_1_0 - 0.771428571428567*G0_0_1_11_1_1; + A[181] = A[239] - 0.0642857142857147*G0_0_1_0_0_0 - 0.0642857142857147*G0_0_1_0_0_1 - 0.0642857142857137*G0_0_1_2_0_1 - 0.0642857142857142*G0_0_1_3_0_0 + 0.0642857142857142*G0_0_1_4_0_0 + 0.128571428571429*G0_0_1_4_0_1 + 0.0642857142857159*G0_0_1_5_0_0 - 0.0642857142857147*G0_0_1_6_1_0 - 0.0642857142857147*G0_0_1_6_1_1 - 0.0642857142857137*G0_0_1_8_1_1 - 0.0642857142857142*G0_0_1_9_1_0 + 0.0642857142857142*G0_0_1_10_1_0 + 0.128571428571429*G0_0_1_10_1_1 + 0.0642857142857159*G0_0_1_11_1_0 + 0.0642857142857147*G0_1_0_0_0_0 + 0.0642857142857147*G0_1_0_0_0_1 + 0.0642857142857138*G0_1_0_2_0_1 + 0.0642857142857142*G0_1_0_3_0_0 - 0.0642857142857142*G0_1_0_4_0_0 - 0.128571428571429*G0_1_0_4_0_1 - 0.0642857142857159*G0_1_0_5_0_0 + 0.0642857142857147*G0_1_0_6_1_0 + 0.0642857142857147*G0_1_0_6_1_1 + 0.0642857142857138*G0_1_0_8_1_1 + 0.0642857142857142*G0_1_0_9_1_0 - 0.0642857142857142*G0_1_0_10_1_0 - 0.128571428571429*G0_1_0_10_1_1 - 0.0642857142857159*G0_1_0_11_1_0; + A[149] = -A[181] - 1.67142857142857*G0_0_0_0_0_0 - 1.67142857142857*G0_0_0_0_0_1 - 1.67142857142857*G0_0_0_1_0_0 - 1.67142857142857*G0_0_0_3_0_1 + 1.67142857142857*G0_0_0_4_0_1 + 3.34285714285714*G0_0_0_5_0_0 + 1.67142857142857*G0_0_0_5_0_1 - 1.67142857142857*G0_0_0_6_1_0 - 1.67142857142857*G0_0_0_6_1_1 - 1.67142857142857*G0_0_0_7_1_0 - 1.67142857142857*G0_0_0_9_1_1 + 1.67142857142857*G0_0_0_10_1_1 + 3.34285714285714*G0_0_0_11_1_0 + 1.67142857142857*G0_0_0_11_1_1 - 0.241071428571428*G0_0_1_0_0_0 - 0.241071428571428*G0_0_1_0_0_1 - 1.49464285714286*G0_0_1_1_0_0 + 0.24107142857143*G0_0_1_2_0_1 - 0.771428571428569*G0_0_1_3_0_0 - 2.50714285714286*G0_0_1_3_0_1 + 0.771428571428569*G0_0_1_4_0_0 + 1.73571428571429*G0_0_1_5_0_0 + 2.50714285714286*G0_0_1_5_0_1 - 0.241071428571428*G0_0_1_6_1_0 - 0.241071428571428*G0_0_1_6_1_1 - 1.49464285714286*G0_0_1_7_1_0 + 0.24107142857143*G0_0_1_8_1_1 - 0.771428571428569*G0_0_1_9_1_0 - 2.50714285714286*G0_0_1_9_1_1 + 0.771428571428569*G0_0_1_10_1_0 + 1.73571428571429*G0_0_1_11_1_0 + 2.50714285714286*G0_0_1_11_1_1 + 0.208928571428573*G0_1_0_0_0_0 + 0.208928571428573*G0_1_0_0_0_1 - 0.53035714285714*G0_1_0_1_0_0 - 0.273214285714285*G0_1_0_2_0_1 - 1.28571428571428*G0_1_0_3_0_0 - 1.54285714285714*G0_1_0_3_0_1 + 1.28571428571428*G0_1_0_4_0_0 + 0.0642857142857114*G0_1_0_4_0_1 + 0.321428571428566*G0_1_0_5_0_0 + 1.54285714285714*G0_1_0_5_0_1 + 0.208928571428573*G0_1_0_6_1_0 + 0.208928571428573*G0_1_0_6_1_1 - 0.53035714285714*G0_1_0_7_1_0 - 0.273214285714285*G0_1_0_8_1_1 - 1.28571428571428*G0_1_0_9_1_0 - 1.54285714285714*G0_1_0_9_1_1 + 1.28571428571428*G0_1_0_10_1_0 + 0.0642857142857114*G0_1_0_10_1_1 + 0.321428571428566*G0_1_0_11_1_0 + 1.54285714285714*G0_1_0_11_1_1 + 1.25357142857143*G0_1_1_0_0_0 + 1.25357142857143*G0_1_1_0_0_1 - 1.44642857142857*G0_1_1_1_0_0 + 0.675000000000002*G0_1_1_2_0_1 - 1.35*G0_1_1_3_0_0 - 3.47142857142857*G0_1_1_3_0_1 + 1.35*G0_1_1_4_0_0 - 1.92857142857143*G0_1_1_4_0_1 + 0.192857142857139*G0_1_1_5_0_0 + 3.47142857142857*G0_1_1_5_0_1 + 1.25357142857143*G0_1_1_6_1_0 + 1.25357142857143*G0_1_1_6_1_1 - 1.44642857142857*G0_1_1_7_1_0 + 0.675000000000002*G0_1_1_8_1_1 - 1.35*G0_1_1_9_1_0 - 3.47142857142857*G0_1_1_9_1_1 + 1.35*G0_1_1_10_1_0 - 1.92857142857143*G0_1_1_10_1_1 + 0.192857142857139*G0_1_1_11_1_0 + 3.47142857142857*G0_1_1_11_1_1; + A[397] = A[149] + 0.385714285714287*G0_0_1_0_0_0 + 0.385714285714287*G0_0_1_0_0_1 + 0.964285714285717*G0_0_1_1_0_0 - 0.578571428571428*G0_0_1_2_0_1 - 0.578571428571428*G0_0_1_3_0_0 + 0.964285714285718*G0_0_1_3_0_1 + 0.578571428571428*G0_0_1_4_0_0 + 0.192857142857142*G0_0_1_4_0_1 - 1.35*G0_0_1_5_0_0 - 0.964285714285717*G0_0_1_5_0_1 + 0.385714285714287*G0_0_1_6_1_0 + 0.385714285714287*G0_0_1_6_1_1 + 0.964285714285717*G0_0_1_7_1_0 - 0.578571428571428*G0_0_1_8_1_1 - 0.578571428571428*G0_0_1_9_1_0 + 0.964285714285718*G0_0_1_9_1_1 + 0.578571428571428*G0_0_1_10_1_0 + 0.192857142857142*G0_0_1_10_1_1 - 1.35*G0_0_1_11_1_0 - 0.964285714285717*G0_0_1_11_1_1 - 0.385714285714287*G0_1_0_0_0_0 - 0.385714285714287*G0_1_0_0_0_1 - 0.964285714285717*G0_1_0_1_0_0 + 0.578571428571428*G0_1_0_2_0_1 + 0.578571428571428*G0_1_0_3_0_0 - 0.964285714285718*G0_1_0_3_0_1 - 0.578571428571428*G0_1_0_4_0_0 - 0.192857142857142*G0_1_0_4_0_1 + 1.35*G0_1_0_5_0_0 + 0.964285714285717*G0_1_0_5_0_1 - 0.385714285714287*G0_1_0_6_1_0 - 0.385714285714287*G0_1_0_6_1_1 - 0.964285714285717*G0_1_0_7_1_0 + 0.578571428571428*G0_1_0_8_1_1 + 0.578571428571428*G0_1_0_9_1_0 - 0.964285714285718*G0_1_0_9_1_1 - 0.578571428571428*G0_1_0_10_1_0 - 0.192857142857142*G0_1_0_10_1_1 + 1.35*G0_1_0_11_1_0 + 0.964285714285717*G0_1_0_11_1_1; + A[206] = 0.0; + A[16] = 0.0; + A[280] = 0.0; + A[256] = -A[259] - 0.401785714285714*G0_1_0_0_0_0 - 0.401785714285714*G0_1_0_0_0_1 + 0.530357142857143*G0_1_0_1_0_0 - 1.64464285714286*G0_1_0_2_0_1 - 2.35714285714285*G0_1_0_3_0_0 - 0.182142857142856*G0_1_0_3_0_1 + 2.35714285714285*G0_1_0_4_0_0 + 2.04642857142857*G0_1_0_4_0_1 - 0.128571428571429*G0_1_0_5_0_0 + 0.182142857142856*G0_1_0_5_0_1 - 0.401785714285714*G0_1_0_6_1_0 - 0.401785714285714*G0_1_0_6_1_1 + 0.530357142857143*G0_1_0_7_1_0 - 1.64464285714286*G0_1_0_8_1_1 - 2.35714285714285*G0_1_0_9_1_0 - 0.182142857142856*G0_1_0_9_1_1 + 2.35714285714285*G0_1_0_10_1_0 + 2.04642857142857*G0_1_0_10_1_1 - 0.128571428571429*G0_1_0_11_1_0 + 0.182142857142856*G0_1_0_11_1_1 - 0.471428571428572*G0_1_1_0_0_0 - 0.471428571428571*G0_1_1_0_0_1 + 0.675*G0_1_1_1_0_0 - 1.82142857142857*G0_1_1_2_0_1 - 2.49642857142857*G0_1_1_3_0_0 + 2.49642857142857*G0_1_1_4_0_0 + 2.29285714285714*G0_1_1_4_0_1 - 0.203571428571429*G0_1_1_5_0_0 - 0.471428571428572*G0_1_1_6_1_0 - 0.471428571428571*G0_1_1_6_1_1 + 0.675*G0_1_1_7_1_0 - 1.82142857142857*G0_1_1_8_1_1 - 2.49642857142857*G0_1_1_9_1_0 + 2.49642857142857*G0_1_1_10_1_0 + 2.29285714285714*G0_1_1_10_1_1 - 0.203571428571429*G0_1_1_11_1_0; + A[305] = 0.0; + A[63] = A[273]; + A[390] = A[180]; + A[373] = A[278] - 0.385714285714285*G0_0_1_0_0_0 - 0.385714285714285*G0_0_1_0_0_1 - 0.771428571428568*G0_0_1_1_0_0 + 0.385714285714284*G0_0_1_2_0_1 + 0.385714285714286*G0_0_1_3_0_0 - 0.771428571428566*G0_0_1_3_0_1 - 0.385714285714286*G0_0_1_4_0_0 + 1.15714285714285*G0_0_1_5_0_0 + 0.771428571428567*G0_0_1_5_0_1 - 0.385714285714285*G0_0_1_6_1_0 - 0.385714285714285*G0_0_1_6_1_1 - 0.771428571428568*G0_0_1_7_1_0 + 0.385714285714284*G0_0_1_8_1_1 + 0.385714285714286*G0_0_1_9_1_0 - 0.771428571428566*G0_0_1_9_1_1 - 0.385714285714286*G0_0_1_10_1_0 + 1.15714285714285*G0_0_1_11_1_0 + 0.771428571428567*G0_0_1_11_1_1 + 0.385714285714285*G0_1_0_0_0_0 + 0.385714285714285*G0_1_0_0_0_1 + 0.771428571428567*G0_1_0_1_0_0 - 0.385714285714284*G0_1_0_2_0_1 - 0.385714285714286*G0_1_0_3_0_0 + 0.771428571428565*G0_1_0_3_0_1 + 0.385714285714286*G0_1_0_4_0_0 - 1.15714285714285*G0_1_0_5_0_0 - 0.771428571428566*G0_1_0_5_0_1 + 0.385714285714285*G0_1_0_6_1_0 + 0.385714285714285*G0_1_0_6_1_1 + 0.771428571428567*G0_1_0_7_1_0 - 0.385714285714284*G0_1_0_8_1_1 - 0.385714285714286*G0_1_0_9_1_0 + 0.771428571428565*G0_1_0_9_1_1 + 0.385714285714286*G0_1_0_10_1_0 - 1.15714285714285*G0_1_0_11_1_0 - 0.771428571428566*G0_1_0_11_1_1; + A[171] = 0.0; + A[190] = 0.0; + A[201] = 0.0; + A[177] = 0.0; + A[232] = 0.0422619047619048*G0_0_1_0_0_0 + 0.0422619047619048*G0_0_1_0_0_1 + 0.0648809523809521*G0_0_1_1_0_0 + 0.0648809523809526*G0_0_1_2_0_1 + 0.152380952380952*G0_0_1_3_0_0 + 0.152380952380952*G0_0_1_3_0_1 - 0.152380952380952*G0_0_1_4_0_0 - 0.107142857142857*G0_0_1_4_0_1 - 0.107142857142857*G0_0_1_5_0_0 - 0.152380952380952*G0_0_1_5_0_1 + 0.0422619047619048*G0_0_1_6_1_0 + 0.0422619047619048*G0_0_1_6_1_1 + 0.0648809523809521*G0_0_1_7_1_0 + 0.0648809523809526*G0_0_1_8_1_1 + 0.152380952380952*G0_0_1_9_1_0 + 0.152380952380952*G0_0_1_9_1_1 - 0.152380952380952*G0_0_1_10_1_0 - 0.107142857142857*G0_0_1_10_1_1 - 0.107142857142857*G0_0_1_11_1_0 - 0.152380952380952*G0_0_1_11_1_1; + A[20] = -A[232] + 0.0648809523809526*G0_0_0_0_0_0 + 0.0648809523809525*G0_0_0_0_0_1 - 0.0648809523809524*G0_0_0_1_0_0 + 0.0422619047619048*G0_0_0_2_0_1 - 0.0452380952380952*G0_0_0_3_0_0 - 0.152380952380952*G0_0_0_3_0_1 + 0.0452380952380952*G0_0_0_4_0_0 - 0.107142857142857*G0_0_0_4_0_1 + 0.152380952380953*G0_0_0_5_0_1 + 0.0648809523809526*G0_0_0_6_1_0 + 0.0648809523809525*G0_0_0_6_1_1 - 0.0648809523809524*G0_0_0_7_1_0 + 0.0422619047619048*G0_0_0_8_1_1 - 0.0452380952380952*G0_0_0_9_1_0 - 0.152380952380952*G0_0_0_9_1_1 + 0.0452380952380952*G0_0_0_10_1_0 - 0.107142857142857*G0_0_0_10_1_1 + 0.152380952380953*G0_0_0_11_1_1 + 0.107142857142857*G0_0_1_0_0_0 + 0.107142857142857*G0_0_1_0_0_1 + 0.107142857142857*G0_0_1_2_0_1 + 0.107142857142857*G0_0_1_3_0_0 - 0.107142857142857*G0_0_1_4_0_0 - 0.214285714285715*G0_0_1_4_0_1 - 0.107142857142857*G0_0_1_5_0_0 + 0.107142857142857*G0_0_1_6_1_0 + 0.107142857142857*G0_0_1_6_1_1 + 0.107142857142857*G0_0_1_8_1_1 + 0.107142857142857*G0_0_1_9_1_0 - 0.107142857142857*G0_0_1_10_1_0 - 0.214285714285715*G0_0_1_10_1_1 - 0.107142857142857*G0_0_1_11_1_0; + A[212] = -A[232] + 0.107142857142857*G0_0_1_0_0_0 + 0.107142857142857*G0_0_1_0_0_1 + 0.107142857142857*G0_0_1_1_0_0 + 0.107142857142857*G0_0_1_3_0_1 - 0.107142857142857*G0_0_1_4_0_1 - 0.214285714285714*G0_0_1_5_0_0 - 0.107142857142857*G0_0_1_5_0_1 + 0.107142857142857*G0_0_1_6_1_0 + 0.107142857142857*G0_0_1_6_1_1 + 0.107142857142857*G0_0_1_7_1_0 + 0.107142857142857*G0_0_1_9_1_1 - 0.107142857142857*G0_0_1_10_1_1 - 0.214285714285714*G0_0_1_11_1_0 - 0.107142857142857*G0_0_1_11_1_1 + 0.0648809523809523*G0_1_1_0_0_0 + 0.0648809523809523*G0_1_1_0_0_1 + 0.0422619047619048*G0_1_1_1_0_0 - 0.0648809523809525*G0_1_1_2_0_1 - 0.152380952380952*G0_1_1_3_0_0 - 0.0452380952380952*G0_1_1_3_0_1 + 0.152380952380952*G0_1_1_4_0_0 - 0.107142857142857*G0_1_1_5_0_0 + 0.0452380952380953*G0_1_1_5_0_1 + 0.0648809523809523*G0_1_1_6_1_0 + 0.0648809523809523*G0_1_1_6_1_1 + 0.0422619047619048*G0_1_1_7_1_0 - 0.0648809523809525*G0_1_1_8_1_1 - 0.152380952380952*G0_1_1_9_1_0 - 0.0452380952380952*G0_1_1_9_1_1 + 0.152380952380952*G0_1_1_10_1_0 - 0.107142857142857*G0_1_1_11_1_0 + 0.0452380952380953*G0_1_1_11_1_1; + A[230] = A[20]; + A[2] = A[212]; + A[291] = A[81]; + A[255] = A[45]; + A[302] = 0.0; + A[274] = A[64]; + A[13] = 0.0; + A[68] = A[278]; + A[28] = -A[239] - 0.47142857142857*G0_0_0_0_0_0 - 0.471428571428571*G0_0_0_0_0_1 - 1.82142857142857*G0_0_0_1_0_0 + 0.674999999999999*G0_0_0_2_0_1 - 2.49642857142857*G0_0_0_3_0_1 - 0.203571428571429*G0_0_0_4_0_1 + 2.29285714285714*G0_0_0_5_0_0 + 2.49642857142857*G0_0_0_5_0_1 - 0.47142857142857*G0_0_0_6_1_0 - 0.471428571428571*G0_0_0_6_1_1 - 1.82142857142857*G0_0_0_7_1_0 + 0.674999999999999*G0_0_0_8_1_1 - 2.49642857142857*G0_0_0_9_1_1 - 0.203571428571429*G0_0_0_10_1_1 + 2.29285714285714*G0_0_0_11_1_0 + 2.49642857142857*G0_0_0_11_1_1 - 0.401785714285713*G0_0_1_0_0_0 - 0.401785714285714*G0_0_1_0_0_1 - 1.64464285714285*G0_0_1_1_0_0 + 0.530357142857142*G0_0_1_2_0_1 - 0.182142857142856*G0_0_1_3_0_0 - 2.35714285714285*G0_0_1_3_0_1 + 0.182142857142856*G0_0_1_4_0_0 - 0.128571428571429*G0_0_1_4_0_1 + 2.04642857142857*G0_0_1_5_0_0 + 2.35714285714285*G0_0_1_5_0_1 - 0.401785714285713*G0_0_1_6_1_0 - 0.401785714285714*G0_0_1_6_1_1 - 1.64464285714285*G0_0_1_7_1_0 + 0.530357142857142*G0_0_1_8_1_1 - 0.182142857142856*G0_0_1_9_1_0 - 2.35714285714285*G0_0_1_9_1_1 + 0.182142857142856*G0_0_1_10_1_0 - 0.128571428571429*G0_0_1_10_1_1 + 2.04642857142857*G0_0_1_11_1_0 + 2.35714285714285*G0_0_1_11_1_1; + A[23] = -A[28] + 0.0267857142857151*G0_0_0_0_0_0 + 0.026785714285715*G0_0_0_0_0_1 - 0.583928571428569*G0_0_0_1_0_0 - 0.0267857142857149*G0_0_0_2_0_1 - 0.664285714285713*G0_0_0_3_0_0 - 1.22142857142857*G0_0_0_3_0_1 + 0.664285714285713*G0_0_0_4_0_0 + 0.557142857142854*G0_0_0_5_0_0 + 1.22142857142857*G0_0_0_5_0_1 + 0.0267857142857151*G0_0_0_6_1_0 + 0.026785714285715*G0_0_0_6_1_1 - 0.583928571428569*G0_0_0_7_1_0 - 0.0267857142857149*G0_0_0_8_1_1 - 0.664285714285713*G0_0_0_9_1_0 - 1.22142857142857*G0_0_0_9_1_1 + 0.664285714285713*G0_0_0_10_1_0 + 0.557142857142854*G0_0_0_11_1_0 + 1.22142857142857*G0_0_0_11_1_1; + A[271] = A[23] - 0.466071428571427*G0_0_1_0_0_0 - 0.466071428571428*G0_0_1_0_0_1 - 1.64464285714285*G0_0_1_1_0_0 + 0.466071428571428*G0_0_1_2_0_1 - 0.24642857142857*G0_0_1_3_0_0 - 2.35714285714285*G0_0_1_3_0_1 + 0.24642857142857*G0_0_1_4_0_0 + 2.11071428571428*G0_0_1_5_0_0 + 2.35714285714285*G0_0_1_5_0_1 - 0.466071428571427*G0_0_1_6_1_0 - 0.466071428571428*G0_0_1_6_1_1 - 1.64464285714285*G0_0_1_7_1_0 + 0.466071428571428*G0_0_1_8_1_1 - 0.24642857142857*G0_0_1_9_1_0 - 2.35714285714285*G0_0_1_9_1_1 + 0.24642857142857*G0_0_1_10_1_0 + 2.11071428571428*G0_0_1_11_1_0 + 2.35714285714285*G0_0_1_11_1_1 + 0.466071428571427*G0_1_0_0_0_0 + 0.466071428571428*G0_1_0_0_0_1 + 1.64464285714285*G0_1_0_1_0_0 - 0.466071428571428*G0_1_0_2_0_1 + 0.24642857142857*G0_1_0_3_0_0 + 2.35714285714285*G0_1_0_3_0_1 - 0.24642857142857*G0_1_0_4_0_0 - 2.11071428571428*G0_1_0_5_0_0 - 2.35714285714285*G0_1_0_5_0_1 + 0.466071428571427*G0_1_0_6_1_0 + 0.466071428571428*G0_1_0_6_1_1 + 1.64464285714285*G0_1_0_7_1_0 - 0.466071428571428*G0_1_0_8_1_1 + 0.24642857142857*G0_1_0_9_1_0 + 2.35714285714285*G0_1_0_9_1_1 - 0.24642857142857*G0_1_0_10_1_0 - 2.11071428571428*G0_1_0_11_1_0 - 2.35714285714285*G0_1_0_11_1_1; + A[61] = A[271]; + A[83] = -A[333] + 0.819642857142857*G0_1_0_0_0_0 + 0.819642857142857*G0_1_0_0_0_1 + 0.723214285714286*G0_1_0_1_0_0 + 1.10892857142857*G0_1_0_2_0_1 + 2.12142857142857*G0_1_0_3_0_0 + 1.73571428571429*G0_1_0_3_0_1 - 2.12142857142857*G0_1_0_4_0_0 - 1.92857142857143*G0_1_0_4_0_1 - 1.54285714285714*G0_1_0_5_0_0 - 1.73571428571429*G0_1_0_5_0_1 + 0.819642857142857*G0_1_0_6_1_0 + 0.819642857142857*G0_1_0_6_1_1 + 0.723214285714286*G0_1_0_7_1_0 + 1.10892857142857*G0_1_0_8_1_1 + 2.12142857142857*G0_1_0_9_1_0 + 1.73571428571429*G0_1_0_9_1_1 - 2.12142857142857*G0_1_0_10_1_0 - 1.92857142857143*G0_1_0_10_1_1 - 1.54285714285714*G0_1_0_11_1_0 - 1.73571428571429*G0_1_0_11_1_1 + 0.0482142857142864*G0_1_1_0_0_0 + 0.0482142857142861*G0_1_1_0_0_1 - 0.819642857142855*G0_1_1_1_0_0 + 0.530357142857142*G0_1_1_2_0_1 + 0.192857142857144*G0_1_1_3_0_0 - 1.15714285714285*G0_1_1_3_0_1 - 0.192857142857144*G0_1_1_4_0_0 - 0.578571428571429*G0_1_1_4_0_1 + 0.771428571428569*G0_1_1_5_0_0 + 1.15714285714285*G0_1_1_5_0_1 + 0.0482142857142864*G0_1_1_6_1_0 + 0.0482142857142861*G0_1_1_6_1_1 - 0.819642857142855*G0_1_1_7_1_0 + 0.530357142857142*G0_1_1_8_1_1 + 0.192857142857144*G0_1_1_9_1_0 - 1.15714285714285*G0_1_1_9_1_1 - 0.192857142857144*G0_1_1_10_1_0 - 0.578571428571429*G0_1_1_10_1_1 + 0.771428571428569*G0_1_1_11_1_0 + 1.15714285714285*G0_1_1_11_1_1; + A[55] = 0.0; + A[102] = -A[62] - 0.0642857142857146*G0_0_1_0_0_0 - 0.0642857142857146*G0_0_1_0_0_1 - 0.0642857142857143*G0_0_1_1_0_0 - 0.0642857142857144*G0_0_1_3_0_1 + 0.0642857142857153*G0_0_1_4_0_1 + 0.128571428571429*G0_0_1_5_0_0 + 0.0642857142857144*G0_0_1_5_0_1 - 0.0642857142857146*G0_0_1_6_1_0 - 0.0642857142857146*G0_0_1_6_1_1 - 0.0642857142857143*G0_0_1_7_1_0 - 0.0642857142857144*G0_0_1_9_1_1 + 0.0642857142857153*G0_0_1_10_1_1 + 0.128571428571429*G0_0_1_11_1_0 + 0.0642857142857144*G0_0_1_11_1_1 - 0.117857142857143*G0_1_1_0_0_0 - 0.117857142857143*G0_1_1_0_0_1 + 0.053571428571428*G0_1_1_1_0_0 + 0.203571428571429*G0_1_1_2_0_1 + 0.578571428571428*G0_1_1_3_0_0 + 0.428571428571428*G0_1_1_3_0_1 - 0.578571428571428*G0_1_1_4_0_0 - 0.0857142857142853*G0_1_1_4_0_1 + 0.064285714285715*G0_1_1_5_0_0 - 0.428571428571428*G0_1_1_5_0_1 - 0.117857142857143*G0_1_1_6_1_0 - 0.117857142857143*G0_1_1_6_1_1 + 0.053571428571428*G0_1_1_7_1_0 + 0.203571428571429*G0_1_1_8_1_1 + 0.578571428571428*G0_1_1_9_1_0 + 0.428571428571428*G0_1_1_9_1_1 - 0.578571428571428*G0_1_1_10_1_0 - 0.0857142857142853*G0_1_1_10_1_1 + 0.064285714285715*G0_1_1_11_1_0 - 0.428571428571428*G0_1_1_11_1_1; + A[326] = 0.0; + A[129] = -A[299] - 1.54285714285714*G0_1_0_0_0_0 - 1.54285714285714*G0_1_0_0_0_1 - 1.54285714285714*G0_1_0_1_0_0 - 1.54285714285714*G0_1_0_3_0_1 + 1.54285714285714*G0_1_0_4_0_1 + 3.08571428571429*G0_1_0_5_0_0 + 1.54285714285714*G0_1_0_5_0_1 - 1.54285714285714*G0_1_0_6_1_0 - 1.54285714285714*G0_1_0_6_1_1 - 1.54285714285714*G0_1_0_7_1_0 - 1.54285714285714*G0_1_0_9_1_1 + 1.54285714285714*G0_1_0_10_1_1 + 3.08571428571429*G0_1_0_11_1_0 + 1.54285714285714*G0_1_0_11_1_1 + 0.289285714285716*G0_1_1_0_0_0 + 0.289285714285716*G0_1_1_0_0_1 - 1.83214285714286*G0_1_1_1_0_0 + 0.0964285714285718*G0_1_1_2_0_1 - 1.92857142857143*G0_1_1_3_0_0 - 3.85714285714286*G0_1_1_3_0_1 + 1.92857142857143*G0_1_1_4_0_0 - 0.385714285714288*G0_1_1_4_0_1 + 1.54285714285714*G0_1_1_5_0_0 + 3.85714285714286*G0_1_1_5_0_1 + 0.289285714285716*G0_1_1_6_1_0 + 0.289285714285716*G0_1_1_6_1_1 - 1.83214285714286*G0_1_1_7_1_0 + 0.0964285714285718*G0_1_1_8_1_1 - 1.92857142857143*G0_1_1_9_1_0 - 3.85714285714286*G0_1_1_9_1_1 + 1.92857142857143*G0_1_1_10_1_0 - 0.385714285714288*G0_1_1_10_1_1 + 1.54285714285714*G0_1_1_11_1_0 + 3.85714285714286*G0_1_1_11_1_1; + A[399] = A[189]; + A[347] = 0.0; + A[152] = 0.0; + A[364] = 0.0; + A[208] = 0.0; + A[225] = 0.0; + A[246] = 0.0; + A[311] = A[101]; + A[267] = 0.0; + A[4] = A[214]; + A[21] = 0.186904761904761*G0_0_0_0_0_0 + 0.186904761904762*G0_0_0_0_0_1 + 0.798809523809523*G0_0_0_1_0_0 - 0.186904761904761*G0_0_0_2_0_1 + 0.238095238095237*G0_0_0_3_0_0 + 1.22380952380952*G0_0_0_3_0_1 - 0.238095238095237*G0_0_0_4_0_0 - 0.985714285714284*G0_0_0_5_0_0 - 1.22380952380952*G0_0_0_5_0_1 + 0.186904761904761*G0_0_0_6_1_0 + 0.186904761904762*G0_0_0_6_1_1 + 0.798809523809523*G0_0_0_7_1_0 - 0.186904761904761*G0_0_0_8_1_1 + 0.238095238095237*G0_0_0_9_1_0 + 1.22380952380952*G0_0_0_9_1_1 - 0.238095238095237*G0_0_0_10_1_0 - 0.985714285714284*G0_0_0_11_1_0 - 1.22380952380952*G0_0_0_11_1_1; + A[0] = A[21] - 0.985714285714286*G0_0_0_0_0_0 - 0.985714285714286*G0_0_0_0_0_1 - 0.985714285714285*G0_0_0_1_0_0 - 0.985714285714284*G0_0_0_3_0_1 + 0.985714285714286*G0_0_0_4_0_1 + 1.97142857142857*G0_0_0_5_0_0 + 0.985714285714284*G0_0_0_5_0_1 - 0.985714285714286*G0_0_0_6_1_0 - 0.985714285714286*G0_0_0_6_1_1 - 0.985714285714285*G0_0_0_7_1_0 - 0.985714285714284*G0_0_0_9_1_1 + 0.985714285714286*G0_0_0_10_1_1 + 1.97142857142857*G0_0_0_11_1_0 + 0.985714285714284*G0_0_0_11_1_1 - 0.798809523809524*G0_0_1_0_0_0 - 0.798809523809524*G0_0_1_0_0_1 - 0.186904761904762*G0_0_1_1_0_0 - 0.186904761904762*G0_0_1_2_0_1 + 0.238095238095238*G0_0_1_3_0_0 + 0.238095238095238*G0_0_1_3_0_1 - 0.238095238095238*G0_0_1_4_0_0 + 0.985714285714286*G0_0_1_4_0_1 + 0.985714285714287*G0_0_1_5_0_0 - 0.238095238095238*G0_0_1_5_0_1 - 0.798809523809524*G0_0_1_6_1_0 - 0.798809523809524*G0_0_1_6_1_1 - 0.186904761904762*G0_0_1_7_1_0 - 0.186904761904762*G0_0_1_8_1_1 + 0.238095238095238*G0_0_1_9_1_0 + 0.238095238095238*G0_0_1_9_1_1 - 0.238095238095238*G0_0_1_10_1_0 + 0.985714285714286*G0_0_1_10_1_1 + 0.985714285714287*G0_0_1_11_1_0 - 0.238095238095238*G0_0_1_11_1_1 - 0.798809523809524*G0_1_0_0_0_0 - 0.798809523809524*G0_1_0_0_0_1 - 0.186904761904762*G0_1_0_1_0_0 - 0.186904761904762*G0_1_0_2_0_1 + 0.238095238095238*G0_1_0_3_0_0 + 0.238095238095238*G0_1_0_3_0_1 - 0.238095238095238*G0_1_0_4_0_0 + 0.985714285714286*G0_1_0_4_0_1 + 0.985714285714287*G0_1_0_5_0_0 - 0.238095238095238*G0_1_0_5_0_1 - 0.798809523809524*G0_1_0_6_1_0 - 0.798809523809524*G0_1_0_6_1_1 - 0.186904761904762*G0_1_0_7_1_0 - 0.186904761904762*G0_1_0_8_1_1 + 0.238095238095238*G0_1_0_9_1_0 + 0.238095238095238*G0_1_0_9_1_1 - 0.238095238095238*G0_1_0_10_1_0 + 0.985714285714286*G0_1_0_10_1_1 + 0.985714285714287*G0_1_0_11_1_0 - 0.238095238095238*G0_1_0_11_1_1 - 0.798809523809524*G0_1_1_0_0_0 - 0.798809523809524*G0_1_1_0_0_1 - 0.186904761904762*G0_1_1_1_0_0 - 0.186904761904762*G0_1_1_2_0_1 + 0.238095238095238*G0_1_1_3_0_0 + 0.238095238095238*G0_1_1_3_0_1 - 0.238095238095238*G0_1_1_4_0_0 + 0.985714285714286*G0_1_1_4_0_1 + 0.985714285714287*G0_1_1_5_0_0 - 0.238095238095238*G0_1_1_5_0_1 - 0.798809523809524*G0_1_1_6_1_0 - 0.798809523809524*G0_1_1_6_1_1 - 0.186904761904762*G0_1_1_7_1_0 - 0.186904761904762*G0_1_1_8_1_1 + 0.238095238095238*G0_1_1_9_1_0 + 0.238095238095238*G0_1_1_9_1_1 - 0.238095238095238*G0_1_1_10_1_0 + 0.985714285714286*G0_1_1_10_1_1 + 0.985714285714287*G0_1_1_11_1_0 - 0.238095238095238*G0_1_1_11_1_1; + A[210] = A[0]; + A[90] = 0.0; + A[46] = A[256]; + A[111] = 0.0; + A[96] = 0.0; + A[339] = A[129]; + A[358] = -A[143] + 1.54285714285714*G0_0_0_0_0_0 + 1.54285714285714*G0_0_0_0_0_1 - 0.578571428571428*G0_0_0_1_0_0 + 0.771428571428571*G0_0_0_2_0_1 - 0.578571428571428*G0_0_0_3_0_0 - 1.92857142857143*G0_0_0_3_0_1 + 0.578571428571428*G0_0_0_4_0_0 - 2.31428571428572*G0_0_0_4_0_1 - 0.964285714285717*G0_0_0_5_0_0 + 1.92857142857143*G0_0_0_5_0_1 + 1.54285714285714*G0_0_0_6_1_0 + 1.54285714285714*G0_0_0_6_1_1 - 0.578571428571428*G0_0_0_7_1_0 + 0.771428571428571*G0_0_0_8_1_1 - 0.578571428571428*G0_0_0_9_1_0 - 1.92857142857143*G0_0_0_9_1_1 + 0.578571428571428*G0_0_0_10_1_0 - 2.31428571428572*G0_0_0_10_1_1 - 0.964285714285717*G0_0_0_11_1_0 + 1.92857142857143*G0_0_0_11_1_1 + 0.723214285714286*G0_1_0_0_0_0 + 0.723214285714286*G0_1_0_0_0_1 - 1.10892857142857*G0_1_0_1_0_0 + 0.819642857142856*G0_1_0_2_0_1 - 0.192857142857142*G0_1_0_3_0_0 - 2.12142857142857*G0_1_0_3_0_1 + 0.192857142857142*G0_1_0_4_0_0 - 1.54285714285714*G0_1_0_4_0_1 + 0.385714285714285*G0_1_0_5_0_0 + 2.12142857142857*G0_1_0_5_0_1 + 0.723214285714286*G0_1_0_6_1_0 + 0.723214285714286*G0_1_0_6_1_1 - 1.10892857142857*G0_1_0_7_1_0 + 0.819642857142856*G0_1_0_8_1_1 - 0.192857142857142*G0_1_0_9_1_0 - 2.12142857142857*G0_1_0_9_1_1 + 0.192857142857142*G0_1_0_10_1_0 - 1.54285714285714*G0_1_0_10_1_1 + 0.385714285714285*G0_1_0_11_1_0 + 2.12142857142857*G0_1_0_11_1_1; + A[377] = A[358] + 0.819642857142857*G0_0_1_0_0_0 + 0.819642857142857*G0_0_1_0_0_1 - 0.819642857142859*G0_0_1_1_0_0 + 0.626785714285715*G0_0_1_2_0_1 - 0.385714285714284*G0_0_1_3_0_0 - 1.83214285714286*G0_0_1_3_0_1 + 0.385714285714284*G0_0_1_4_0_0 - 1.44642857142857*G0_0_1_4_0_1 + 1.83214285714286*G0_0_1_5_0_1 + 0.819642857142857*G0_0_1_6_1_0 + 0.819642857142857*G0_0_1_6_1_1 - 0.819642857142859*G0_0_1_7_1_0 + 0.626785714285715*G0_0_1_8_1_1 - 0.385714285714284*G0_0_1_9_1_0 - 1.83214285714286*G0_0_1_9_1_1 + 0.385714285714284*G0_0_1_10_1_0 - 1.44642857142857*G0_0_1_10_1_1 + 1.83214285714286*G0_0_1_11_1_1 - 0.819642857142857*G0_1_0_0_0_0 - 0.819642857142857*G0_1_0_0_0_1 + 0.819642857142858*G0_1_0_1_0_0 - 0.626785714285715*G0_1_0_2_0_1 + 0.385714285714285*G0_1_0_3_0_0 + 1.83214285714286*G0_1_0_3_0_1 - 0.385714285714285*G0_1_0_4_0_0 + 1.44642857142857*G0_1_0_4_0_1 - 1.83214285714286*G0_1_0_5_0_1 - 0.819642857142857*G0_1_0_6_1_0 - 0.819642857142857*G0_1_0_6_1_1 + 0.819642857142858*G0_1_0_7_1_0 - 0.626785714285715*G0_1_0_8_1_1 + 0.385714285714285*G0_1_0_9_1_0 + 1.83214285714286*G0_1_0_9_1_1 - 0.385714285714285*G0_1_0_10_1_0 + 1.44642857142857*G0_1_0_10_1_1 - 1.83214285714286*G0_1_0_11_1_1; + A[167] = A[377]; + A[260] = 0.0; + A[236] = A[26]; + A[41] = 0.0422619047619048*G0_1_0_0_0_0 + 0.0422619047619048*G0_1_0_0_0_1 + 0.0648809523809521*G0_1_0_1_0_0 + 0.0648809523809526*G0_1_0_2_0_1 + 0.152380952380952*G0_1_0_3_0_0 + 0.152380952380952*G0_1_0_3_0_1 - 0.152380952380952*G0_1_0_4_0_0 - 0.107142857142857*G0_1_0_4_0_1 - 0.107142857142857*G0_1_0_5_0_0 - 0.152380952380952*G0_1_0_5_0_1 + 0.0422619047619048*G0_1_0_6_1_0 + 0.0422619047619048*G0_1_0_6_1_1 + 0.0648809523809521*G0_1_0_7_1_0 + 0.0648809523809526*G0_1_0_8_1_1 + 0.152380952380952*G0_1_0_9_1_0 + 0.152380952380952*G0_1_0_9_1_1 - 0.152380952380952*G0_1_0_10_1_0 - 0.107142857142857*G0_1_0_10_1_1 - 0.107142857142857*G0_1_0_11_1_0 - 0.152380952380952*G0_1_0_11_1_1; + A[250] = -A[41] + 0.107142857142857*G0_1_0_0_0_0 + 0.107142857142857*G0_1_0_0_0_1 + 0.107142857142857*G0_1_0_1_0_0 + 0.107142857142857*G0_1_0_3_0_1 - 0.107142857142857*G0_1_0_4_0_1 - 0.214285714285714*G0_1_0_5_0_0 - 0.107142857142857*G0_1_0_5_0_1 + 0.107142857142857*G0_1_0_6_1_0 + 0.107142857142857*G0_1_0_6_1_1 + 0.107142857142857*G0_1_0_7_1_0 + 0.107142857142857*G0_1_0_9_1_1 - 0.107142857142857*G0_1_0_10_1_1 - 0.214285714285714*G0_1_0_11_1_0 - 0.107142857142857*G0_1_0_11_1_1 + 0.0648809523809523*G0_1_1_0_0_0 + 0.0648809523809523*G0_1_1_0_0_1 + 0.0422619047619048*G0_1_1_1_0_0 - 0.0648809523809525*G0_1_1_2_0_1 - 0.152380952380952*G0_1_1_3_0_0 - 0.0452380952380952*G0_1_1_3_0_1 + 0.152380952380952*G0_1_1_4_0_0 - 0.107142857142857*G0_1_1_5_0_0 + 0.0452380952380953*G0_1_1_5_0_1 + 0.0648809523809523*G0_1_1_6_1_0 + 0.0648809523809523*G0_1_1_6_1_1 + 0.0422619047619048*G0_1_1_7_1_0 - 0.0648809523809525*G0_1_1_8_1_1 - 0.152380952380952*G0_1_1_9_1_0 - 0.0452380952380952*G0_1_1_9_1_1 + 0.152380952380952*G0_1_1_10_1_0 - 0.107142857142857*G0_1_1_11_1_0 + 0.0452380952380953*G0_1_1_11_1_1; + A[142] = A[162] + 0.128571428571428*G0_1_1_0_0_0 + 0.128571428571428*G0_1_1_0_0_1 + 0.128571428571428*G0_1_1_1_0_0 + 0.128571428571428*G0_1_1_3_0_1 - 0.128571428571429*G0_1_1_4_0_1 - 0.257142857142856*G0_1_1_5_0_0 - 0.128571428571428*G0_1_1_5_0_1 + 0.128571428571428*G0_1_1_6_1_0 + 0.128571428571428*G0_1_1_6_1_1 + 0.128571428571428*G0_1_1_7_1_0 + 0.128571428571428*G0_1_1_9_1_1 - 0.128571428571429*G0_1_1_10_1_1 - 0.257142857142856*G0_1_1_11_1_0 - 0.128571428571428*G0_1_1_11_1_1; + A[387] = 0.0; + A[351] = -A[81] - 0.117857142857143*G0_0_0_0_0_0 - 0.117857142857143*G0_0_0_0_0_1 + 0.203571428571427*G0_0_0_1_0_0 + 0.0535714285714292*G0_0_0_2_0_1 + 0.428571428571428*G0_0_0_3_0_0 + 0.578571428571427*G0_0_0_3_0_1 - 0.428571428571428*G0_0_0_4_0_0 + 0.0642857142857144*G0_0_0_4_0_1 - 0.0857142857142838*G0_0_0_5_0_0 - 0.578571428571427*G0_0_0_5_0_1 - 0.117857142857143*G0_0_0_6_1_0 - 0.117857142857143*G0_0_0_6_1_1 + 0.203571428571427*G0_0_0_7_1_0 + 0.0535714285714292*G0_0_0_8_1_1 + 0.428571428571428*G0_0_0_9_1_0 + 0.578571428571427*G0_0_0_9_1_1 - 0.428571428571428*G0_0_0_10_1_0 + 0.0642857142857144*G0_0_0_10_1_1 - 0.0857142857142838*G0_0_0_11_1_0 - 0.578571428571427*G0_0_0_11_1_1 - 0.0642857142857142*G0_1_0_0_0_0 - 0.0642857142857142*G0_1_0_0_0_1 - 0.064285714285714*G0_1_0_2_0_1 - 0.0642857142857141*G0_1_0_3_0_0 + 0.0642857142857141*G0_1_0_4_0_0 + 0.128571428571428*G0_1_0_4_0_1 + 0.0642857142857143*G0_1_0_5_0_0 - 0.0642857142857142*G0_1_0_6_1_0 - 0.0642857142857142*G0_1_0_6_1_1 - 0.064285714285714*G0_1_0_8_1_1 - 0.0642857142857141*G0_1_0_9_1_0 + 0.0642857142857141*G0_1_0_10_1_0 + 0.128571428571428*G0_1_0_10_1_1 + 0.0642857142857143*G0_1_0_11_1_0; + A[376] = -A[276] - 0.0482142857142853*G0_0_0_0_0_0 - 0.0482142857142855*G0_0_0_0_0_1 - 0.530357142857143*G0_0_0_1_0_0 + 0.819642857142859*G0_0_0_2_0_1 + 1.15714285714286*G0_0_0_3_0_0 - 0.192857142857143*G0_0_0_3_0_1 - 1.15714285714286*G0_0_0_4_0_0 - 0.771428571428573*G0_0_0_4_0_1 + 0.578571428571429*G0_0_0_5_0_0 + 0.192857142857142*G0_0_0_5_0_1 - 0.0482142857142853*G0_0_0_6_1_0 - 0.0482142857142855*G0_0_0_6_1_1 - 0.530357142857143*G0_0_0_7_1_0 + 0.819642857142859*G0_0_0_8_1_1 + 1.15714285714286*G0_0_0_9_1_0 - 0.192857142857143*G0_0_0_9_1_1 - 1.15714285714286*G0_0_0_10_1_0 - 0.771428571428573*G0_0_0_10_1_1 + 0.578571428571429*G0_0_0_11_1_0 + 0.192857142857142*G0_0_0_11_1_1 + 0.385714285714287*G0_0_1_0_0_0 + 0.385714285714287*G0_0_1_0_0_1 + 0.385714285714287*G0_0_1_2_0_1 + 0.385714285714288*G0_0_1_3_0_0 - 0.385714285714288*G0_0_1_4_0_0 - 0.771428571428574*G0_0_1_4_0_1 - 0.385714285714288*G0_0_1_5_0_0 + 0.385714285714287*G0_0_1_6_1_0 + 0.385714285714287*G0_0_1_6_1_1 + 0.385714285714287*G0_0_1_8_1_1 + 0.385714285714288*G0_0_1_9_1_0 - 0.385714285714288*G0_0_1_10_1_0 - 0.771428571428574*G0_0_1_10_1_1 - 0.385714285714288*G0_0_1_11_1_0; + A[144] = -A[376] + 0.192857142857144*G0_0_1_0_0_0 + 0.192857142857144*G0_0_1_0_0_1 + 0.192857142857145*G0_0_1_1_0_0 + 0.192857142857145*G0_0_1_3_0_1 - 0.192857142857144*G0_0_1_4_0_1 - 0.385714285714289*G0_0_1_5_0_0 - 0.192857142857145*G0_0_1_5_0_1 + 0.192857142857144*G0_0_1_6_1_0 + 0.192857142857144*G0_0_1_6_1_1 + 0.192857142857145*G0_0_1_7_1_0 + 0.192857142857145*G0_0_1_9_1_1 - 0.192857142857144*G0_0_1_10_1_1 - 0.385714285714289*G0_0_1_11_1_0 - 0.192857142857145*G0_0_1_11_1_1 - 0.0964285714285713*G0_1_0_0_0_0 - 0.0964285714285713*G0_1_0_0_0_1 - 0.0964285714285713*G0_1_0_1_0_0 - 0.0964285714285703*G0_1_0_3_0_1 + 0.0964285714285703*G0_1_0_4_0_1 + 0.192857142857143*G0_1_0_5_0_0 + 0.0964285714285705*G0_1_0_5_0_1 - 0.0964285714285713*G0_1_0_6_1_0 - 0.0964285714285713*G0_1_0_6_1_1 - 0.0964285714285713*G0_1_0_7_1_0 - 0.0964285714285703*G0_1_0_9_1_1 + 0.0964285714285703*G0_1_0_10_1_1 + 0.192857142857143*G0_1_0_11_1_0 + 0.0964285714285705*G0_1_0_11_1_1 - 0.144642857142858*G0_1_1_0_0_0 - 0.144642857142858*G0_1_1_0_0_1 + 0.24107142857143*G0_1_1_1_0_0 - 0.0482142857142867*G0_1_1_2_0_1 + 0.289285714285714*G0_1_1_3_0_0 + 0.578571428571431*G0_1_1_3_0_1 - 0.289285714285714*G0_1_1_4_0_0 + 0.192857142857145*G0_1_1_4_0_1 - 0.0964285714285712*G0_1_1_5_0_0 - 0.57857142857143*G0_1_1_5_0_1 - 0.144642857142858*G0_1_1_6_1_0 - 0.144642857142858*G0_1_1_6_1_1 + 0.24107142857143*G0_1_1_7_1_0 - 0.0482142857142867*G0_1_1_8_1_1 + 0.289285714285714*G0_1_1_9_1_0 + 0.578571428571431*G0_1_1_9_1_1 - 0.289285714285714*G0_1_1_10_1_0 + 0.192857142857145*G0_1_1_10_1_1 - 0.0964285714285712*G0_1_1_11_1_0 - 0.57857142857143*G0_1_1_11_1_1; + A[87] = A[144] - 0.0964285714285721*G0_0_1_0_0_0 - 0.0964285714285721*G0_0_1_0_0_1 - 0.192857142857144*G0_0_1_1_0_0 + 0.0964285714285725*G0_0_1_2_0_1 + 0.096428571428573*G0_0_1_3_0_0 - 0.192857142857143*G0_0_1_3_0_1 - 0.096428571428573*G0_0_1_4_0_0 + 0.289285714285716*G0_0_1_5_0_0 + 0.192857142857143*G0_0_1_5_0_1 - 0.0964285714285721*G0_0_1_6_1_0 - 0.0964285714285721*G0_0_1_6_1_1 - 0.192857142857144*G0_0_1_7_1_0 + 0.0964285714285725*G0_0_1_8_1_1 + 0.096428571428573*G0_0_1_9_1_0 - 0.192857142857143*G0_0_1_9_1_1 - 0.096428571428573*G0_0_1_10_1_0 + 0.289285714285716*G0_0_1_11_1_0 + 0.192857142857143*G0_0_1_11_1_1 + 0.0964285714285722*G0_1_0_0_0_0 + 0.0964285714285721*G0_1_0_0_0_1 + 0.192857142857144*G0_1_0_1_0_0 - 0.0964285714285724*G0_1_0_2_0_1 - 0.0964285714285729*G0_1_0_3_0_0 + 0.192857142857143*G0_1_0_3_0_1 + 0.0964285714285729*G0_1_0_4_0_0 - 0.289285714285716*G0_1_0_5_0_0 - 0.192857142857143*G0_1_0_5_0_1 + 0.0964285714285722*G0_1_0_6_1_0 + 0.0964285714285721*G0_1_0_6_1_1 + 0.192857142857144*G0_1_0_7_1_0 - 0.0964285714285724*G0_1_0_8_1_1 - 0.0964285714285729*G0_1_0_9_1_0 + 0.192857142857143*G0_1_0_9_1_1 + 0.0964285714285729*G0_1_0_10_1_0 - 0.289285714285716*G0_1_0_11_1_0 - 0.192857142857143*G0_1_0_11_1_1; + A[85] = A[87] + 0.337499999999999*G0_0_0_0_0_0 + 0.337499999999999*G0_0_0_0_0_1 - 0.144642857142857*G0_0_0_1_0_0 + 0.819642857142856*G0_0_0_2_0_1 + 1.15714285714286*G0_0_0_3_0_0 + 0.192857142857142*G0_0_0_3_0_1 - 1.15714285714286*G0_0_0_4_0_0 - 1.15714285714285*G0_0_0_4_0_1 - 0.192857142857142*G0_0_0_5_0_0 - 0.192857142857142*G0_0_0_5_0_1 + 0.337499999999999*G0_0_0_6_1_0 + 0.337499999999999*G0_0_0_6_1_1 - 0.144642857142857*G0_0_0_7_1_0 + 0.819642857142856*G0_0_0_8_1_1 + 1.15714285714286*G0_0_0_9_1_0 + 0.192857142857142*G0_0_0_9_1_1 - 1.15714285714286*G0_0_0_10_1_0 - 1.15714285714285*G0_0_0_10_1_1 - 0.192857142857142*G0_0_0_11_1_0 - 0.192857142857142*G0_0_0_11_1_1 + 0.578571428571429*G0_0_1_0_0_0 + 0.578571428571429*G0_0_1_0_0_1 + 0.578571428571428*G0_0_1_2_0_1 + 0.578571428571426*G0_0_1_3_0_0 - 0.578571428571426*G0_0_1_4_0_0 - 1.15714285714286*G0_0_1_4_0_1 - 0.578571428571429*G0_0_1_5_0_0 + 0.578571428571429*G0_0_1_6_1_0 + 0.578571428571429*G0_0_1_6_1_1 + 0.578571428571428*G0_0_1_8_1_1 + 0.578571428571426*G0_0_1_9_1_0 - 0.578571428571426*G0_0_1_10_1_0 - 1.15714285714286*G0_0_1_10_1_1 - 0.578571428571429*G0_0_1_11_1_0 + 0.385714285714284*G0_1_0_0_0_0 + 0.385714285714284*G0_1_0_0_0_1 + 0.385714285714286*G0_1_0_2_0_1 + 0.385714285714286*G0_1_0_3_0_0 - 0.385714285714286*G0_1_0_4_0_0 - 0.77142857142857*G0_1_0_4_0_1 - 0.385714285714282*G0_1_0_5_0_0 + 0.385714285714284*G0_1_0_6_1_0 + 0.385714285714284*G0_1_0_6_1_1 + 0.385714285714286*G0_1_0_8_1_1 + 0.385714285714286*G0_1_0_9_1_0 - 0.385714285714286*G0_1_0_10_1_0 - 0.77142857142857*G0_1_0_10_1_1 - 0.385714285714282*G0_1_0_11_1_0 + 0.626785714285715*G0_1_1_0_0_0 + 0.626785714285716*G0_1_1_0_0_1 - 0.0482142857142871*G0_1_1_1_0_0 + 0.337500000000001*G0_1_1_2_0_1 - 0.385714285714289*G0_1_1_3_0_1 - 0.964285714285716*G0_1_1_4_0_1 - 0.578571428571429*G0_1_1_5_0_0 + 0.385714285714289*G0_1_1_5_0_1 + 0.626785714285715*G0_1_1_6_1_0 + 0.626785714285716*G0_1_1_6_1_1 - 0.0482142857142871*G0_1_1_7_1_0 + 0.337500000000001*G0_1_1_8_1_1 - 0.385714285714289*G0_1_1_9_1_1 - 0.964285714285716*G0_1_1_10_1_1 - 0.578571428571429*G0_1_1_11_1_0 + 0.385714285714289*G0_1_1_11_1_1; + A[297] = A[87]; + A[127] = -A[87] + 0.385714285714286*G0_1_0_0_0_0 + 0.385714285714286*G0_1_0_0_0_1 + 0.385714285714287*G0_1_0_1_0_0 + 0.385714285714287*G0_1_0_3_0_1 - 0.385714285714286*G0_1_0_4_0_1 - 0.771428571428573*G0_1_0_5_0_0 - 0.385714285714287*G0_1_0_5_0_1 + 0.385714285714286*G0_1_0_6_1_0 + 0.385714285714286*G0_1_0_6_1_1 + 0.385714285714287*G0_1_0_7_1_0 + 0.385714285714287*G0_1_0_9_1_1 - 0.385714285714286*G0_1_0_10_1_1 - 0.771428571428573*G0_1_0_11_1_0 - 0.385714285714287*G0_1_0_11_1_1 - 0.433928571428573*G0_1_1_0_0_0 - 0.433928571428572*G0_1_1_0_0_1 + 0.433928571428572*G0_1_1_1_0_0 - 0.530357142857144*G0_1_1_2_0_1 - 0.192857142857143*G0_1_1_3_0_0 + 0.771428571428573*G0_1_1_3_0_1 + 0.192857142857143*G0_1_1_4_0_0 + 0.964285714285716*G0_1_1_4_0_1 - 0.771428571428573*G0_1_1_5_0_1 - 0.433928571428573*G0_1_1_6_1_0 - 0.433928571428572*G0_1_1_6_1_1 + 0.433928571428572*G0_1_1_7_1_0 - 0.530357142857144*G0_1_1_8_1_1 - 0.192857142857143*G0_1_1_9_1_0 + 0.771428571428573*G0_1_1_9_1_1 + 0.192857142857143*G0_1_1_10_1_0 + 0.964285714285716*G0_1_1_10_1_1 - 0.771428571428573*G0_1_1_11_1_1; + A[146] = -A[144] + 0.385714285714286*G0_0_1_0_0_0 + 0.385714285714286*G0_0_1_0_0_1 + 0.385714285714287*G0_0_1_1_0_0 + 0.385714285714287*G0_0_1_3_0_1 - 0.385714285714286*G0_0_1_4_0_1 - 0.771428571428573*G0_0_1_5_0_0 - 0.385714285714287*G0_0_1_5_0_1 + 0.385714285714286*G0_0_1_6_1_0 + 0.385714285714286*G0_0_1_6_1_1 + 0.385714285714287*G0_0_1_7_1_0 + 0.385714285714287*G0_0_1_9_1_1 - 0.385714285714286*G0_0_1_10_1_1 - 0.771428571428573*G0_0_1_11_1_0 - 0.385714285714287*G0_0_1_11_1_1 - 0.433928571428572*G0_1_1_0_0_0 - 0.433928571428572*G0_1_1_0_0_1 + 0.433928571428572*G0_1_1_1_0_0 - 0.530357142857144*G0_1_1_2_0_1 - 0.192857142857143*G0_1_1_3_0_0 + 0.771428571428573*G0_1_1_3_0_1 + 0.192857142857143*G0_1_1_4_0_0 + 0.964285714285716*G0_1_1_4_0_1 - 0.771428571428573*G0_1_1_5_0_1 - 0.433928571428572*G0_1_1_6_1_0 - 0.433928571428572*G0_1_1_6_1_1 + 0.433928571428572*G0_1_1_7_1_0 - 0.530357142857144*G0_1_1_8_1_1 - 0.192857142857143*G0_1_1_9_1_0 + 0.771428571428573*G0_1_1_9_1_1 + 0.192857142857143*G0_1_1_10_1_0 + 0.964285714285716*G0_1_1_10_1_1 - 0.771428571428573*G0_1_1_11_1_1; + A[104] = A[85] - 0.0964285714285728*G0_0_1_0_0_0 - 0.0964285714285726*G0_0_1_0_0_1 + 0.192857142857142*G0_0_1_1_0_0 - 0.289285714285715*G0_0_1_2_0_1 - 0.289285714285713*G0_0_1_3_0_0 + 0.192857142857143*G0_0_1_3_0_1 + 0.289285714285713*G0_0_1_4_0_0 + 0.385714285714287*G0_0_1_4_0_1 - 0.0964285714285698*G0_0_1_5_0_0 - 0.192857142857143*G0_0_1_5_0_1 - 0.0964285714285728*G0_0_1_6_1_0 - 0.0964285714285726*G0_0_1_6_1_1 + 0.192857142857142*G0_0_1_7_1_0 - 0.289285714285715*G0_0_1_8_1_1 - 0.289285714285713*G0_0_1_9_1_0 + 0.192857142857143*G0_0_1_9_1_1 + 0.289285714285713*G0_0_1_10_1_0 + 0.385714285714287*G0_0_1_10_1_1 - 0.0964285714285698*G0_0_1_11_1_0 - 0.192857142857143*G0_0_1_11_1_1 + 0.0964285714285727*G0_1_0_0_0_0 + 0.0964285714285726*G0_1_0_0_0_1 - 0.192857142857142*G0_1_0_1_0_0 + 0.289285714285714*G0_1_0_2_0_1 + 0.289285714285713*G0_1_0_3_0_0 - 0.192857142857143*G0_1_0_3_0_1 - 0.289285714285713*G0_1_0_4_0_0 - 0.385714285714287*G0_1_0_4_0_1 + 0.0964285714285698*G0_1_0_5_0_0 + 0.192857142857143*G0_1_0_5_0_1 + 0.0964285714285727*G0_1_0_6_1_0 + 0.0964285714285726*G0_1_0_6_1_1 - 0.192857142857142*G0_1_0_7_1_0 + 0.289285714285714*G0_1_0_8_1_1 + 0.289285714285713*G0_1_0_9_1_0 - 0.192857142857143*G0_1_0_9_1_1 - 0.289285714285713*G0_1_0_10_1_0 - 0.385714285714287*G0_1_0_10_1_1 + 0.0964285714285698*G0_1_0_11_1_0 + 0.192857142857143*G0_1_0_11_1_1; + A[106] = -A[104] + 0.723214285714285*G0_0_1_0_0_0 + 0.723214285714286*G0_0_1_0_0_1 + 0.819642857142858*G0_0_1_1_0_0 - 1.10892857142857*G0_0_1_2_0_1 - 2.12142857142857*G0_0_1_3_0_0 - 0.192857142857142*G0_0_1_3_0_1 + 2.12142857142857*G0_0_1_4_0_0 + 0.385714285714285*G0_0_1_4_0_1 - 1.54285714285714*G0_0_1_5_0_0 + 0.192857142857142*G0_0_1_5_0_1 + 0.723214285714285*G0_0_1_6_1_0 + 0.723214285714286*G0_0_1_6_1_1 + 0.819642857142858*G0_0_1_7_1_0 - 1.10892857142857*G0_0_1_8_1_1 - 2.12142857142857*G0_0_1_9_1_0 - 0.192857142857142*G0_0_1_9_1_1 + 2.12142857142857*G0_0_1_10_1_0 + 0.385714285714285*G0_0_1_10_1_1 - 1.54285714285714*G0_0_1_11_1_0 + 0.192857142857142*G0_0_1_11_1_1 + 1.54285714285714*G0_1_1_0_0_0 + 1.54285714285714*G0_1_1_0_0_1 + 0.771428571428572*G0_1_1_1_0_0 - 0.578571428571428*G0_1_1_2_0_1 - 1.92857142857143*G0_1_1_3_0_0 - 0.578571428571429*G0_1_1_3_0_1 + 1.92857142857143*G0_1_1_4_0_0 - 0.964285714285716*G0_1_1_4_0_1 - 2.31428571428572*G0_1_1_5_0_0 + 0.578571428571429*G0_1_1_5_0_1 + 1.54285714285714*G0_1_1_6_1_0 + 1.54285714285714*G0_1_1_6_1_1 + 0.771428571428572*G0_1_1_7_1_0 - 0.578571428571428*G0_1_1_8_1_1 - 1.92857142857143*G0_1_1_9_1_0 - 0.578571428571429*G0_1_1_9_1_1 + 1.92857142857143*G0_1_1_10_1_0 - 0.964285714285716*G0_1_1_10_1_1 - 2.31428571428572*G0_1_1_11_1_0 + 0.578571428571429*G0_1_1_11_1_1; + A[337] = A[127]; + A[125] = A[106] - 0.819642857142858*G0_0_1_0_0_0 - 0.819642857142858*G0_0_1_0_0_1 - 0.626785714285715*G0_0_1_1_0_0 + 0.819642857142857*G0_0_1_2_0_1 + 1.83214285714286*G0_0_1_3_0_0 + 0.385714285714285*G0_0_1_3_0_1 - 1.83214285714286*G0_0_1_4_0_0 + 1.44642857142857*G0_0_1_5_0_0 - 0.385714285714285*G0_0_1_5_0_1 - 0.819642857142858*G0_0_1_6_1_0 - 0.819642857142858*G0_0_1_6_1_1 - 0.626785714285715*G0_0_1_7_1_0 + 0.819642857142857*G0_0_1_8_1_1 + 1.83214285714286*G0_0_1_9_1_0 + 0.385714285714285*G0_0_1_9_1_1 - 1.83214285714286*G0_0_1_10_1_0 + 1.44642857142857*G0_0_1_11_1_0 - 0.385714285714285*G0_0_1_11_1_1 + 0.819642857142858*G0_1_0_0_0_0 + 0.819642857142858*G0_1_0_0_0_1 + 0.626785714285715*G0_1_0_1_0_0 - 0.819642857142857*G0_1_0_2_0_1 - 1.83214285714286*G0_1_0_3_0_0 - 0.385714285714285*G0_1_0_3_0_1 + 1.83214285714286*G0_1_0_4_0_0 - 1.44642857142857*G0_1_0_5_0_0 + 0.385714285714285*G0_1_0_5_0_1 + 0.819642857142858*G0_1_0_6_1_0 + 0.819642857142858*G0_1_0_6_1_1 + 0.626785714285715*G0_1_0_7_1_0 - 0.819642857142857*G0_1_0_8_1_1 - 1.83214285714286*G0_1_0_9_1_0 - 0.385714285714285*G0_1_0_9_1_1 + 1.83214285714286*G0_1_0_10_1_0 - 1.44642857142857*G0_1_0_11_1_0 + 0.385714285714285*G0_1_0_11_1_1; + A[164] = -A[376] + 0.385714285714286*G0_0_1_0_0_0 + 0.385714285714286*G0_0_1_0_0_1 + 0.385714285714284*G0_0_1_1_0_0 + 0.385714285714283*G0_0_1_3_0_1 - 0.385714285714287*G0_0_1_4_0_1 - 0.77142857142857*G0_0_1_5_0_0 - 0.385714285714283*G0_0_1_5_0_1 + 0.385714285714286*G0_0_1_6_1_0 + 0.385714285714286*G0_0_1_6_1_1 + 0.385714285714284*G0_0_1_7_1_0 + 0.385714285714283*G0_0_1_9_1_1 - 0.385714285714287*G0_0_1_10_1_1 - 0.77142857142857*G0_0_1_11_1_0 - 0.385714285714283*G0_0_1_11_1_1 - 0.0482142857142866*G0_1_1_0_0_0 - 0.0482142857142863*G0_1_1_0_0_1 + 0.819642857142855*G0_1_1_1_0_0 - 0.530357142857142*G0_1_1_2_0_1 - 0.192857142857143*G0_1_1_3_0_0 + 1.15714285714285*G0_1_1_3_0_1 + 0.192857142857143*G0_1_1_4_0_0 + 0.578571428571429*G0_1_1_4_0_1 - 0.771428571428569*G0_1_1_5_0_0 - 1.15714285714286*G0_1_1_5_0_1 - 0.0482142857142866*G0_1_1_6_1_0 - 0.0482142857142863*G0_1_1_6_1_1 + 0.819642857142855*G0_1_1_7_1_0 - 0.530357142857142*G0_1_1_8_1_1 - 0.192857142857143*G0_1_1_9_1_0 + 1.15714285714285*G0_1_1_9_1_1 + 0.192857142857143*G0_1_1_10_1_0 + 0.578571428571429*G0_1_1_10_1_1 - 0.771428571428569*G0_1_1_11_1_0 - 1.15714285714286*G0_1_1_11_1_1; + A[335] = A[125]; + A[354] = A[144]; + A[316] = A[106]; + A[166] = A[376]; + A[187] = A[397]; + A[204] = 0.0; + A[229] = 0.0; + A[18] = 0.0; + A[286] = 0.0; + A[258] = A[48]; + A[39] = 0.0; + A[307] = 0.0; + A[279] = -A[379] + 0.289285714285716*G0_0_0_0_0_0 + 0.289285714285716*G0_0_0_0_0_1 + 0.0964285714285729*G0_0_0_1_0_0 - 1.83214285714286*G0_0_0_2_0_1 - 3.85714285714286*G0_0_0_3_0_0 - 1.92857142857143*G0_0_0_3_0_1 + 3.85714285714286*G0_0_0_4_0_0 + 1.54285714285714*G0_0_0_4_0_1 - 0.385714285714289*G0_0_0_5_0_0 + 1.92857142857143*G0_0_0_5_0_1 + 0.289285714285716*G0_0_0_6_1_0 + 0.289285714285716*G0_0_0_6_1_1 + 0.0964285714285729*G0_0_0_7_1_0 - 1.83214285714286*G0_0_0_8_1_1 - 3.85714285714286*G0_0_0_9_1_0 - 1.92857142857143*G0_0_0_9_1_1 + 3.85714285714286*G0_0_0_10_1_0 + 1.54285714285714*G0_0_0_10_1_1 - 0.385714285714289*G0_0_0_11_1_0 + 1.92857142857143*G0_0_0_11_1_1 - 1.54285714285714*G0_0_1_0_0_0 - 1.54285714285714*G0_0_1_0_0_1 - 1.54285714285714*G0_0_1_2_0_1 - 1.54285714285714*G0_0_1_3_0_0 + 1.54285714285714*G0_0_1_4_0_0 + 3.08571428571428*G0_0_1_4_0_1 + 1.54285714285714*G0_0_1_5_0_0 - 1.54285714285714*G0_0_1_6_1_0 - 1.54285714285714*G0_0_1_6_1_1 - 1.54285714285714*G0_0_1_8_1_1 - 1.54285714285714*G0_0_1_9_1_0 + 1.54285714285714*G0_0_1_10_1_0 + 3.08571428571428*G0_0_1_10_1_1 + 1.54285714285714*G0_0_1_11_1_0; + A[393] = A[279] + 0.578571428571428*G0_0_1_0_0_0 + 0.578571428571427*G0_0_1_0_0_1 - 0.385714285714285*G0_0_1_1_0_0 + 0.964285714285712*G0_0_1_2_0_1 + 0.964285714285713*G0_0_1_3_0_0 - 0.385714285714285*G0_0_1_3_0_1 - 0.964285714285713*G0_0_1_4_0_0 - 1.54285714285714*G0_0_1_4_0_1 - 0.192857142857143*G0_0_1_5_0_0 + 0.385714285714286*G0_0_1_5_0_1 + 0.578571428571428*G0_0_1_6_1_0 + 0.578571428571427*G0_0_1_6_1_1 - 0.385714285714285*G0_0_1_7_1_0 + 0.964285714285712*G0_0_1_8_1_1 + 0.964285714285713*G0_0_1_9_1_0 - 0.385714285714285*G0_0_1_9_1_1 - 0.964285714285713*G0_0_1_10_1_0 - 1.54285714285714*G0_0_1_10_1_1 - 0.192857142857143*G0_0_1_11_1_0 + 0.385714285714286*G0_0_1_11_1_1 - 0.578571428571428*G0_1_0_0_0_0 - 0.578571428571427*G0_1_0_0_0_1 + 0.385714285714285*G0_1_0_1_0_0 - 0.964285714285712*G0_1_0_2_0_1 - 0.964285714285714*G0_1_0_3_0_0 + 0.385714285714284*G0_1_0_3_0_1 + 0.964285714285714*G0_1_0_4_0_0 + 1.54285714285714*G0_1_0_4_0_1 + 0.192857142857143*G0_1_0_5_0_0 - 0.385714285714286*G0_1_0_5_0_1 - 0.578571428571428*G0_1_0_6_1_0 - 0.578571428571427*G0_1_0_6_1_1 + 0.385714285714285*G0_1_0_7_1_0 - 0.964285714285712*G0_1_0_8_1_1 - 0.964285714285714*G0_1_0_9_1_0 + 0.385714285714284*G0_1_0_9_1_1 + 0.964285714285714*G0_1_0_10_1_0 + 1.54285714285714*G0_1_0_10_1_1 + 0.192857142857143*G0_1_0_11_1_0 - 0.385714285714286*G0_1_0_11_1_1; + A[398] = -A[393] + 0.289285714285716*G0_0_0_0_0_0 + 0.289285714285716*G0_0_0_0_0_1 + 0.0964285714285726*G0_0_0_1_0_0 - 1.83214285714286*G0_0_0_2_0_1 - 3.85714285714285*G0_0_0_3_0_0 - 1.92857142857143*G0_0_0_3_0_1 + 3.85714285714285*G0_0_0_4_0_0 + 1.54285714285714*G0_0_0_4_0_1 - 0.385714285714289*G0_0_0_5_0_0 + 1.92857142857143*G0_0_0_5_0_1 + 0.289285714285716*G0_0_0_6_1_0 + 0.289285714285716*G0_0_0_6_1_1 + 0.0964285714285726*G0_0_0_7_1_0 - 1.83214285714286*G0_0_0_8_1_1 - 3.85714285714285*G0_0_0_9_1_0 - 1.92857142857143*G0_0_0_9_1_1 + 3.85714285714285*G0_0_0_10_1_0 + 1.54285714285714*G0_0_0_10_1_1 - 0.385714285714289*G0_0_0_11_1_0 + 1.92857142857143*G0_0_0_11_1_1 - 1.54285714285714*G0_1_0_0_0_0 - 1.54285714285714*G0_1_0_0_0_1 - 1.54285714285714*G0_1_0_2_0_1 - 1.54285714285714*G0_1_0_3_0_0 + 1.54285714285714*G0_1_0_4_0_0 + 3.08571428571429*G0_1_0_4_0_1 + 1.54285714285714*G0_1_0_5_0_0 - 1.54285714285714*G0_1_0_6_1_0 - 1.54285714285714*G0_1_0_6_1_1 - 1.54285714285714*G0_1_0_8_1_1 - 1.54285714285714*G0_1_0_9_1_0 + 1.54285714285714*G0_1_0_10_1_0 + 3.08571428571429*G0_1_0_10_1_1 + 1.54285714285714*G0_1_0_11_1_0; + A[350] = A[398] + 0.150000000000001*G0_0_0_0_0_0 + 0.15*G0_0_0_0_0_1 - 1.2*G0_0_0_1_0_0 + 0.675*G0_0_0_2_0_1 - 1.875*G0_0_0_3_0_1 - 0.825000000000001*G0_0_0_4_0_1 + 1.05*G0_0_0_5_0_0 + 1.875*G0_0_0_5_0_1 + 0.150000000000001*G0_0_0_6_1_0 + 0.15*G0_0_0_6_1_1 - 1.2*G0_0_0_7_1_0 + 0.675*G0_0_0_8_1_1 - 1.875*G0_0_0_9_1_1 - 0.825000000000001*G0_0_0_10_1_1 + 1.05*G0_0_0_11_1_0 + 1.875*G0_0_0_11_1_1 + 0.680357142857144*G0_0_1_0_0_0 + 0.680357142857144*G0_0_1_0_0_1 - 1.34464285714285*G0_0_1_1_0_0 + 0.337499999999999*G0_0_1_2_0_1 - 1.35*G0_0_1_3_0_0 - 3.03214285714285*G0_0_1_3_0_1 + 1.35*G0_0_1_4_0_0 - 1.01785714285714*G0_0_1_4_0_1 + 0.664285714285709*G0_0_1_5_0_0 + 3.03214285714285*G0_0_1_5_0_1 + 0.680357142857144*G0_0_1_6_1_0 + 0.680357142857144*G0_0_1_6_1_1 - 1.34464285714285*G0_0_1_7_1_0 + 0.337499999999999*G0_0_1_8_1_1 - 1.35*G0_0_1_9_1_0 - 3.03214285714285*G0_0_1_9_1_1 + 1.35*G0_0_1_10_1_0 - 1.01785714285714*G0_0_1_10_1_1 + 0.664285714285709*G0_0_1_11_1_0 + 3.03214285714285*G0_0_1_11_1_1 - 1.425*G0_1_0_1_0_0 + 0.45*G0_1_0_2_0_1 - 0.524999999999998*G0_1_0_3_0_0 - 2.4*G0_1_0_3_0_1 + 0.524999999999998*G0_1_0_4_0_0 - 0.450000000000002*G0_1_0_4_0_1 + 1.425*G0_1_0_5_0_0 + 2.4*G0_1_0_5_0_1 - 1.425*G0_1_0_7_1_0 + 0.45*G0_1_0_8_1_1 - 0.524999999999998*G0_1_0_9_1_0 - 2.4*G0_1_0_9_1_1 + 0.524999999999998*G0_1_0_10_1_0 - 0.450000000000002*G0_1_0_10_1_1 + 1.425*G0_1_0_11_1_0 + 2.4*G0_1_0_11_1_1 - 0.916071428571428*G0_1_1_0_0_0 - 0.916071428571428*G0_1_1_0_0_1 - 0.316071428571425*G0_1_1_1_0_0 - 0.562500000000001*G0_1_1_2_0_1 - 0.524999999999999*G0_1_1_3_0_0 - 0.278571428571423*G0_1_1_3_0_1 + 0.524999999999999*G0_1_1_4_0_0 + 1.47857142857143*G0_1_1_4_0_1 + 1.23214285714285*G0_1_1_5_0_0 + 0.278571428571423*G0_1_1_5_0_1 - 0.916071428571428*G0_1_1_6_1_0 - 0.916071428571428*G0_1_1_6_1_1 - 0.316071428571425*G0_1_1_7_1_0 - 0.562500000000001*G0_1_1_8_1_1 - 0.524999999999999*G0_1_1_9_1_0 - 0.278571428571423*G0_1_1_9_1_1 + 0.524999999999999*G0_1_1_10_1_0 + 1.47857142857143*G0_1_1_10_1_1 + 1.23214285714285*G0_1_1_11_1_0 + 0.278571428571423*G0_1_1_11_1_1; + A[217] = A[350] - 1.64464285714286*G0_0_1_0_0_0 - 1.64464285714286*G0_0_1_0_0_1 - 0.466071428571429*G0_0_1_1_0_0 - 0.466071428571428*G0_0_1_2_0_1 + 0.246428571428571*G0_0_1_3_0_0 + 0.246428571428571*G0_0_1_3_0_1 - 0.246428571428571*G0_0_1_4_0_0 + 2.11071428571429*G0_0_1_4_0_1 + 2.11071428571429*G0_0_1_5_0_0 - 0.246428571428571*G0_0_1_5_0_1 - 1.64464285714286*G0_0_1_6_1_0 - 1.64464285714286*G0_0_1_6_1_1 - 0.466071428571429*G0_0_1_7_1_0 - 0.466071428571428*G0_0_1_8_1_1 + 0.246428571428571*G0_0_1_9_1_0 + 0.246428571428571*G0_0_1_9_1_1 - 0.246428571428571*G0_0_1_10_1_0 + 2.11071428571429*G0_0_1_10_1_1 + 2.11071428571429*G0_0_1_11_1_0 - 0.246428571428571*G0_0_1_11_1_1 + 1.64464285714286*G0_1_0_0_0_0 + 1.64464285714286*G0_1_0_0_0_1 + 0.466071428571429*G0_1_0_1_0_0 + 0.466071428571428*G0_1_0_2_0_1 - 0.246428571428571*G0_1_0_3_0_0 - 0.246428571428571*G0_1_0_3_0_1 + 0.246428571428571*G0_1_0_4_0_0 - 2.11071428571429*G0_1_0_4_0_1 - 2.11071428571429*G0_1_0_5_0_0 + 0.246428571428571*G0_1_0_5_0_1 + 1.64464285714286*G0_1_0_6_1_0 + 1.64464285714286*G0_1_0_6_1_1 + 0.466071428571429*G0_1_0_7_1_0 + 0.466071428571428*G0_1_0_8_1_1 - 0.246428571428571*G0_1_0_9_1_0 - 0.246428571428571*G0_1_0_9_1_1 + 0.246428571428571*G0_1_0_10_1_0 - 2.11071428571429*G0_1_0_10_1_1 - 2.11071428571429*G0_1_0_11_1_0 + 0.246428571428571*G0_1_0_11_1_1; + A[7] = A[217]; + A[183] = A[393]; + A[140] = A[350]; + A[65] = A[313] + 0.0964285714285711*G0_0_1_0_0_0 + 0.0964285714285711*G0_0_1_0_0_1 - 0.0964285714285711*G0_0_1_1_0_0 + 0.192857142857142*G0_0_1_2_0_1 + 0.192857142857142*G0_0_1_3_0_0 - 0.0964285714285708*G0_0_1_3_0_1 - 0.192857142857142*G0_0_1_4_0_0 - 0.289285714285713*G0_0_1_4_0_1 + 0.0964285714285711*G0_0_1_5_0_1 + 0.0964285714285711*G0_0_1_6_1_0 + 0.0964285714285711*G0_0_1_6_1_1 - 0.0964285714285711*G0_0_1_7_1_0 + 0.192857142857142*G0_0_1_8_1_1 + 0.192857142857142*G0_0_1_9_1_0 - 0.0964285714285708*G0_0_1_9_1_1 - 0.192857142857142*G0_0_1_10_1_0 - 0.289285714285713*G0_0_1_10_1_1 + 0.0964285714285711*G0_0_1_11_1_1 - 0.0964285714285712*G0_1_0_0_0_0 - 0.0964285714285711*G0_1_0_0_0_1 + 0.096428571428571*G0_1_0_1_0_0 - 0.192857142857142*G0_1_0_2_0_1 - 0.192857142857142*G0_1_0_3_0_0 + 0.0964285714285708*G0_1_0_3_0_1 + 0.192857142857142*G0_1_0_4_0_0 + 0.289285714285713*G0_1_0_4_0_1 - 0.0964285714285711*G0_1_0_5_0_1 - 0.0964285714285712*G0_1_0_6_1_0 - 0.0964285714285711*G0_1_0_6_1_1 + 0.096428571428571*G0_1_0_7_1_0 - 0.192857142857142*G0_1_0_8_1_1 - 0.192857142857142*G0_1_0_9_1_0 + 0.0964285714285708*G0_1_0_9_1_1 + 0.192857142857142*G0_1_0_10_1_0 + 0.289285714285713*G0_1_0_10_1_1 - 0.0964285714285711*G0_1_0_11_1_1; + A[165] = -A[65] - 0.433928571428573*G0_0_0_0_0_0 - 0.433928571428573*G0_0_0_0_0_1 - 0.530357142857144*G0_0_0_1_0_0 + 0.433928571428571*G0_0_0_2_0_1 + 0.771428571428571*G0_0_0_3_0_0 - 0.192857142857143*G0_0_0_3_0_1 - 0.771428571428571*G0_0_0_4_0_0 + 0.964285714285717*G0_0_0_5_0_0 + 0.192857142857143*G0_0_0_5_0_1 - 0.433928571428573*G0_0_0_6_1_0 - 0.433928571428573*G0_0_0_6_1_1 - 0.530357142857144*G0_0_0_7_1_0 + 0.433928571428571*G0_0_0_8_1_1 + 0.771428571428571*G0_0_0_9_1_0 - 0.192857142857143*G0_0_0_9_1_1 - 0.771428571428571*G0_0_0_10_1_0 + 0.964285714285717*G0_0_0_11_1_0 + 0.192857142857143*G0_0_0_11_1_1 + 0.385714285714285*G0_0_1_0_0_0 + 0.385714285714285*G0_0_1_0_0_1 + 0.385714285714285*G0_0_1_2_0_1 + 0.385714285714285*G0_0_1_3_0_0 - 0.385714285714285*G0_0_1_4_0_0 - 0.77142857142857*G0_0_1_4_0_1 - 0.385714285714284*G0_0_1_5_0_0 + 0.385714285714285*G0_0_1_6_1_0 + 0.385714285714285*G0_0_1_6_1_1 + 0.385714285714285*G0_0_1_8_1_1 + 0.385714285714285*G0_0_1_9_1_0 - 0.385714285714285*G0_0_1_10_1_0 - 0.77142857142857*G0_0_1_10_1_1 - 0.385714285714284*G0_0_1_11_1_0; + A[375] = A[165]; + A[86] = A[373] - 0.337500000000002*G0_0_0_0_0_0 - 0.337500000000001*G0_0_0_0_0_1 + 1.6875*G0_0_0_1_0_0 - 3.7125*G0_0_0_2_0_1 - 5.4*G0_0_0_3_0_0 + 5.4*G0_0_0_4_0_0 + 4.05*G0_0_0_4_0_1 - 1.35*G0_0_0_5_0_0 - 0.337500000000002*G0_0_0_6_1_0 - 0.337500000000001*G0_0_0_6_1_1 + 1.6875*G0_0_0_7_1_0 - 3.7125*G0_0_0_8_1_1 - 5.4*G0_0_0_9_1_0 + 5.4*G0_0_0_10_1_0 + 4.05*G0_0_0_10_1_1 - 1.35*G0_0_0_11_1_0 + 2.60357142857142*G0_0_1_1_0_0 - 2.60357142857143*G0_0_1_2_0_1 - 2.60357142857143*G0_0_1_3_0_0 + 2.60357142857142*G0_0_1_3_0_1 + 2.60357142857143*G0_0_1_4_0_0 + 2.60357142857143*G0_0_1_4_0_1 - 2.60357142857142*G0_0_1_5_0_0 - 2.60357142857142*G0_0_1_5_0_1 + 2.60357142857142*G0_0_1_7_1_0 - 2.60357142857143*G0_0_1_8_1_1 - 2.60357142857143*G0_0_1_9_1_0 + 2.60357142857142*G0_0_1_9_1_1 + 2.60357142857143*G0_0_1_10_1_0 + 2.60357142857143*G0_0_1_10_1_1 - 2.60357142857142*G0_0_1_11_1_0 - 2.60357142857142*G0_0_1_11_1_1 + 1.44642857142857*G0_1_0_1_0_0 - 1.44642857142857*G0_1_0_2_0_1 - 1.44642857142857*G0_1_0_3_0_0 + 1.44642857142857*G0_1_0_3_0_1 + 1.44642857142857*G0_1_0_4_0_0 + 1.44642857142857*G0_1_0_4_0_1 - 1.44642857142857*G0_1_0_5_0_0 - 1.44642857142857*G0_1_0_5_0_1 + 1.44642857142857*G0_1_0_7_1_0 - 1.44642857142857*G0_1_0_8_1_1 - 1.44642857142857*G0_1_0_9_1_0 + 1.44642857142857*G0_1_0_9_1_1 + 1.44642857142857*G0_1_0_10_1_0 + 1.44642857142857*G0_1_0_10_1_1 - 1.44642857142857*G0_1_0_11_1_0 - 1.44642857142857*G0_1_0_11_1_1 + 0.337499999999998*G0_1_1_0_0_0 + 0.337499999999999*G0_1_1_0_0_1 + 3.7125*G0_1_1_1_0_0 - 1.6875*G0_1_1_2_0_1 + 5.39999999999999*G0_1_1_3_0_1 + 1.35*G0_1_1_4_0_1 - 4.04999999999999*G0_1_1_5_0_0 - 5.4*G0_1_1_5_0_1 + 0.337499999999998*G0_1_1_6_1_0 + 0.337499999999999*G0_1_1_6_1_1 + 3.7125*G0_1_1_7_1_0 - 1.6875*G0_1_1_8_1_1 + 5.39999999999999*G0_1_1_9_1_1 + 1.35*G0_1_1_10_1_1 - 4.04999999999999*G0_1_1_11_1_0 - 5.4*G0_1_1_11_1_1; + A[294] = -A[86] - 0.385714285714285*G0_0_1_0_0_0 - 0.385714285714285*G0_0_1_0_0_1 + 0.385714285714286*G0_0_1_1_0_0 - 0.77142857142857*G0_0_1_2_0_1 - 0.771428571428568*G0_0_1_3_0_0 + 0.385714285714288*G0_0_1_3_0_1 + 0.771428571428568*G0_0_1_4_0_0 + 1.15714285714285*G0_0_1_4_0_1 - 0.385714285714288*G0_0_1_5_0_1 - 0.385714285714285*G0_0_1_6_1_0 - 0.385714285714285*G0_0_1_6_1_1 + 0.385714285714286*G0_0_1_7_1_0 - 0.77142857142857*G0_0_1_8_1_1 - 0.771428571428568*G0_0_1_9_1_0 + 0.385714285714288*G0_0_1_9_1_1 + 0.771428571428568*G0_0_1_10_1_0 + 1.15714285714285*G0_0_1_10_1_1 - 0.385714285714288*G0_0_1_11_1_1 + 0.144642857142857*G0_1_1_0_0_0 + 0.144642857142857*G0_1_1_0_0_1 + 1.39821428571429*G0_1_1_1_0_0 + 0.433928571428572*G0_1_1_2_0_1 + 2.12142857142857*G0_1_1_3_0_0 + 3.08571428571429*G0_1_1_3_0_1 - 2.12142857142857*G0_1_1_4_0_0 - 0.578571428571429*G0_1_1_4_0_1 - 1.54285714285714*G0_1_1_5_0_0 - 3.08571428571429*G0_1_1_5_0_1 + 0.144642857142857*G0_1_1_6_1_0 + 0.144642857142857*G0_1_1_6_1_1 + 1.39821428571429*G0_1_1_7_1_0 + 0.433928571428572*G0_1_1_8_1_1 + 2.12142857142857*G0_1_1_9_1_0 + 3.08571428571429*G0_1_1_9_1_1 - 2.12142857142857*G0_1_1_10_1_0 - 0.578571428571429*G0_1_1_10_1_1 - 1.54285714285714*G0_1_1_11_1_0 - 3.08571428571429*G0_1_1_11_1_1; + A[84] = A[294]; + A[321] = 0.0; + A[392] = A[259] + 0.0642857142857146*G0_0_1_0_0_0 + 0.0642857142857146*G0_0_1_0_0_1 + 0.0642857142857142*G0_0_1_1_0_0 + 0.0642857142857145*G0_0_1_3_0_1 - 0.0642857142857154*G0_0_1_4_0_1 - 0.128571428571429*G0_0_1_5_0_0 - 0.0642857142857144*G0_0_1_5_0_1 + 0.0642857142857146*G0_0_1_6_1_0 + 0.0642857142857146*G0_0_1_6_1_1 + 0.0642857142857142*G0_0_1_7_1_0 + 0.0642857142857145*G0_0_1_9_1_1 - 0.0642857142857154*G0_0_1_10_1_1 - 0.128571428571429*G0_0_1_11_1_0 - 0.0642857142857144*G0_0_1_11_1_1 - 0.0642857142857146*G0_1_0_0_0_0 - 0.0642857142857146*G0_1_0_0_0_1 - 0.0642857142857142*G0_1_0_1_0_0 - 0.0642857142857145*G0_1_0_3_0_1 + 0.0642857142857154*G0_1_0_4_0_1 + 0.128571428571429*G0_1_0_5_0_0 + 0.0642857142857144*G0_1_0_5_0_1 - 0.0642857142857146*G0_1_0_6_1_0 - 0.0642857142857146*G0_1_0_6_1_1 - 0.0642857142857142*G0_1_0_7_1_0 - 0.0642857142857145*G0_1_0_9_1_1 + 0.0642857142857154*G0_1_0_10_1_1 + 0.128571428571429*G0_1_0_11_1_0 + 0.0642857142857144*G0_1_0_11_1_1; + A[319] = -A[392] + 1.25357142857143*G0_0_0_0_0_0 + 1.25357142857143*G0_0_0_0_0_1 + 0.675000000000002*G0_0_0_1_0_0 - 1.44642857142857*G0_0_0_2_0_1 - 3.47142857142857*G0_0_0_3_0_0 - 1.35*G0_0_0_3_0_1 + 3.47142857142857*G0_0_0_4_0_0 + 0.192857142857138*G0_0_0_4_0_1 - 1.92857142857143*G0_0_0_5_0_0 + 1.35*G0_0_0_5_0_1 + 1.25357142857143*G0_0_0_6_1_0 + 1.25357142857143*G0_0_0_6_1_1 + 0.675000000000002*G0_0_0_7_1_0 - 1.44642857142857*G0_0_0_8_1_1 - 3.47142857142857*G0_0_0_9_1_0 - 1.35*G0_0_0_9_1_1 + 3.47142857142857*G0_0_0_10_1_0 + 0.192857142857138*G0_0_0_10_1_1 - 1.92857142857143*G0_0_0_11_1_0 + 1.35*G0_0_0_11_1_1 + 0.208928571428573*G0_0_1_0_0_0 + 0.208928571428573*G0_0_1_0_0_1 - 0.273214285714285*G0_0_1_1_0_0 - 0.53035714285714*G0_0_1_2_0_1 - 1.54285714285714*G0_0_1_3_0_0 - 1.28571428571428*G0_0_1_3_0_1 + 1.54285714285714*G0_0_1_4_0_0 + 0.321428571428566*G0_0_1_4_0_1 + 0.0642857142857113*G0_0_1_5_0_0 + 1.28571428571428*G0_0_1_5_0_1 + 0.208928571428573*G0_0_1_6_1_0 + 0.208928571428573*G0_0_1_6_1_1 - 0.273214285714285*G0_0_1_7_1_0 - 0.53035714285714*G0_0_1_8_1_1 - 1.54285714285714*G0_0_1_9_1_0 - 1.28571428571428*G0_0_1_9_1_1 + 1.54285714285714*G0_0_1_10_1_0 + 0.321428571428566*G0_0_1_10_1_1 + 0.0642857142857113*G0_0_1_11_1_0 + 1.28571428571428*G0_0_1_11_1_1 - 0.241071428571428*G0_1_0_0_0_0 - 0.241071428571428*G0_1_0_0_0_1 + 0.24107142857143*G0_1_0_1_0_0 - 1.49464285714286*G0_1_0_2_0_1 - 2.50714285714285*G0_1_0_3_0_0 - 0.771428571428568*G0_1_0_3_0_1 + 2.50714285714285*G0_1_0_4_0_0 + 1.73571428571428*G0_1_0_4_0_1 + 0.771428571428568*G0_1_0_5_0_1 - 0.241071428571428*G0_1_0_6_1_0 - 0.241071428571428*G0_1_0_6_1_1 + 0.24107142857143*G0_1_0_7_1_0 - 1.49464285714286*G0_1_0_8_1_1 - 2.50714285714285*G0_1_0_9_1_0 - 0.771428571428568*G0_1_0_9_1_1 + 2.50714285714285*G0_1_0_10_1_0 + 1.73571428571428*G0_1_0_10_1_1 + 0.771428571428568*G0_1_0_11_1_1 - 1.67142857142857*G0_1_1_0_0_0 - 1.67142857142857*G0_1_1_0_0_1 - 1.67142857142857*G0_1_1_2_0_1 - 1.67142857142857*G0_1_1_3_0_0 + 1.67142857142857*G0_1_1_4_0_0 + 3.34285714285714*G0_1_1_4_0_1 + 1.67142857142857*G0_1_1_5_0_0 - 1.67142857142857*G0_1_1_6_1_0 - 1.67142857142857*G0_1_1_6_1_1 - 1.67142857142857*G0_1_1_8_1_1 - 1.67142857142857*G0_1_1_9_1_0 + 1.67142857142857*G0_1_1_10_1_0 + 3.34285714285714*G0_1_1_10_1_1 + 1.67142857142857*G0_1_1_11_1_0; + A[395] = A[319] - 0.385714285714287*G0_0_1_0_0_0 - 0.385714285714286*G0_0_1_0_0_1 + 0.578571428571429*G0_0_1_1_0_0 - 0.964285714285714*G0_0_1_2_0_1 - 0.964285714285714*G0_0_1_3_0_0 + 0.57857142857143*G0_0_1_3_0_1 + 0.964285714285714*G0_0_1_4_0_0 + 1.35*G0_0_1_4_0_1 - 0.192857142857142*G0_0_1_5_0_0 - 0.57857142857143*G0_0_1_5_0_1 - 0.385714285714287*G0_0_1_6_1_0 - 0.385714285714286*G0_0_1_6_1_1 + 0.578571428571429*G0_0_1_7_1_0 - 0.964285714285714*G0_0_1_8_1_1 - 0.964285714285714*G0_0_1_9_1_0 + 0.57857142857143*G0_0_1_9_1_1 + 0.964285714285714*G0_0_1_10_1_0 + 1.35*G0_0_1_10_1_1 - 0.192857142857142*G0_0_1_11_1_0 - 0.57857142857143*G0_0_1_11_1_1 + 0.385714285714287*G0_1_0_0_0_0 + 0.385714285714287*G0_1_0_0_0_1 - 0.578571428571429*G0_1_0_1_0_0 + 0.964285714285714*G0_1_0_2_0_1 + 0.964285714285714*G0_1_0_3_0_0 - 0.57857142857143*G0_1_0_3_0_1 - 0.964285714285714*G0_1_0_4_0_0 - 1.35*G0_1_0_4_0_1 + 0.192857142857142*G0_1_0_5_0_0 + 0.57857142857143*G0_1_0_5_0_1 + 0.385714285714287*G0_1_0_6_1_0 + 0.385714285714287*G0_1_0_6_1_1 - 0.578571428571429*G0_1_0_7_1_0 + 0.964285714285714*G0_1_0_8_1_1 + 0.964285714285714*G0_1_0_9_1_0 - 0.57857142857143*G0_1_0_9_1_1 - 0.964285714285714*G0_1_0_10_1_0 - 1.35*G0_1_0_10_1_1 + 0.192857142857142*G0_1_0_11_1_0 + 0.57857142857143*G0_1_0_11_1_1; + A[122] = -A[392] - 0.401785714285714*G0_0_1_0_0_0 - 0.401785714285714*G0_0_1_0_0_1 + 0.530357142857143*G0_0_1_1_0_0 - 1.64464285714286*G0_0_1_2_0_1 - 2.35714285714285*G0_0_1_3_0_0 - 0.182142857142856*G0_0_1_3_0_1 + 2.35714285714285*G0_0_1_4_0_0 + 2.04642857142857*G0_0_1_4_0_1 - 0.128571428571429*G0_0_1_5_0_0 + 0.182142857142856*G0_0_1_5_0_1 - 0.401785714285714*G0_0_1_6_1_0 - 0.401785714285714*G0_0_1_6_1_1 + 0.530357142857143*G0_0_1_7_1_0 - 1.64464285714286*G0_0_1_8_1_1 - 2.35714285714285*G0_0_1_9_1_0 - 0.182142857142856*G0_0_1_9_1_1 + 2.35714285714285*G0_0_1_10_1_0 + 2.04642857142857*G0_0_1_10_1_1 - 0.128571428571429*G0_0_1_11_1_0 + 0.182142857142856*G0_0_1_11_1_1 - 0.471428571428572*G0_1_1_0_0_0 - 0.471428571428572*G0_1_1_0_0_1 + 0.675*G0_1_1_1_0_0 - 1.82142857142857*G0_1_1_2_0_1 - 2.49642857142857*G0_1_1_3_0_0 + 2.49642857142857*G0_1_1_4_0_0 + 2.29285714285714*G0_1_1_4_0_1 - 0.203571428571429*G0_1_1_5_0_0 - 0.471428571428572*G0_1_1_6_1_0 - 0.471428571428572*G0_1_1_6_1_1 + 0.675*G0_1_1_7_1_0 - 1.82142857142857*G0_1_1_8_1_1 - 2.49642857142857*G0_1_1_9_1_0 + 2.49642857142857*G0_1_1_10_1_0 + 2.29285714285714*G0_1_1_10_1_1 - 0.203571428571429*G0_1_1_11_1_0; + A[292] = -A[122] + 0.0267857142857144*G0_1_1_0_0_0 + 0.0267857142857145*G0_1_1_0_0_1 - 0.026785714285714*G0_1_1_1_0_0 - 0.583928571428571*G0_1_1_2_0_1 - 1.22142857142857*G0_1_1_3_0_0 - 0.664285714285713*G0_1_1_3_0_1 + 1.22142857142857*G0_1_1_4_0_0 + 0.557142857142856*G0_1_1_4_0_1 + 0.664285714285714*G0_1_1_5_0_1 + 0.0267857142857144*G0_1_1_6_1_0 + 0.0267857142857145*G0_1_1_6_1_1 - 0.026785714285714*G0_1_1_7_1_0 - 0.583928571428571*G0_1_1_8_1_1 - 1.22142857142857*G0_1_1_9_1_0 - 0.664285714285713*G0_1_1_9_1_1 + 1.22142857142857*G0_1_1_10_1_0 + 0.557142857142856*G0_1_1_10_1_1 + 0.664285714285714*G0_1_1_11_1_1; + A[352] = A[142]; + A[157] = 0.0; + A[371] = -A[271] + 0.0267857142857152*G0_0_0_0_0_0 + 0.026785714285715*G0_0_0_0_0_1 - 0.583928571428569*G0_0_0_1_0_0 - 0.0267857142857149*G0_0_0_2_0_1 - 0.664285714285713*G0_0_0_3_0_0 - 1.22142857142857*G0_0_0_3_0_1 + 0.664285714285713*G0_0_0_4_0_0 + 0.557142857142854*G0_0_0_5_0_0 + 1.22142857142857*G0_0_0_5_0_1 + 0.0267857142857152*G0_0_0_6_1_0 + 0.026785714285715*G0_0_0_6_1_1 - 0.583928571428569*G0_0_0_7_1_0 - 0.0267857142857149*G0_0_0_8_1_1 - 0.664285714285713*G0_0_0_9_1_0 - 1.22142857142857*G0_0_0_9_1_1 + 0.664285714285713*G0_0_0_10_1_0 + 0.557142857142854*G0_0_0_11_1_0 + 1.22142857142857*G0_0_0_11_1_1; + A[173] = 0.0; + A[188] = A[398]; + A[215] = A[5]; + A[179] = 0.0; + A[234] = A[24]; + A[198] = 0.0; + A[289] = 0.0; + A[249] = 0.0; + A[312] = A[102]; + A[272] = A[62]; + A[59] = 0.0; + A[15] = 0.0; + A[70] = 0.0; + A[34] = 0.0; + A[93] = 0.0; + A[53] = 0.0; + A[100] = A[310]; + A[76] = 0.0; + A[135] = 0.0; + A[345] = 0.0; + A[154] = 0.0; + A[362] = 0.0; + A[227] = 0.0; + A[296] = A[86]; + A[240] = 0.0; + A[216] = -A[214] - 0.557142857142858*G0_0_1_0_0_0 - 0.557142857142858*G0_0_1_0_0_1 - 0.214285714285714*G0_0_1_1_0_0 - 0.042857142857143*G0_0_1_2_0_1 + 0.257142857142857*G0_0_1_3_0_0 + 0.0857142857142859*G0_0_1_3_0_1 - 0.257142857142857*G0_0_1_4_0_0 + 0.6*G0_0_1_4_0_1 + 0.771428571428572*G0_0_1_5_0_0 - 0.085714285714286*G0_0_1_5_0_1 - 0.557142857142858*G0_0_1_6_1_0 - 0.557142857142858*G0_0_1_6_1_1 - 0.214285714285714*G0_0_1_7_1_0 - 0.042857142857143*G0_0_1_8_1_1 + 0.257142857142857*G0_0_1_9_1_0 + 0.0857142857142859*G0_0_1_9_1_1 - 0.257142857142857*G0_0_1_10_1_0 + 0.6*G0_0_1_10_1_1 + 0.771428571428572*G0_0_1_11_1_0 - 0.085714285714286*G0_0_1_11_1_1 - 0.557142857142858*G0_1_1_0_0_0 - 0.557142857142858*G0_1_1_0_0_1 - 0.214285714285714*G0_1_1_1_0_0 - 0.042857142857143*G0_1_1_2_0_1 + 0.257142857142857*G0_1_1_3_0_0 + 0.0857142857142859*G0_1_1_3_0_1 - 0.257142857142857*G0_1_1_4_0_0 + 0.6*G0_1_1_4_0_1 + 0.771428571428572*G0_1_1_5_0_0 - 0.085714285714286*G0_1_1_5_0_1 - 0.557142857142858*G0_1_1_6_1_0 - 0.557142857142858*G0_1_1_6_1_1 - 0.214285714285714*G0_1_1_7_1_0 - 0.042857142857143*G0_1_1_8_1_1 + 0.257142857142857*G0_1_1_9_1_0 + 0.0857142857142859*G0_1_1_9_1_1 - 0.257142857142857*G0_1_1_10_1_0 + 0.6*G0_1_1_10_1_1 + 0.771428571428572*G0_1_1_11_1_0 - 0.085714285714286*G0_1_1_11_1_1; + A[265] = 0.0; + A[6] = A[216]; + A[27] = -A[24] - 0.117857142857143*G0_0_0_0_0_0 - 0.117857142857143*G0_0_0_0_0_1 + 0.203571428571427*G0_0_0_1_0_0 + 0.0535714285714292*G0_0_0_2_0_1 + 0.428571428571428*G0_0_0_3_0_0 + 0.578571428571427*G0_0_0_3_0_1 - 0.428571428571428*G0_0_0_4_0_0 + 0.0642857142857144*G0_0_0_4_0_1 - 0.0857142857142838*G0_0_0_5_0_0 - 0.578571428571427*G0_0_0_5_0_1 - 0.117857142857143*G0_0_0_6_1_0 - 0.117857142857143*G0_0_0_6_1_1 + 0.203571428571427*G0_0_0_7_1_0 + 0.0535714285714292*G0_0_0_8_1_1 + 0.428571428571428*G0_0_0_9_1_0 + 0.578571428571427*G0_0_0_9_1_1 - 0.428571428571428*G0_0_0_10_1_0 + 0.0642857142857144*G0_0_0_10_1_1 - 0.0857142857142838*G0_0_0_11_1_0 - 0.578571428571427*G0_0_0_11_1_1 - 0.0642857142857142*G0_0_1_0_0_0 - 0.0642857142857142*G0_0_1_0_0_1 - 0.064285714285714*G0_0_1_2_0_1 - 0.0642857142857141*G0_0_1_3_0_0 + 0.0642857142857141*G0_0_1_4_0_0 + 0.128571428571428*G0_0_1_4_0_1 + 0.0642857142857143*G0_0_1_5_0_0 - 0.0642857142857142*G0_0_1_6_1_0 - 0.0642857142857142*G0_0_1_6_1_1 - 0.064285714285714*G0_0_1_8_1_1 - 0.0642857142857141*G0_0_1_9_1_0 + 0.0642857142857141*G0_0_1_10_1_0 + 0.128571428571428*G0_0_1_10_1_1 + 0.0642857142857143*G0_0_1_11_1_0; + A[44] = -A[256] + 0.0267857142857144*G0_1_1_0_0_0 + 0.0267857142857145*G0_1_1_0_0_1 - 0.026785714285714*G0_1_1_1_0_0 - 0.583928571428571*G0_1_1_2_0_1 - 1.22142857142857*G0_1_1_3_0_0 - 0.664285714285713*G0_1_1_3_0_1 + 1.22142857142857*G0_1_1_4_0_0 + 0.557142857142856*G0_1_1_4_0_1 + 0.664285714285714*G0_1_1_5_0_1 + 0.0267857142857144*G0_1_1_6_1_0 + 0.0267857142857145*G0_1_1_6_1_1 - 0.026785714285714*G0_1_1_7_1_0 - 0.583928571428571*G0_1_1_8_1_1 - 1.22142857142857*G0_1_1_9_1_0 - 0.664285714285713*G0_1_1_9_1_1 + 1.22142857142857*G0_1_1_10_1_0 + 0.557142857142856*G0_1_1_10_1_1 + 0.664285714285714*G0_1_1_11_1_1; + A[109] = A[319]; + A[126] = -A[86] + 0.385714285714286*G0_1_0_0_0_0 + 0.385714285714286*G0_1_0_0_0_1 - 0.385714285714286*G0_1_0_1_0_0 + 0.771428571428572*G0_1_0_2_0_1 + 0.771428571428569*G0_1_0_3_0_0 - 0.385714285714288*G0_1_0_3_0_1 - 0.771428571428569*G0_1_0_4_0_0 - 1.15714285714286*G0_1_0_4_0_1 + 0.385714285714288*G0_1_0_5_0_1 + 0.385714285714286*G0_1_0_6_1_0 + 0.385714285714286*G0_1_0_6_1_1 - 0.385714285714286*G0_1_0_7_1_0 + 0.771428571428572*G0_1_0_8_1_1 + 0.771428571428569*G0_1_0_9_1_0 - 0.385714285714288*G0_1_0_9_1_1 - 0.771428571428569*G0_1_0_10_1_0 - 1.15714285714286*G0_1_0_10_1_1 + 0.385714285714288*G0_1_0_11_1_1 - 1.0125*G0_1_1_0_0_0 - 1.0125*G0_1_1_0_0_1 - 0.530357142857143*G0_1_1_1_0_0 + 1.20535714285714*G0_1_1_2_0_1 + 2.89285714285714*G0_1_1_3_0_0 + 1.15714285714286*G0_1_1_3_0_1 - 2.89285714285714*G0_1_1_4_0_0 - 0.192857142857142*G0_1_1_4_0_1 + 1.54285714285714*G0_1_1_5_0_0 - 1.15714285714286*G0_1_1_5_0_1 - 1.0125*G0_1_1_6_1_0 - 1.0125*G0_1_1_6_1_1 - 0.530357142857143*G0_1_1_7_1_0 + 1.20535714285714*G0_1_1_8_1_1 + 2.89285714285714*G0_1_1_9_1_0 + 1.15714285714286*G0_1_1_9_1_1 - 2.89285714285714*G0_1_1_10_1_0 - 0.192857142857142*G0_1_1_10_1_1 + 1.54285714285714*G0_1_1_11_1_0 - 1.15714285714286*G0_1_1_11_1_1; + A[98] = 0.0; + A[119] = 0.0; + A[380] = 0.0; + A[356] = A[146]; + A[161] = A[371]; + A[318] = A[108]; + A[238] = A[28]; + A[332] = A[122]; + A[139] = 0.0; + A[389] = 0.0; + A[349] = 0.0; + A[374] = A[164]; + A[168] = A[378]; + A[185] = A[395]; + A[202] = 0.0; + A[231] = A[21]; + A[284] = 0.0; + A[252] = 0.186904761904762*G0_1_1_0_0_0 + 0.186904761904762*G0_1_1_0_0_1 - 0.186904761904762*G0_1_1_1_0_0 + 0.798809523809523*G0_1_1_2_0_1 + 1.22380952380952*G0_1_1_3_0_0 + 0.238095238095237*G0_1_1_3_0_1 - 1.22380952380952*G0_1_1_4_0_0 - 0.985714285714285*G0_1_1_4_0_1 - 0.238095238095238*G0_1_1_5_0_1 + 0.186904761904762*G0_1_1_6_1_0 + 0.186904761904762*G0_1_1_6_1_1 - 0.186904761904762*G0_1_1_7_1_0 + 0.798809523809523*G0_1_1_8_1_1 + 1.22380952380952*G0_1_1_9_1_0 + 0.238095238095237*G0_1_1_9_1_1 - 1.22380952380952*G0_1_1_10_1_0 - 0.985714285714285*G0_1_1_10_1_1 - 0.238095238095238*G0_1_1_11_1_1; + A[37] = 0.0; + A[301] = 0.0; + A[277] = A[143] - 0.0964285714285713*G0_0_1_0_0_0 - 0.0964285714285714*G0_0_1_0_0_1 - 0.289285714285712*G0_0_1_1_0_0 + 0.192857142857141*G0_0_1_2_0_1 + 0.192857142857142*G0_0_1_3_0_0 - 0.289285714285712*G0_0_1_3_0_1 - 0.192857142857142*G0_0_1_4_0_0 - 0.0964285714285703*G0_0_1_4_0_1 + 0.385714285714284*G0_0_1_5_0_0 + 0.289285714285712*G0_0_1_5_0_1 - 0.0964285714285713*G0_0_1_6_1_0 - 0.0964285714285714*G0_0_1_6_1_1 - 0.289285714285712*G0_0_1_7_1_0 + 0.192857142857141*G0_0_1_8_1_1 + 0.192857142857142*G0_0_1_9_1_0 - 0.289285714285712*G0_0_1_9_1_1 - 0.192857142857142*G0_0_1_10_1_0 - 0.0964285714285703*G0_0_1_10_1_1 + 0.385714285714284*G0_0_1_11_1_0 + 0.289285714285712*G0_0_1_11_1_1 + 0.0964285714285711*G0_1_0_0_0_0 + 0.0964285714285713*G0_1_0_0_0_1 + 0.289285714285712*G0_1_0_1_0_0 - 0.192857142857142*G0_1_0_2_0_1 - 0.192857142857142*G0_1_0_3_0_0 + 0.289285714285712*G0_1_0_3_0_1 + 0.192857142857142*G0_1_0_4_0_0 + 0.0964285714285705*G0_1_0_4_0_1 - 0.385714285714284*G0_1_0_5_0_0 - 0.289285714285712*G0_1_0_5_0_1 + 0.0964285714285711*G0_1_0_6_1_0 + 0.0964285714285713*G0_1_0_6_1_1 + 0.289285714285712*G0_1_0_7_1_0 - 0.192857142857142*G0_1_0_8_1_1 - 0.192857142857142*G0_1_0_9_1_0 + 0.289285714285712*G0_1_0_9_1_1 + 0.192857142857142*G0_1_0_10_1_0 + 0.0964285714285705*G0_1_0_10_1_1 - 0.385714285714284*G0_1_0_11_1_0 - 0.289285714285712*G0_1_0_11_1_1; + A[145] = A[277] + 0.192857142857144*G0_0_0_0_0_0 + 0.192857142857143*G0_0_0_0_0_1 + 0.192857142857144*G0_0_0_1_0_0 + 0.192857142857144*G0_0_0_3_0_1 - 0.192857142857143*G0_0_0_4_0_1 - 0.385714285714287*G0_0_0_5_0_0 - 0.192857142857144*G0_0_0_5_0_1 + 0.192857142857144*G0_0_0_6_1_0 + 0.192857142857143*G0_0_0_6_1_1 + 0.192857142857144*G0_0_0_7_1_0 + 0.192857142857144*G0_0_0_9_1_1 - 0.192857142857143*G0_0_0_10_1_1 - 0.385714285714287*G0_0_0_11_1_0 - 0.192857142857144*G0_0_0_11_1_1 - 1.83214285714286*G0_0_1_0_0_0 - 1.83214285714286*G0_0_1_0_0_1 - 0.674999999999998*G0_0_1_1_0_0 - 0.482142857142857*G0_0_1_2_0_1 + 0.192857142857143*G0_0_1_3_0_0 - 0.192857142857143*G0_0_1_4_0_0 + 2.31428571428571*G0_0_1_4_0_1 + 2.50714285714285*G0_0_1_5_0_0 - 1.83214285714286*G0_0_1_6_1_0 - 1.83214285714286*G0_0_1_6_1_1 - 0.674999999999998*G0_0_1_7_1_0 - 0.482142857142857*G0_0_1_8_1_1 + 0.192857142857143*G0_0_1_9_1_0 - 0.192857142857143*G0_0_1_10_1_0 + 2.31428571428571*G0_0_1_10_1_1 + 2.50714285714285*G0_0_1_11_1_0 - 1.15714285714286*G0_1_0_0_0_0 - 1.15714285714286*G0_1_0_0_0_1 - 0.578571428571426*G0_1_0_1_0_0 + 0.0964285714285703*G0_1_0_2_0_1 + 0.771428571428571*G0_1_0_3_0_0 + 0.0964285714285747*G0_1_0_3_0_1 - 0.771428571428571*G0_1_0_4_0_0 + 1.06071428571429*G0_1_0_4_0_1 + 1.73571428571428*G0_1_0_5_0_0 - 0.0964285714285745*G0_1_0_5_0_1 - 1.15714285714286*G0_1_0_6_1_0 - 1.15714285714286*G0_1_0_6_1_1 - 0.578571428571426*G0_1_0_7_1_0 + 0.0964285714285703*G0_1_0_8_1_1 + 0.771428571428571*G0_1_0_9_1_0 + 0.0964285714285747*G0_1_0_9_1_1 - 0.771428571428571*G0_1_0_10_1_0 + 1.06071428571429*G0_1_0_10_1_1 + 1.73571428571428*G0_1_0_11_1_0 - 0.0964285714285745*G0_1_0_11_1_1 + 0.337500000000001*G0_1_1_0_0_0 + 0.337500000000001*G0_1_1_0_0_1 - 0.626785714285711*G0_1_1_1_0_0 + 0.626785714285713*G0_1_1_2_0_1 + 0.289285714285714*G0_1_1_3_0_0 - 0.96428571428571*G0_1_1_3_0_1 - 0.289285714285714*G0_1_1_4_0_0 - 0.964285714285714*G0_1_1_4_0_1 + 0.28928571428571*G0_1_1_5_0_0 + 0.964285714285711*G0_1_1_5_0_1 + 0.337500000000001*G0_1_1_6_1_0 + 0.337500000000001*G0_1_1_6_1_1 - 0.626785714285711*G0_1_1_7_1_0 + 0.626785714285713*G0_1_1_8_1_1 + 0.289285714285714*G0_1_1_9_1_0 - 0.96428571428571*G0_1_1_9_1_1 - 0.289285714285714*G0_1_1_10_1_0 - 0.964285714285714*G0_1_1_10_1_1 + 0.28928571428571*G0_1_1_11_1_0 + 0.964285714285711*G0_1_1_11_1_1; + A[357] = A[145] - 2.74821428571429*G0_0_0_0_0_0 - 2.74821428571429*G0_0_0_0_0_1 - 0.144642857142858*G0_0_0_1_0_0 - 0.916071428571428*G0_0_0_2_0_1 + 0.77142857142857*G0_0_0_3_0_0 + 1.54285714285714*G0_0_0_3_0_1 - 0.77142857142857*G0_0_0_4_0_0 + 3.66428571428572*G0_0_0_4_0_1 + 2.89285714285715*G0_0_0_5_0_0 - 1.54285714285714*G0_0_0_5_0_1 - 2.74821428571429*G0_0_0_6_1_0 - 2.74821428571429*G0_0_0_6_1_1 - 0.144642857142858*G0_0_0_7_1_0 - 0.916071428571428*G0_0_0_8_1_1 + 0.77142857142857*G0_0_0_9_1_0 + 1.54285714285714*G0_0_0_9_1_1 - 0.77142857142857*G0_0_0_10_1_0 + 3.66428571428572*G0_0_0_10_1_1 + 2.89285714285715*G0_0_0_11_1_0 - 1.54285714285714*G0_0_0_11_1_1 + 1.54285714285714*G0_0_1_0_0_0 + 1.54285714285714*G0_0_1_0_0_1 + 1.54285714285714*G0_0_1_1_0_0 + 1.54285714285714*G0_0_1_3_0_1 - 1.54285714285714*G0_0_1_4_0_1 - 3.08571428571428*G0_0_1_5_0_0 - 1.54285714285714*G0_0_1_5_0_1 + 1.54285714285714*G0_0_1_6_1_0 + 1.54285714285714*G0_0_1_6_1_1 + 1.54285714285714*G0_0_1_7_1_0 + 1.54285714285714*G0_0_1_9_1_1 - 1.54285714285714*G0_0_1_10_1_1 - 3.08571428571428*G0_0_1_11_1_0 - 1.54285714285714*G0_0_1_11_1_1 + 0.771428571428571*G0_1_0_0_0_0 + 0.771428571428571*G0_1_0_0_0_1 + 1.15714285714286*G0_1_0_1_0_0 - 0.385714285714286*G0_1_0_2_0_1 - 0.385714285714286*G0_1_0_3_0_0 + 1.15714285714286*G0_1_0_3_0_1 + 0.385714285714286*G0_1_0_4_0_0 - 0.385714285714285*G0_1_0_4_0_1 - 1.92857142857143*G0_1_0_5_0_0 - 1.15714285714286*G0_1_0_5_0_1 + 0.771428571428571*G0_1_0_6_1_0 + 0.771428571428571*G0_1_0_6_1_1 + 1.15714285714286*G0_1_0_7_1_0 - 0.385714285714286*G0_1_0_8_1_1 - 0.385714285714286*G0_1_0_9_1_0 + 1.15714285714286*G0_1_0_9_1_1 + 0.385714285714286*G0_1_0_10_1_0 - 0.385714285714285*G0_1_0_10_1_1 - 1.92857142857143*G0_1_0_11_1_0 - 1.15714285714286*G0_1_0_11_1_1 - 1.97678571428572*G0_1_1_0_0_0 - 1.97678571428572*G0_1_1_0_0_1 + 1.0125*G0_1_1_1_0_0 - 1.30178571428571*G0_1_1_2_0_1 + 0.385714285714284*G0_1_1_3_0_0 + 2.7*G0_1_1_3_0_1 - 0.385714285714284*G0_1_1_4_0_0 + 3.27857142857143*G0_1_1_4_0_1 + 0.964285714285718*G0_1_1_5_0_0 - 2.7*G0_1_1_5_0_1 - 1.97678571428572*G0_1_1_6_1_0 - 1.97678571428572*G0_1_1_6_1_1 + 1.0125*G0_1_1_7_1_0 - 1.30178571428571*G0_1_1_8_1_1 + 0.385714285714284*G0_1_1_9_1_0 + 2.7*G0_1_1_9_1_1 - 0.385714285714284*G0_1_1_10_1_0 + 3.27857142857143*G0_1_1_10_1_1 + 0.964285714285718*G0_1_1_11_1_0 - 2.7*G0_1_1_11_1_1; + A[315] = A[357] + 0.771428571428571*G0_0_0_0_0_0 + 0.77142857142857*G0_0_0_0_0_1 - 1.15714285714286*G0_0_0_1_0_0 + 1.92857142857143*G0_0_0_2_0_1 + 1.92857142857143*G0_0_0_3_0_0 - 1.15714285714286*G0_0_0_3_0_1 - 1.92857142857143*G0_0_0_4_0_0 - 2.7*G0_0_0_4_0_1 + 0.385714285714287*G0_0_0_5_0_0 + 1.15714285714286*G0_0_0_5_0_1 + 0.771428571428571*G0_0_0_6_1_0 + 0.77142857142857*G0_0_0_6_1_1 - 1.15714285714286*G0_0_0_7_1_0 + 1.92857142857143*G0_0_0_8_1_1 + 1.92857142857143*G0_0_0_9_1_0 - 1.15714285714286*G0_0_0_9_1_1 - 1.92857142857143*G0_0_0_10_1_0 - 2.7*G0_0_0_10_1_1 + 0.385714285714287*G0_0_0_11_1_0 + 1.15714285714286*G0_0_0_11_1_1 - 1.54285714285714*G0_0_1_1_0_0 + 1.54285714285714*G0_0_1_2_0_1 + 1.54285714285714*G0_0_1_3_0_0 - 1.54285714285714*G0_0_1_3_0_1 - 1.54285714285714*G0_0_1_4_0_0 - 1.54285714285714*G0_0_1_4_0_1 + 1.54285714285714*G0_0_1_5_0_0 + 1.54285714285714*G0_0_1_5_0_1 - 1.54285714285714*G0_0_1_7_1_0 + 1.54285714285714*G0_0_1_8_1_1 + 1.54285714285714*G0_0_1_9_1_0 - 1.54285714285714*G0_0_1_9_1_1 - 1.54285714285714*G0_0_1_10_1_0 - 1.54285714285714*G0_0_1_10_1_1 + 1.54285714285714*G0_0_1_11_1_0 + 1.54285714285714*G0_0_1_11_1_1 - 1.54285714285714*G0_1_0_1_0_0 + 1.54285714285714*G0_1_0_2_0_1 + 1.54285714285714*G0_1_0_3_0_0 - 1.54285714285714*G0_1_0_3_0_1 - 1.54285714285714*G0_1_0_4_0_0 - 1.54285714285714*G0_1_0_4_0_1 + 1.54285714285714*G0_1_0_5_0_0 + 1.54285714285714*G0_1_0_5_0_1 - 1.54285714285714*G0_1_0_7_1_0 + 1.54285714285714*G0_1_0_8_1_1 + 1.54285714285714*G0_1_0_9_1_0 - 1.54285714285714*G0_1_0_9_1_1 - 1.54285714285714*G0_1_0_10_1_0 - 1.54285714285714*G0_1_0_10_1_1 + 1.54285714285714*G0_1_0_11_1_0 + 1.54285714285714*G0_1_0_11_1_1 - 0.77142857142857*G0_1_1_0_0_0 - 0.77142857142857*G0_1_1_0_0_1 - 1.92857142857143*G0_1_1_1_0_0 + 1.15714285714286*G0_1_1_2_0_1 + 1.15714285714286*G0_1_1_3_0_0 - 1.92857142857143*G0_1_1_3_0_1 - 1.15714285714286*G0_1_1_4_0_0 - 0.385714285714287*G0_1_1_4_0_1 + 2.7*G0_1_1_5_0_0 + 1.92857142857143*G0_1_1_5_0_1 - 0.77142857142857*G0_1_1_6_1_0 - 0.77142857142857*G0_1_1_6_1_1 - 1.92857142857143*G0_1_1_7_1_0 + 1.15714285714286*G0_1_1_8_1_1 + 1.15714285714286*G0_1_1_9_1_0 - 1.92857142857143*G0_1_1_9_1_1 - 1.15714285714286*G0_1_1_10_1_0 - 0.385714285714287*G0_1_1_10_1_1 + 2.7*G0_1_1_11_1_0 + 1.92857142857143*G0_1_1_11_1_1; + A[107] = A[145] + 0.771428571428571*G0_0_1_0_0_0 + 0.77142857142857*G0_0_1_0_0_1 + 0.385714285714285*G0_0_1_1_0_0 + 0.385714285714285*G0_0_1_2_0_1 + 0.385714285714286*G0_0_1_3_0_0 + 0.385714285714285*G0_0_1_3_0_1 - 0.385714285714286*G0_0_1_4_0_0 - 1.15714285714286*G0_0_1_4_0_1 - 1.15714285714286*G0_0_1_5_0_0 - 0.385714285714285*G0_0_1_5_0_1 + 0.771428571428571*G0_0_1_6_1_0 + 0.77142857142857*G0_0_1_6_1_1 + 0.385714285714285*G0_0_1_7_1_0 + 0.385714285714285*G0_0_1_8_1_1 + 0.385714285714286*G0_0_1_9_1_0 + 0.385714285714285*G0_0_1_9_1_1 - 0.385714285714286*G0_0_1_10_1_0 - 1.15714285714286*G0_0_1_10_1_1 - 1.15714285714286*G0_0_1_11_1_0 - 0.385714285714285*G0_0_1_11_1_1 - 0.771428571428571*G0_1_0_0_0_0 - 0.77142857142857*G0_1_0_0_0_1 - 0.385714285714285*G0_1_0_1_0_0 - 0.385714285714285*G0_1_0_2_0_1 - 0.385714285714286*G0_1_0_3_0_0 - 0.385714285714285*G0_1_0_3_0_1 + 0.385714285714286*G0_1_0_4_0_0 + 1.15714285714286*G0_1_0_4_0_1 + 1.15714285714286*G0_1_0_5_0_0 + 0.385714285714286*G0_1_0_5_0_1 - 0.771428571428571*G0_1_0_6_1_0 - 0.77142857142857*G0_1_0_6_1_1 - 0.385714285714285*G0_1_0_7_1_0 - 0.385714285714285*G0_1_0_8_1_1 - 0.385714285714286*G0_1_0_9_1_0 - 0.385714285714285*G0_1_0_9_1_1 + 0.385714285714286*G0_1_0_10_1_0 + 1.15714285714286*G0_1_0_10_1_1 + 1.15714285714286*G0_1_0_11_1_0 + 0.385714285714286*G0_1_0_11_1_1; + A[147] = A[357]; + A[10] = 0.0; + A[67] = A[277]; + A[31] = 0.0; + A[80] = A[214] + 0.0535714285714285*G0_0_1_1_0_0 - 0.0535714285714287*G0_0_1_2_0_1 - 0.0535714285714289*G0_0_1_3_0_0 + 0.0535714285714282*G0_0_1_3_0_1 + 0.0535714285714289*G0_0_1_4_0_0 + 0.0535714285714285*G0_0_1_4_0_1 - 0.0535714285714286*G0_0_1_5_0_0 - 0.0535714285714281*G0_0_1_5_0_1 + 0.0535714285714285*G0_0_1_7_1_0 - 0.0535714285714287*G0_0_1_8_1_1 - 0.0535714285714289*G0_0_1_9_1_0 + 0.0535714285714282*G0_0_1_9_1_1 + 0.0535714285714289*G0_0_1_10_1_0 + 0.0535714285714285*G0_0_1_10_1_1 - 0.0535714285714286*G0_0_1_11_1_0 - 0.0535714285714281*G0_0_1_11_1_1 - 0.0535714285714285*G0_1_0_1_0_0 + 0.0535714285714287*G0_1_0_2_0_1 + 0.0535714285714289*G0_1_0_3_0_0 - 0.0535714285714281*G0_1_0_3_0_1 - 0.0535714285714289*G0_1_0_4_0_0 - 0.0535714285714285*G0_1_0_4_0_1 + 0.0535714285714286*G0_1_0_5_0_0 + 0.0535714285714281*G0_1_0_5_0_1 - 0.0535714285714285*G0_1_0_7_1_0 + 0.0535714285714287*G0_1_0_8_1_1 + 0.0535714285714289*G0_1_0_9_1_0 - 0.0535714285714281*G0_1_0_9_1_1 - 0.0535714285714289*G0_1_0_10_1_0 - 0.0535714285714285*G0_1_0_10_1_1 + 0.0535714285714286*G0_1_0_11_1_0 + 0.0535714285714281*G0_1_0_11_1_1; + A[120] = -A[80] - 0.557142857142858*G0_1_0_0_0_0 - 0.557142857142858*G0_1_0_0_0_1 - 0.214285714285714*G0_1_0_1_0_0 - 0.042857142857143*G0_1_0_2_0_1 + 0.257142857142857*G0_1_0_3_0_0 + 0.0857142857142859*G0_1_0_3_0_1 - 0.257142857142857*G0_1_0_4_0_0 + 0.6*G0_1_0_4_0_1 + 0.771428571428572*G0_1_0_5_0_0 - 0.085714285714286*G0_1_0_5_0_1 - 0.557142857142858*G0_1_0_6_1_0 - 0.557142857142858*G0_1_0_6_1_1 - 0.214285714285714*G0_1_0_7_1_0 - 0.042857142857143*G0_1_0_8_1_1 + 0.257142857142857*G0_1_0_9_1_0 + 0.0857142857142859*G0_1_0_9_1_1 - 0.257142857142857*G0_1_0_10_1_0 + 0.6*G0_1_0_10_1_1 + 0.771428571428572*G0_1_0_11_1_0 - 0.085714285714286*G0_1_0_11_1_1 - 0.557142857142858*G0_1_1_0_0_0 - 0.557142857142858*G0_1_1_0_0_1 - 0.214285714285715*G0_1_1_1_0_0 - 0.042857142857143*G0_1_1_2_0_1 + 0.257142857142857*G0_1_1_3_0_0 + 0.0857142857142859*G0_1_1_3_0_1 - 0.257142857142857*G0_1_1_4_0_0 + 0.6*G0_1_1_4_0_1 + 0.771428571428573*G0_1_1_5_0_0 - 0.085714285714286*G0_1_1_5_0_1 - 0.557142857142858*G0_1_1_6_1_0 - 0.557142857142858*G0_1_1_6_1_1 - 0.214285714285715*G0_1_1_7_1_0 - 0.042857142857143*G0_1_1_8_1_1 + 0.257142857142857*G0_1_1_9_1_0 + 0.0857142857142859*G0_1_1_9_1_1 - 0.257142857142857*G0_1_1_10_1_0 + 0.6*G0_1_1_10_1_1 + 0.771428571428573*G0_1_1_11_1_0 - 0.085714285714286*G0_1_1_11_1_1; + A[330] = A[120]; + A[105] = A[315]; + A[323] = 0.0; + A[130] = 0.0; + A[394] = A[184]; + A[342] = 0.0; + A[159] = 0.0; + A[369] = 0.0; + A[175] = 0.0; + A[194] = 0.0; + A[213] = A[214] - 0.128571428571428*G0_0_0_1_0_0 + 0.128571428571429*G0_0_0_2_0_1 + 0.128571428571429*G0_0_0_3_0_0 - 0.128571428571428*G0_0_0_3_0_1 - 0.128571428571429*G0_0_0_4_0_0 - 0.128571428571429*G0_0_0_4_0_1 + 0.128571428571428*G0_0_0_5_0_0 + 0.128571428571428*G0_0_0_5_0_1 - 0.128571428571428*G0_0_0_7_1_0 + 0.128571428571429*G0_0_0_8_1_1 + 0.128571428571429*G0_0_0_9_1_0 - 0.128571428571428*G0_0_0_9_1_1 - 0.128571428571429*G0_0_0_10_1_0 - 0.128571428571429*G0_0_0_10_1_1 + 0.128571428571428*G0_0_0_11_1_0 + 0.128571428571428*G0_0_0_11_1_1 - 0.128571428571428*G0_0_1_1_0_0 + 0.128571428571429*G0_0_1_2_0_1 + 0.128571428571428*G0_0_1_3_0_0 - 0.128571428571429*G0_0_1_3_0_1 - 0.128571428571428*G0_0_1_4_0_0 - 0.12857142857143*G0_0_1_4_0_1 + 0.128571428571427*G0_0_1_5_0_0 + 0.128571428571429*G0_0_1_5_0_1 - 0.128571428571428*G0_0_1_7_1_0 + 0.128571428571429*G0_0_1_8_1_1 + 0.128571428571428*G0_0_1_9_1_0 - 0.128571428571429*G0_0_1_9_1_1 - 0.128571428571428*G0_0_1_10_1_0 - 0.12857142857143*G0_0_1_10_1_1 + 0.128571428571427*G0_0_1_11_1_0 + 0.128571428571429*G0_0_1_11_1_1 - 0.128571428571428*G0_1_0_1_0_0 + 0.128571428571429*G0_1_0_2_0_1 + 0.128571428571429*G0_1_0_3_0_0 - 0.128571428571428*G0_1_0_3_0_1 - 0.128571428571429*G0_1_0_4_0_0 - 0.128571428571429*G0_1_0_4_0_1 + 0.128571428571428*G0_1_0_5_0_0 + 0.128571428571428*G0_1_0_5_0_1 - 0.128571428571428*G0_1_0_7_1_0 + 0.128571428571429*G0_1_0_8_1_1 + 0.128571428571429*G0_1_0_9_1_0 - 0.128571428571428*G0_1_0_9_1_1 - 0.128571428571429*G0_1_0_10_1_0 - 0.128571428571429*G0_1_0_10_1_1 + 0.128571428571428*G0_1_0_11_1_0 + 0.128571428571428*G0_1_0_11_1_1 - 0.128571428571428*G0_1_1_1_0_0 + 0.128571428571429*G0_1_1_2_0_1 + 0.128571428571428*G0_1_1_3_0_0 - 0.128571428571428*G0_1_1_3_0_1 - 0.128571428571428*G0_1_1_4_0_0 - 0.12857142857143*G0_1_1_4_0_1 + 0.128571428571426*G0_1_1_5_0_0 + 0.128571428571428*G0_1_1_5_0_1 - 0.128571428571428*G0_1_1_7_1_0 + 0.128571428571429*G0_1_1_8_1_1 + 0.128571428571428*G0_1_1_9_1_0 - 0.128571428571428*G0_1_1_9_1_1 - 0.128571428571428*G0_1_1_10_1_0 - 0.12857142857143*G0_1_1_10_1_1 + 0.128571428571426*G0_1_1_11_1_0 + 0.128571428571428*G0_1_1_11_1_1; + A[218] = -A[213] - 0.557142857142857*G0_0_0_0_0_0 - 0.557142857142857*G0_0_0_0_0_1 - 0.0428571428571428*G0_0_0_1_0_0 - 0.214285714285714*G0_0_0_2_0_1 + 0.085714285714286*G0_0_0_3_0_0 + 0.257142857142857*G0_0_0_3_0_1 - 0.085714285714286*G0_0_0_4_0_0 + 0.771428571428572*G0_0_0_4_0_1 + 0.6*G0_0_0_5_0_0 - 0.257142857142858*G0_0_0_5_0_1 - 0.557142857142857*G0_0_0_6_1_0 - 0.557142857142857*G0_0_0_6_1_1 - 0.0428571428571428*G0_0_0_7_1_0 - 0.214285714285714*G0_0_0_8_1_1 + 0.085714285714286*G0_0_0_9_1_0 + 0.257142857142857*G0_0_0_9_1_1 - 0.085714285714286*G0_0_0_10_1_0 + 0.771428571428572*G0_0_0_10_1_1 + 0.6*G0_0_0_11_1_0 - 0.257142857142858*G0_0_0_11_1_1 - 0.557142857142857*G0_1_0_0_0_0 - 0.557142857142857*G0_1_0_0_0_1 - 0.0428571428571431*G0_1_0_1_0_0 - 0.214285714285714*G0_1_0_2_0_1 + 0.0857142857142858*G0_1_0_3_0_0 + 0.257142857142857*G0_1_0_3_0_1 - 0.0857142857142858*G0_1_0_4_0_0 + 0.771428571428571*G0_1_0_4_0_1 + 0.6*G0_1_0_5_0_0 - 0.257142857142857*G0_1_0_5_0_1 - 0.557142857142857*G0_1_0_6_1_0 - 0.557142857142857*G0_1_0_6_1_1 - 0.0428571428571431*G0_1_0_7_1_0 - 0.214285714285714*G0_1_0_8_1_1 + 0.0857142857142858*G0_1_0_9_1_0 + 0.257142857142857*G0_1_0_9_1_1 - 0.0857142857142858*G0_1_0_10_1_0 + 0.771428571428571*G0_1_0_10_1_1 + 0.6*G0_1_0_11_1_0 - 0.257142857142857*G0_1_0_11_1_1; + A[8] = A[218]; + A[220] = 0.0; + A[196] = 0.0; + A[295] = A[85]; + A[251] = A[41]; + A[314] = A[104]; + A[270] = A[213] + 0.0535714285714287*G0_0_1_1_0_0 - 0.0535714285714285*G0_0_1_2_0_1 - 0.053571428571428*G0_0_1_3_0_0 + 0.0535714285714292*G0_0_1_3_0_1 + 0.053571428571428*G0_0_1_4_0_0 + 0.0535714285714292*G0_0_1_4_0_1 - 0.0535714285714282*G0_0_1_5_0_0 - 0.0535714285714292*G0_0_1_5_0_1 + 0.0535714285714287*G0_0_1_7_1_0 - 0.0535714285714285*G0_0_1_8_1_1 - 0.053571428571428*G0_0_1_9_1_0 + 0.0535714285714292*G0_0_1_9_1_1 + 0.053571428571428*G0_0_1_10_1_0 + 0.0535714285714292*G0_0_1_10_1_1 - 0.0535714285714282*G0_0_1_11_1_0 - 0.0535714285714292*G0_0_1_11_1_1 - 0.0535714285714286*G0_1_0_1_0_0 + 0.0535714285714285*G0_1_0_2_0_1 + 0.0535714285714281*G0_1_0_3_0_0 - 0.0535714285714291*G0_1_0_3_0_1 - 0.0535714285714281*G0_1_0_4_0_0 - 0.0535714285714292*G0_1_0_4_0_1 + 0.0535714285714281*G0_1_0_5_0_0 + 0.0535714285714292*G0_1_0_5_0_1 - 0.0535714285714286*G0_1_0_7_1_0 + 0.0535714285714285*G0_1_0_8_1_1 + 0.0535714285714281*G0_1_0_9_1_0 - 0.0535714285714291*G0_1_0_9_1_1 - 0.0535714285714281*G0_1_0_10_1_0 - 0.0535714285714292*G0_1_0_10_1_1 + 0.0535714285714281*G0_1_0_11_1_0 + 0.0535714285714292*G0_1_0_11_1_1; + A[370] = -A[270] - 0.557142857142857*G0_0_0_0_0_0 - 0.557142857142857*G0_0_0_0_0_1 - 0.0428571428571428*G0_0_0_1_0_0 - 0.214285714285714*G0_0_0_2_0_1 + 0.085714285714286*G0_0_0_3_0_0 + 0.257142857142857*G0_0_0_3_0_1 - 0.085714285714286*G0_0_0_4_0_0 + 0.771428571428572*G0_0_0_4_0_1 + 0.6*G0_0_0_5_0_0 - 0.257142857142858*G0_0_0_5_0_1 - 0.557142857142857*G0_0_0_6_1_0 - 0.557142857142857*G0_0_0_6_1_1 - 0.0428571428571428*G0_0_0_7_1_0 - 0.214285714285714*G0_0_0_8_1_1 + 0.085714285714286*G0_0_0_9_1_0 + 0.257142857142857*G0_0_0_9_1_1 - 0.085714285714286*G0_0_0_10_1_0 + 0.771428571428572*G0_0_0_10_1_1 + 0.6*G0_0_0_11_1_0 - 0.257142857142858*G0_0_0_11_1_1 - 0.557142857142857*G0_0_1_0_0_0 - 0.557142857142857*G0_0_1_0_0_1 - 0.042857142857143*G0_0_1_1_0_0 - 0.214285714285714*G0_0_1_2_0_1 + 0.0857142857142859*G0_0_1_3_0_0 + 0.257142857142857*G0_0_1_3_0_1 - 0.0857142857142859*G0_0_1_4_0_0 + 0.771428571428571*G0_0_1_4_0_1 + 0.6*G0_0_1_5_0_0 - 0.257142857142857*G0_0_1_5_0_1 - 0.557142857142857*G0_0_1_6_1_0 - 0.557142857142857*G0_0_1_6_1_1 - 0.042857142857143*G0_0_1_7_1_0 - 0.214285714285714*G0_0_1_8_1_1 + 0.0857142857142859*G0_0_1_9_1_0 + 0.257142857142857*G0_0_1_9_1_1 - 0.0857142857142859*G0_0_1_10_1_0 + 0.771428571428571*G0_0_1_10_1_1 + 0.6*G0_0_1_11_1_0 - 0.257142857142857*G0_0_1_11_1_1; + A[160] = A[370]; + A[57] = 0.0; + A[1] = -A[41] + 0.0648809523809526*G0_0_0_0_0_0 + 0.0648809523809525*G0_0_0_0_0_1 - 0.0648809523809524*G0_0_0_1_0_0 + 0.0422619047619048*G0_0_0_2_0_1 - 0.0452380952380952*G0_0_0_3_0_0 - 0.152380952380952*G0_0_0_3_0_1 + 0.0452380952380952*G0_0_0_4_0_0 - 0.107142857142857*G0_0_0_4_0_1 + 0.152380952380953*G0_0_0_5_0_1 + 0.0648809523809526*G0_0_0_6_1_0 + 0.0648809523809525*G0_0_0_6_1_1 - 0.0648809523809524*G0_0_0_7_1_0 + 0.0422619047619048*G0_0_0_8_1_1 - 0.0452380952380952*G0_0_0_9_1_0 - 0.152380952380952*G0_0_0_9_1_1 + 0.0452380952380952*G0_0_0_10_1_0 - 0.107142857142857*G0_0_0_10_1_1 + 0.152380952380953*G0_0_0_11_1_1 + 0.107142857142857*G0_1_0_0_0_0 + 0.107142857142857*G0_1_0_0_0_1 + 0.107142857142857*G0_1_0_2_0_1 + 0.107142857142857*G0_1_0_3_0_0 - 0.107142857142857*G0_1_0_4_0_0 - 0.214285714285715*G0_1_0_4_0_1 - 0.107142857142857*G0_1_0_5_0_0 + 0.107142857142857*G0_1_0_6_1_0 + 0.107142857142857*G0_1_0_6_1_1 + 0.107142857142857*G0_1_0_8_1_1 + 0.107142857142857*G0_1_0_9_1_0 - 0.107142857142857*G0_1_0_10_1_0 - 0.214285714285715*G0_1_0_10_1_1 - 0.107142857142857*G0_1_0_11_1_0; + A[72] = 0.0; + A[32] = 0.0; + A[95] = 0.0; + A[51] = 0.0; + A[114] = 0.0; + A[78] = 0.0; + A[133] = 0.0; + A[148] = A[358]; + A[360] = 0.0; + A[336] = A[126]; + A[242] = 0.0; + A[263] = 0.0; + A[25] = A[235]; + A[42] = A[252]; + A[124] = A[86] + 0.385714285714286*G0_0_1_0_0_0 + 0.385714285714285*G0_0_1_0_0_1 - 0.385714285714286*G0_0_1_1_0_0 + 0.771428571428571*G0_0_1_2_0_1 + 0.771428571428568*G0_0_1_3_0_0 - 0.385714285714288*G0_0_1_3_0_1 - 0.771428571428568*G0_0_1_4_0_0 - 1.15714285714286*G0_0_1_4_0_1 + 0.385714285714288*G0_0_1_5_0_1 + 0.385714285714286*G0_0_1_6_1_0 + 0.385714285714285*G0_0_1_6_1_1 - 0.385714285714286*G0_0_1_7_1_0 + 0.771428571428571*G0_0_1_8_1_1 + 0.771428571428568*G0_0_1_9_1_0 - 0.385714285714288*G0_0_1_9_1_1 - 0.771428571428568*G0_0_1_10_1_0 - 1.15714285714286*G0_0_1_10_1_1 + 0.385714285714288*G0_0_1_11_1_1 - 0.385714285714286*G0_1_0_0_0_0 - 0.385714285714285*G0_1_0_0_0_1 + 0.385714285714286*G0_1_0_1_0_0 - 0.771428571428571*G0_1_0_2_0_1 - 0.771428571428568*G0_1_0_3_0_0 + 0.385714285714288*G0_1_0_3_0_1 + 0.771428571428568*G0_1_0_4_0_0 + 1.15714285714286*G0_1_0_4_0_1 - 0.385714285714288*G0_1_0_5_0_1 - 0.385714285714286*G0_1_0_6_1_0 - 0.385714285714285*G0_1_0_6_1_1 + 0.385714285714286*G0_1_0_7_1_0 - 0.771428571428571*G0_1_0_8_1_1 - 0.771428571428568*G0_1_0_9_1_0 + 0.385714285714288*G0_1_0_9_1_1 + 0.771428571428568*G0_1_0_10_1_0 + 1.15714285714286*G0_1_0_10_1_1 - 0.385714285714288*G0_1_0_11_1_1; + A[141] = A[351]; + A[117] = 0.0; + A[382] = 0.0; + A[163] = A[373]; + A[182] = A[392]; + A[283] = 0.0; + A[60] = A[270]; + A[334] = A[124]; + A[137] = 0.0; + A[391] = A[181]; + A[355] = A[145]; + A[372] = A[162]; + A[170] = 0.0; + A[191] = 0.0; + A[200] = 0.0; + A[176] = 0.0; + A[233] = A[23]; + A[290] = A[80]; + A[254] = A[44]; + A[303] = 0.0; + A[275] = A[65]; + A[12] = 0.0; + A[69] = A[279]; + A[29] = A[239]; + A[82] = A[292]; + A[54] = 0.0; + A[103] = A[313]; + A[325] = 0.0; + A[128] = -A[333] - 0.0482142857142853*G0_0_0_0_0_0 - 0.0482142857142855*G0_0_0_0_0_1 - 0.530357142857143*G0_0_0_1_0_0 + 0.819642857142859*G0_0_0_2_0_1 + 1.15714285714286*G0_0_0_3_0_0 - 0.192857142857143*G0_0_0_3_0_1 - 1.15714285714286*G0_0_0_4_0_0 - 0.771428571428573*G0_0_0_4_0_1 + 0.578571428571429*G0_0_0_5_0_0 + 0.192857142857143*G0_0_0_5_0_1 - 0.0482142857142853*G0_0_0_6_1_0 - 0.0482142857142855*G0_0_0_6_1_1 - 0.530357142857143*G0_0_0_7_1_0 + 0.819642857142859*G0_0_0_8_1_1 + 1.15714285714286*G0_0_0_9_1_0 - 0.192857142857143*G0_0_0_9_1_1 - 1.15714285714286*G0_0_0_10_1_0 - 0.771428571428573*G0_0_0_10_1_1 + 0.578571428571429*G0_0_0_11_1_0 + 0.192857142857143*G0_0_0_11_1_1 + 0.385714285714287*G0_1_0_0_0_0 + 0.385714285714287*G0_1_0_0_0_1 + 0.385714285714287*G0_1_0_2_0_1 + 0.385714285714288*G0_1_0_3_0_0 - 0.385714285714288*G0_1_0_4_0_0 - 0.771428571428574*G0_1_0_4_0_1 - 0.385714285714288*G0_1_0_5_0_0 + 0.385714285714287*G0_1_0_6_1_0 + 0.385714285714287*G0_1_0_6_1_1 + 0.385714285714287*G0_1_0_8_1_1 + 0.385714285714288*G0_1_0_9_1_0 - 0.385714285714288*G0_1_0_10_1_0 - 0.771428571428574*G0_1_0_10_1_1 - 0.385714285714288*G0_1_0_11_1_0; + A[88] = -A[128] + 0.385714285714286*G0_1_0_0_0_0 + 0.385714285714286*G0_1_0_0_0_1 + 0.385714285714284*G0_1_0_1_0_0 + 0.385714285714283*G0_1_0_3_0_1 - 0.385714285714287*G0_1_0_4_0_1 - 0.77142857142857*G0_1_0_5_0_0 - 0.385714285714283*G0_1_0_5_0_1 + 0.385714285714286*G0_1_0_6_1_0 + 0.385714285714286*G0_1_0_6_1_1 + 0.385714285714284*G0_1_0_7_1_0 + 0.385714285714283*G0_1_0_9_1_1 - 0.385714285714287*G0_1_0_10_1_1 - 0.77142857142857*G0_1_0_11_1_0 - 0.385714285714283*G0_1_0_11_1_1 - 0.0482142857142866*G0_1_1_0_0_0 - 0.0482142857142863*G0_1_1_0_0_1 + 0.819642857142855*G0_1_1_1_0_0 - 0.530357142857142*G0_1_1_2_0_1 - 0.192857142857143*G0_1_1_3_0_0 + 1.15714285714285*G0_1_1_3_0_1 + 0.192857142857143*G0_1_1_4_0_0 + 0.578571428571429*G0_1_1_4_0_1 - 0.771428571428569*G0_1_1_5_0_0 - 1.15714285714286*G0_1_1_5_0_1 - 0.0482142857142866*G0_1_1_6_1_0 - 0.0482142857142863*G0_1_1_6_1_1 + 0.819642857142855*G0_1_1_7_1_0 - 0.530357142857142*G0_1_1_8_1_1 - 0.192857142857143*G0_1_1_9_1_0 + 1.15714285714285*G0_1_1_9_1_1 + 0.192857142857143*G0_1_1_10_1_0 + 0.578571428571429*G0_1_1_10_1_1 - 0.771428571428569*G0_1_1_11_1_0 - 1.15714285714286*G0_1_1_11_1_1; + A[298] = A[88]; + A[396] = A[186]; + A[340] = 0.0; + A[153] = 0.0; + A[367] = 0.0; + A[192] = 0.0; + A[211] = A[1]; + A[222] = 0.0; + A[293] = A[83]; + A[245] = 0.0; + A[308] = 0.0; + A[268] = 0.0; + A[3] = A[213]; + A[74] = 0.0; + A[22] = A[232]; + A[89] = A[299]; + A[49] = A[259]; + A[112] = 0.0; + A[123] = A[333]; + A[150] = 0.0; + A[338] = A[128]; + A[359] = A[149]; + A[317] = A[107]; + A[261] = 0.0; + A[237] = A[27]; + A[40] = A[250]; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p2_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q3_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q3_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q3_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q4_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q4_excafe.h new file mode 100644 index 0000000..056838d --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q4_excafe.h @@ -0,0 +1,1684 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 38 minutes and 8.52 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + A[574] = 0.0000000000000000000000000; + const double var_0 = -x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = x[1][0] + var_2; + const double var_5 = x[1][1] + var_0; + const double var_6 = var_5*w[0][10]; + const double var_7 = var_4*w[0][3]; + const double var_8 = -var_6 + var_4*w[0][4] + -var_7 + var_5*w[0][9]; + const double var_9 = var_1*var_3*var_8; + const double var_10 = 0.0592592592592592615208247*var_9; + const double var_11 = var_1*var_4; + const double var_12 = -var_3*var_5 + var_11; + const double var_13 = var_12; + const double var_14 = std::abs(var_13); + const double var_15 = var_12; + const double var_16 = var_3*var_3 + var_1*var_1; + const double var_17 = var_5*var_5 + var_4*var_4; + const double var_18 = var_3*var_4 + var_1*var_5; + const double var_19 = -var_4*w[0][8] + var_5*w[0][2]; + const double var_20 = var_4*w[0][8] + -var_5*w[0][2]; + const double var_21 = var_3*var_5*var_5*w[0][9] + -var_1*var_4*var_4*w[0][3]; + const double var_22 = -var_3*var_5*var_5*w[0][10] + var_21 + var_1*var_4*var_4*w[0][4]; + const double var_23 = var_3*var_3*var_5*w[0][3] + -var_1*var_1*var_4*w[0][9]; + const double var_24 = -var_3*var_3*var_5*w[0][5] + var_1*var_1*var_4*w[0][11] + var_23; + const double var_25 = -var_3*var_5*var_5*w[0][11] + var_1*var_4*var_4*w[0][5]; + const double var_26 = -var_3*var_3*var_5*w[0][4] + var_1*var_1*var_4*w[0][10]; + const double var_27 = var_3*var_3*var_4*w[0][10] + -var_1*var_1*var_5*w[0][4]; + const double var_28 = var_1*var_5*var_5*w[0][5] + -var_3*var_4*var_4*w[0][11]; + const double var_29 = var_3*var_4*var_4*w[0][9] + -var_1*var_5*var_5*w[0][3]; + const double var_30 = var_1*var_1*var_5*w[0][3] + -var_3*var_3*var_4*w[0][9]; + const double var_31 = var_1*w[0][5] + -var_3*w[0][11]; + const double var_32 = -var_3*var_4*var_4*w[0][10] + var_1*var_5*var_5*w[0][4]; + const double var_33 = var_3*w[0][4] + -var_1*w[0][10]; + const double var_34 = var_33*var_4*var_5; + const double var_35 = var_3*w[0][7] + -var_1*w[0][1]; + const double var_36 = var_16*var_35; + const double var_37 = var_1*w[0][6]; + const double var_38 = var_4*w[0][0]; + const double var_39 = var_37 + var_38; + const double var_40 = var_3*w[0][0]; + const double var_41 = var_5*w[0][6]; + const double var_42 = var_40 + var_41; + const double var_43 = -var_3*var_39*var_5 + var_1*var_4*var_42; + const double var_44 = var_1*var_1*var_5*w[0][0] + -var_3*var_3*var_4*w[0][6]; + const double var_45 = -var_1*var_5*var_5*w[0][0] + var_3*var_4*var_4*w[0][6]; + const double var_46 = var_45 + var_44; + const double var_47 = var_3*w[0][6] + -var_1*w[0][0]; + const double var_48 = -var_1*var_1*var_4*w[0][6] + var_3*var_3*var_5*w[0][0] + var_16*var_47; + const double var_49 = var_5*w[0][0] + -var_4*w[0][6]; + const double var_50 = -var_1*var_4*var_4*w[0][0] + var_17*var_49 + var_3*var_5*var_5*w[0][6]; + const double var_51 = var_50 + var_48; + const double var_52 = var_46 + 0.3333333333333333148296163*var_51; + const double var_53 = 0.6666666666666666296592325*var_52 + 0.4444444444444444197728217*var_43; + const double var_54 = var_1*w[0][9]; + const double var_55 = -var_3*w[0][3] + var_54; + const double var_56 = var_3*w[0][5]; + const double var_57 = -var_1*w[0][11] + var_56; + const double var_58 = var_55 + var_57; + const double var_59 = var_4*var_5*var_58; + const double var_60 = var_4*w[0][10] + -var_5*w[0][4]; + const double var_61 = 2.0000000000000000000000000*var_17*var_60; + const double var_62 = var_61 + var_59; + const double var_63 = var_17*var_35; + const double var_64 = var_4*w[0][11] + -var_5*w[0][5]; + const double var_65 = -var_4*w[0][9] + var_5*w[0][3] + var_64; + const double var_66 = var_17*var_65; + const double var_67 = 0.1142857142857142821457117*var_66; + const double var_68 = 0.0666666666666666657414808*var_63 + var_67; + const double var_69 = var_1*w[0][4] + -var_3*w[0][10]; + const double var_70 = -var_1*w[0][3] + var_3*w[0][9] + var_69; + const double var_71 = var_16*var_70; + const double var_72 = 4.0000000000000000000000000*var_71; + const double var_73 = 3.2857142857142855874030829*var_16*var_19; + const double var_74 = var_72 + var_73; + const double var_75 = -var_3*w[0][7] + var_1*w[0][1]; + const double var_76 = 0.1174603174603174593482180*var_18*var_75; + const double var_77 = var_3*var_3*var_4*w[0][11] + -var_1*var_1*var_5*w[0][5]; + const double var_78 = 0.6603174603174603030097956*var_77; + const double var_79 = -var_5*w[0][9] + var_7; + const double var_80 = -var_4*w[0][4] + var_6; + const double var_81 = var_79 + var_80; + const double var_82 = var_5*w[0][11] + -var_4*w[0][5]; + const double var_83 = 59.0000000000000000000000000*var_82 + 54.3333333333333285963817616*var_81; + const double var_84 = 0.0507936507936507936067372*var_36 + 0.6158730158730159054414344*var_30 + 0.4222222222222222209886411*var_18*var_20 + 0.2888888888888889172612551*var_25 + var_78 + 0.2126984126984126921566798*var_62 + 0.8666666666666666962726140*var_34 + 0.0984126984126984100109681*var_24 + 0.0095238095238095246686250*var_1*var_3*var_83 + 0.2031746031746031744269487*var_17*var_19 + 0.2507936507936507908311796*var_22 + 0.9587301587301587657563573*var_27 + 0.2730158730158729896153602*var_16*var_31 + 1.1174603174603174871037936*var_32 + 0.4412698412698412564481032*var_26 + 0.0666666666666666657414808*var_74 + var_53 + 0.4634920634920635107434350*var_29 + 0.5015873015873015816623592*var_28 + var_68 + var_76; + A[14] = 1.7777777777777776790912867*var_14*var_84/(var_15*var_15*var_15); + A[479] = A[14]; + const double var_85 = var_3*var_4*var_4*w[0][10] + -var_1*var_5*var_5*w[0][4]; + const double var_86 = var_1*var_3*var_81; + const double var_87 = 2.0000000000000000000000000*var_16*var_31; + const double var_88 = var_26 + var_87; + const double var_89 = var_24 + var_36 + var_88 + var_48; + const double var_90 = var_27 + var_30; + const double var_91 = 0.1428571428571428492126927*var_89 + var_86 + 1.1428571428571427937015414*var_90; + const double var_92 = var_17*var_20; + const double var_93 = var_18*var_75; + const double var_94 = var_5*w[0][4] + -var_4*w[0][10]; + const double var_95 = 2.0000000000000000000000000*var_17*var_94; + const double var_96 = var_1*var_5*var_5*w[0][0] + -var_3*var_4*var_4*w[0][6]; + const double var_97 = var_77 + var_96; + const double var_98 = var_44 + 4.0000000000000000000000000*var_97; + const double var_99 = 0.1142857142857142821457117*var_4*var_5*var_55; + const double var_100 = -var_4*w[0][11] + var_5*w[0][5]; + const double var_101 = 4.0000000000000000000000000*var_100*var_18; + const double var_102 = 0.0158730158730158721347436*var_43; + const double var_103 = var_18*var_19; + const double var_104 = 0.0095238095238095246686250*var_103; + const double var_105 = 0.3333333333333333148296163*var_104; + const double var_106 = 4.0000000000000000000000000*var_66; + const double var_107 = 0.0476190476190476164042309*var_106; + const double var_108 = 13.0000000000000000000000000*var_1*var_3*var_82; + const double var_109 = -var_5*w[0][0] + var_4*w[0][6]; + const double var_110 = var_1*var_4*var_4*w[0][0] + -var_3*var_5*var_5*w[0][6] + var_109*var_17; + const double var_111 = var_63 + var_110; + const double var_112 = -var_3*var_5*var_5*w[0][9] + var_1*var_4*var_4*w[0][3]; + const double var_113 = var_3*var_5*var_5*w[0][10] + var_112 + -var_1*var_4*var_4*w[0][4]; + const double var_114 = 2.0000000000000000000000000*var_29; + const double var_115 = var_113 + var_114; + const double var_116 = 0.1142857142857142821457117*var_95 + 0.0126984126984126984016843*var_34 + var_107 + 0.1238095238095238276310184*var_92 + var_102 + 0.0666666666666666657414808*var_93 + 0.0285714285714285705364279*var_101 + 0.0253968253968253968033686*var_85 + 0.0222222222222222230703093*var_98 + 0.0380952380952380986744998*var_115 + 0.0444444444444444461406185*var_91 + 0.1047619047619047782937685*var_111 + var_99 + var_105 + 0.0063492063492063492008421*var_108; + A[408] = 0.0000000000000000000000000; + const double var_117 = -var_3*var_3*var_4*w[0][11] + var_1*var_1*var_5*w[0][5]; + const double var_118 = -var_1*var_1*var_5*w[0][3] + var_3*var_3*var_4*w[0][9]; + const double var_119 = -var_3*var_3*var_4*w[0][10] + var_1*var_1*var_5*w[0][4]; + const double var_120 = -var_1*var_1*var_4*w[0][10] + var_3*var_3*var_5*w[0][4]; + const double var_121 = -var_54 + var_1*w[0][11] + var_3*w[0][3] + -var_56; + const double var_122 = -var_1*w[0][6] + var_40; + const double var_123 = var_18*var_47 + var_122*var_4*var_5; + const double var_124 = -var_3*w[0][4] + var_1*w[0][10]; + const double var_125 = var_124*var_4*var_5; + const double var_126 = -var_1*var_4*var_4*w[0][5] + var_3*var_5*var_5*w[0][11]; + const double var_127 = var_126 + var_95; + const double var_128 = var_110 + var_113 + var_92 + var_127; + const double var_129 = -var_3*var_4*var_4*w[0][9] + var_1*var_5*var_5*w[0][3]; + const double var_130 = -var_1*var_5*var_5*w[0][5] + var_3*var_4*var_4*w[0][11]; + const double var_131 = var_130 + var_129; + const double var_132 = 0.0412698412698412689381122*var_96; + const double var_133 = 0.0507936507936507936067372*var_85; + const double var_134 = var_4*w[0][5] + -var_5*w[0][11]; + const double var_135 = 1.8888888888888888395456433*var_1*var_134*var_3; + const double var_136 = var_135 + var_9; + const double var_137 = var_133 + var_104 + 0.1206349206349206365507243*var_121*var_4*var_5 + 0.0730158730158730201464934*var_18*var_35 + var_132 + 0.0444444444444444461406185*var_125 + 0.0063492063492063492008421*var_128 + 0.0349206349206349214719936*var_123 + 0.1269841269841269770779490*var_131 + 0.0571428571428571410728559*var_136; + const double var_138 = -var_1*w[0][4] + var_3*w[0][10]; + const double var_139 = -var_3*w[0][9] + var_1*w[0][3]; + const double var_140 = var_138 + var_139; + const double var_141 = var_140*var_16; + const double var_142 = var_16*var_20; + const double var_143 = 0.1523809523809523946979994*var_141 + 0.0952380952380952328084618*var_142; + const double var_144 = -var_3*var_3*var_5*w[0][3] + var_1*var_1*var_4*w[0][9]; + const double var_145 = var_3*var_3*var_5*w[0][5] + -var_1*var_1*var_4*w[0][11] + var_144; + const double var_146 = var_87 + var_145; + const double var_147 = 0.0952380952380952328084618*var_120 + var_143 + 0.0190476190476190493372499*var_146 + 0.1269841269841269770779490*var_117 + var_137 + 0.1523809523809523946979994*var_119 + 0.0761904761904761973489997*var_118 + 0.0380952380952380986744998*var_36; + const double var_148 = 0.0571428571428571410728559*var_59; + const double var_149 = -var_3*w[0][6] + var_1*w[0][0]; + const double var_150 = var_149 + var_109; + const double var_151 = var_150 + var_35; + A[108] = 0.0000000000000000000000000; + const double var_152 = var_1*var_3*var_82; + const double var_153 = var_152 + var_24; + const double var_154 = var_16*var_19; + const double var_155 = 0.0476190476190476164042309*var_154; + const double var_156 = var_63 + var_106; + const double var_157 = 0.1777777777777777845624740*var_77; + const double var_158 = 0.0571428571428571410728559*var_156 + var_157; + const double var_159 = 3.8666666666666666962726140*var_27 + var_22; + const double var_160 = 0.1142857142857142821457117*var_71; + const double var_161 = var_3*var_39*var_5 + -var_1*var_4*var_42; + const double var_162 = 0.0349206349206349214719936*var_161; + const double var_163 = 0.2539682539682539541558981*var_30; + const double var_164 = 0.2857142857142856984253854*var_59; + const double var_165 = var_114 + var_110; + const double var_166 = var_16*var_31; + const double var_167 = 5.3333333333333330372738601*var_166 + 1.6000000000000000888178420*var_92; + const double var_168 = var_18*var_20; + const double var_169 = 0.1428571428571428492126927*var_168; + const double var_170 = 0.0476190476190476164042309*var_167 + 0.1523809523809523946979994*var_28 + var_164 + 0.0952380952380952328084618*var_159 + 0.0317460317460317442694873*var_125 + 0.1206349206349206365507243*var_44 + 0.1555555555555555580227178*var_48 + 0.1650793650793650757524489*var_1*var_3*var_81 + 0.1333333333333333314829616*var_127 + 0.1238095238095238276310184*var_93 + var_155 + var_162 + 0.3333333333333333148296163*var_160 + 0.0634920634920634885389745*var_32 + 0.1904761904761904656169236*var_165 + 0.2253968253968254009667049*var_96 + 0.0222222222222222230703093*var_169 + 0.2031746031746031744269487*var_26 + 0.0984126984126984100109681*var_16*var_35 + 0.0888888888888888922812370*var_153 + var_158 + var_163; + A[282] = 14.2222222222222214327302936*var_14*var_170/(var_15*var_15*var_15); + A[258] = 0.0000000000000000000000000; + const double var_171 = var_18*var_35; + const double var_172 = 0.6666666666666666296592325*var_4*var_5*var_58; + const double var_173 = 0.0031746031746031746004211*var_43; + const double var_174 = var_17*var_75; + const double var_175 = -var_5*w[0][3] + var_4*w[0][9]; + const double var_176 = var_100 + var_175; + const double var_177 = var_17*var_176; + const double var_178 = 0.0380952380952380986744998*var_177; + const double var_179 = 0.0285714285714285705364279*var_174 + var_178; + const double var_180 = 0.3619047619047619512855363*var_1*var_3*var_81; + const double var_181 = var_1*var_134*var_3; + const double var_182 = 0.6666666666666666296592325*var_117 + var_181; + const double var_183 = 8.0000000000000000000000000*var_33*var_4*var_5; + const double var_184 = 0.0095238095238095246686250*var_44; + const double var_185 = 0.0095238095238095246686250*var_183 + 0.1269841269841269770779490*var_90 + 0.0730158730158730201464934*var_18*var_20 + 0.0222222222222222230703093*var_171 + 0.3333333333333333148296163*var_180 + var_179 + 0.0063492063492063492008421*var_89 + var_173 + 0.0380952380952380986744998*var_172 + 0.0190476190476190493372499*var_182 + var_184; + const double var_186 = var_17*var_19; + const double var_187 = var_61 + var_22; + const double var_188 = var_25 + var_114; + const double var_189 = 0.1777777777777777845624740*var_32; + const double var_190 = 0.0634920634920634885389745*var_188 + 0.1111111111111111049432054*var_186 + var_189 + 0.0920634920634920694837433*var_50 + 0.0952380952380952328084618*var_45 + 0.0888888888888888922812370*var_28 + 0.1015873015873015872134744*var_187 + var_185; + A[252] = 14.2222222222222214327302936*var_14*var_190/(var_15*var_15*var_15); + const double var_191 = 23.0000000000000000000000000*var_82 + 83.0000000000000000000000000*var_81; + const double var_192 = var_19 + var_35; + const double var_193 = var_1*var_1*var_4*w[0][6] + -var_3*var_3*var_5*w[0][0] + var_149*var_16; + const double var_194 = var_110 + var_193; + const double var_195 = -var_1*var_1*var_5*w[0][0] + var_3*var_3*var_4*w[0][6]; + const double var_196 = var_195 + var_96; + const double var_197 = 0.3333333333333333148296163*var_194 + 0.6666666666666666296592325*var_161 + var_196; + const double var_198 = -var_1*w[0][5] + var_3*w[0][11]; + const double var_199 = var_16*var_198; + const double var_200 = var_17*var_94; + const double var_201 = var_199 + var_200; + const double var_202 = var_113 + var_145; + const double var_203 = var_118 + var_129; + const double var_204 = var_125 + var_181; + const double var_205 = var_121*var_4*var_5; + const double var_206 = var_9 + var_205; + const double var_207 = var_177 + var_141; + const double var_208 = var_119 + var_130; + const double var_209 = var_85 + var_117; + const double var_210 = var_16*var_75; + const double var_211 = var_92 + var_210; + const double var_212 = var_142 + var_174; + const double var_213 = var_120 + var_126; + const double var_214 = 0.2380952380952380820211545*var_212 + 1.7777777777777776790912867*var_209 + 1.5714285714285713968507707*var_204 + 0.7936507936507936067371816*var_201 + 0.1904761904761904656169236*var_207 + 1.6190476190476190687661529*var_197 + 0.2063492063492063377516672*var_202 + 1.1746031746031746489933312*var_208 + 0.6031746031746031411202580*var_203 + 0.2539682539682539541558981*var_211 + 0.4920634920634920361770526*var_18*var_192 + 0.3968253968253968033685908*var_206 + 0.7777777777777777901135892*var_213; + A[12] = 1.7777777777777776790912867*var_14*var_214/(var_15*var_15*var_15); + A[825] = A[12]; + const double var_215 = 0.6666666666666666296592325*var_1*var_3*var_81; + const double var_216 = var_215 + var_25; + const double var_217 = var_32 + var_27; + const double var_218 = 0.1174603174603174593482180*var_17*var_35; + const double var_219 = 2.0000000000000000000000000*var_30; + const double var_220 = var_36 + var_219; + const double var_221 = 0.1111111111111111049432054*var_43; + const double var_222 = 0.0571428571428571410728559*var_86; + const double var_223 = 0.1650793650793650757524489*var_66; + const double var_224 = var_154 + var_72; + const double var_225 = 0.0063492063492063492008421*var_224; + const double var_226 = var_183 + var_61; + const double var_227 = 0.3809523809523809312338471*var_172 + 0.2793650793650793717759484*var_29 + var_225 + var_222 + 0.1269841269841269770779490*var_217 + 0.1650793650793650757524489*var_25 + 0.0222222222222222230703093*var_92 + 0.0634920634920634885389745*var_48 + var_221 + 0.2984126984126984072354105*var_1*var_3*var_82 + 0.0761904761904761973489997*var_220 + 0.0253968253968253968033686*var_22 + var_218 + 0.1873015873015873022922051*var_18*var_75 + 0.3936507936507936400438723*var_77 + var_104 + 0.1587301587301587213474363*var_45 + 0.0476190476190476164042309*var_50 + 0.4190476190476191131750738*var_28 + 0.0698412698412698429439871*var_88 + 0.1746031746031745934821799*var_44 + 0.0952380952380952328084618*var_24 + 0.0126984126984126984016843*var_226 + var_223; + const double var_228 = 2.0000000000000000000000000*var_16*var_198; + const double var_229 = var_120 + var_228; + const double var_230 = var_229 + var_210 + var_193 + var_145; + const double var_231 = var_119 + var_118; + const double var_232 = 0.1428571428571428492126927*var_230 + 0.5714285714285713968507707*var_85 + var_9 + 1.1428571428571427937015414*var_231; + A[202] = 0.0000000000000000000000000; + A[116] = 0.0000000000000000000000000; + const double var_233 = var_117 + var_118; + A[522] = 0.0000000000000000000000000; + const double var_234 = var_126 + var_50; + A[873] = 0.0000000000000000000000000; + A[46] = 0.0000000000000000000000000; + const double var_235 = var_30 + var_77; + const double var_236 = 12.5333333333333332149095440*var_31 + 6.8000000000000007105427358*var_20 + 7.6666666666666660745477202*var_35; + const double var_237 = -var_4*w[0][0] + var_41; + const double var_238 = var_18*var_49 + var_1*var_237*var_3; + const double var_239 = 2.0000000000000000000000000*var_18*var_60; + const double var_240 = var_181 + var_9 + var_238 + var_103 + var_239; + const double var_241 = var_240 + var_120 + 2.0000000000000000000000000*var_119; + const double var_242 = 0.4000000000000000222044605*var_141 + 0.1358024691358024615972511*var_24 + 0.1802469135802469146767635*var_48 + 0.0641975308641975356271914*var_235 + 0.0716049382716049398478475*var_241 + 0.0370370370370370349810685*var_16*var_236 + 0.1086419753086419748289160*var_44; + A[37] = 0.2857142857142856984253854*var_14*var_242/(var_15*var_15*var_15); + A[545] = 0.0000000000000000000000000; + const double var_243 = var_200 + var_71; + const double var_244 = var_117 + var_130; + const double var_245 = var_210 + var_48; + const double var_246 = var_141 + var_9; + const double var_247 = var_154 + var_168; + const double var_248 = 11.0000000000000000000000000*var_121*var_4*var_5; + const double var_249 = 0.0539682539682539708092435*var_161; + const double var_250 = var_113 + var_34; + const double var_251 = 0.0571428571428571410728559*var_44; + const double var_252 = 2.0000000000000000000000000*var_1*var_134*var_3; + const double var_253 = var_252 + var_126; + const double var_254 = var_177 + var_253; + const double var_255 = 0.0126984126984126984016843*var_95; + const double var_256 = 0.0476190476190476164042309*var_110; + const double var_257 = 0.4444444444444444197728217*var_129 + 0.0793650793650793606737182*var_247 + 0.5841269841269841611719471*var_244 + 0.0253968253968253968033686*var_250 + 0.2761904761904762084512299*var_18*var_35 + var_251 + 0.0634920634920634885389745*var_246 + 0.0222222222222222230703093*var_186 + var_249 + 0.1904761904761904656169236*var_26 + var_255 + 0.1111111111111111049432054*var_245 + 0.3174603174603174426948726*var_118 + 0.1269841269841269770779490*var_27 + 0.1015873015873015872134744*var_96 + 0.2539682539682539541558981*var_145 + 0.1174603174603174593482180*var_17*var_75 + 0.1650793650793650757524489*var_254 + 0.0380952380952380986744998*var_248 + var_256; + A[355] = 0.0000000000000000000000000; + const double var_258 = -var_5*w[0][6] + var_38; + const double var_259 = 4.0000000000000000000000000*var_138*var_18; + const double var_260 = var_168 + var_193 + var_16*var_192 + 4.0000000000000000000000000*var_219 + var_259 + var_72; + const double var_261 = 0.1142857142857142821457117*var_1*var_3*var_79; + const double var_262 = 0.0285714285714285705364279*var_260 + 0.1142857142857142821457117*var_24 + var_261; + const double var_263 = 0.1015873015873015872134744*var_17*var_176 + 0.0634920634920634885389745*var_174; + const double var_264 = var_244 + var_195 + var_29; + const double var_265 = 0.0571428571428571410728559*var_61; + const double var_266 = 0.0063492063492063492008421*var_205; + const double var_267 = 0.0158730158730158721347436*var_171; + const double var_268 = 0.0222222222222222230703093*var_161; + const double var_269 = var_125 + var_126; + const double var_270 = 0.0317460317460317442694873*var_22 + 0.0698412698412698429439871*var_17*var_19 + 0.0126984126984126984016843*var_32 + var_266 + 0.1111111111111111049432054*var_262 + 0.0222222222222222230703093*var_45 + 0.0444444444444444461406185*var_50 + var_265 + var_267 + var_263 + var_268 + 0.0380952380952380986744998*var_181 + 0.0253968253968253968033686*var_264 + 0.0190476190476190493372499*var_269; + A[314] = 10.6666666666666660745477202*var_14*var_270/(var_15*var_15*var_15); + A[779] = A[314]; + const double var_271 = var_25 + var_61; + const double var_272 = 0.0380952380952380986744998*var_141; + const double var_273 = 0.0285714285714285705364279*var_142 + var_272; + const double var_274 = 0.0571428571428571410728559*var_113; + const double var_275 = var_273 + 0.0349206349206349214719936*var_103 + var_274; + const double var_276 = 4.0000000000000000000000000*var_17*var_176 + var_174; + const double var_277 = 0.0761904761904761973489997*var_130; + const double var_278 = 0.1523809523809523946979994*var_129 + 0.0190476190476190493372499*var_276 + var_277; + const double var_279 = 0.0412698412698412689381122*var_45; + const double var_280 = 0.1269841269841269770779490*var_118; + const double var_281 = 0.0158730158730158721347436*var_210 + 0.0952380952380952328084618*var_205; + const double var_282 = 0.0507936507936507936067372*var_117; + const double var_283 = var_228 + var_145; + const double var_284 = var_283 + var_181; + const double var_285 = var_195 + 2.0000000000000000000000000*var_120; + const double var_286 = var_125 + var_285; + const double var_287 = 0.1015873015873015872134744*var_1*var_3*var_8 + var_278 + var_279 + var_280 + var_282 + 0.0380952380952380986744998*var_50 + var_173 + 0.1650793650793650757524489*var_119 + 0.0349206349206349214719936*var_193 + var_275 + var_281 + 0.0888888888888888922812370*var_85 + 0.0190476190476190493372499*var_271 + 0.0253968253968253968033686*var_284 + 0.0285714285714285705364279*var_171 + 0.0317460317460317442694873*var_286; + A[284] = 14.2222222222222214327302936*var_14*var_287/(var_15*var_15*var_15); + A[894] = A[284]; + const double var_288 = 0.1777777777777777845624740*var_85; + const double var_289 = var_288 + var_186; + const double var_290 = var_142 + var_103; + const double var_291 = 0.0095238095238095246686250*var_161; + const double var_292 = 0.3333333333333333148296163*var_291; + const double var_293 = var_127 + var_248; + const double var_294 = var_44 + var_276; + const double var_295 = 0.0031746031746031746004211*var_110; + const double var_296 = var_292 + 0.2878306878306878258122481*var_118 + 0.0042328042328042330896820*var_294 + 0.0095238095238095246686250*var_96 + 0.1142857142857142821457117*var_85 + 0.0148148148148148153802062*var_92 + 0.2582010582010582089296236*var_119 + 0.1058201058201058142316242*var_145 + 2.0000000000000000000000000*var_295 + 0.0211640211640211628463248*var_181 + 0.0105820105820105814231624*var_293 + 0.0867724867724867787721621*var_124*var_4*var_5 + 0.0761904761904761973489997*var_120 + 0.1439153439153439129061240*var_129 + 0.0275132275132275137818905*var_113 + 0.0179894179894179891132655*var_171 + 0.1269841269841269770779490*var_244 + 0.1820105820105820115806239*var_246 + 0.0074074074074074076901031*var_245 + 0.0835978835978836015696558*var_290; + A[127] = 4.0000000000000000000000000*var_14*var_296/(var_15*var_15*var_15); + A[679] = A[127]; + A[369] = A[282]; + const double var_297 = -var_3*w[0][0] + var_37; + const double var_298 = var_149*var_18 + var_297*var_4*var_5; + const double var_299 = 1.1333333333333333037273860*var_17*var_75; + const double var_300 = 2.0000000000000000000000000*var_18*var_31; + const double var_301 = 34.6000000000000014210854715*var_33 + 5.0000000000000000000000000*var_58; + const double var_302 = var_140*var_18 + var_29; + const double var_303 = 38.6000000000000014210854715*var_22 + 21.2000000000000028421709430*var_17*var_19 + 14.8000000000000007105427358*var_17*var_60 + 6.4000000000000003552713679*var_110 + 43.6000000000000014210854715*var_302 + 2.0000000000000000000000000*var_300 + 29.2000000000000028421709430*var_18*var_20 + 11.6000000000000014210854715*var_130 + var_301*var_4*var_5 + 9.4000000000000003552713679*var_18*var_35 + 16.6000000000000014210854715*var_126 + var_96; + const double var_304 = 0.2000000000000000111022302*var_298 + 2.7111111111111112492721986*var_32 + 0.3333333333333333148296163*var_299 + 0.0370370370370370349810685*var_303 + 0.0666666666666666657414808*var_106; + A[66] = 0.3809523809523809312338471*var_14*var_304/(var_15*var_15*var_15); + const double var_305 = 0.0730158730158730201464934*var_17*var_35 + var_67; + const double var_306 = 0.1375661375661375585011115*var_96 + 0.4656084656084655826191465*var_117; + const double var_307 = 0.0592592592592592615208247*var_205; + const double var_308 = 0.0141093474426807752308832*var_228; + const double var_309 = 0.0299823633156966473656269*var_161; + const double var_310 = 0.5206349206349206726329726*var_16*var_70; + const double var_311 = var_310 + var_255; + const double var_312 = 0.0363315696649030017706394*var_18*var_19 + 0.1333333333333333314829616*var_306 + 0.0056437389770723107862427*var_145 + 0.1259259259259259411400933*var_16*var_19 + 0.0253968253968253968033686*var_28 + 0.0049382716049382715042815*var_195 + 0.0691358024691357958557703*var_1*var_3*var_8 + 0.0211640211640211628463248*var_159 + 0.0663139329805996491362663*var_124*var_4*var_5 + var_307 + 0.0380952380952380986744998*var_129 + 0.3333333333333333148296163*var_311 + 0.0747795414462081170503538*var_118 + 0.0451499118165784862899415*var_85 + var_308 + 0.0201058201058201060917874*var_17*var_20 + 0.0116402116402116416471468*var_50 + 0.0846560846560846513852994*var_25 + 0.1509700176366843005215657*var_26 + var_309 + var_305 + 0.0564373897707231009235329*var_181 + 0.0250440917107583801981541*var_48 + 0.0532627865961199306599205*var_16*var_75 + 0.0264550264550264535579061*var_18*var_35; + const double var_313 = var_298 + var_59 + 2.0000000000000000000000000*var_18*var_198 + var_34 + var_93; + const double var_314 = var_85 + var_129; + const double var_315 = 0.5238095238095238359576911*var_113 + 0.0476190476190476164042309*var_313 + 0.6666666666666666296592325*var_92 + 0.4761904761904761640423089*var_314; + const double var_316 = 0.1873015873015873022922051*var_96; + const double var_317 = var_68 + 0.1206349206349206365507243*var_130 + 0.3333333333333333148296163*var_315 + 0.1365079365079364948076801*var_126 + 0.4253968253968253843133596*var_17*var_94 + var_316 + 0.2031746031746031744269487*var_110; + A[72] = 1.7777777777777776790912867*var_14*var_317/(var_15*var_15*var_15); + A[827] = A[72]; + A[358] = 0.0000000000000000000000000; + const double var_318 = 0.0571428571428571410728559*var_145; + const double var_319 = var_179 + 0.0349206349206349214719936*var_171 + var_318; + const double var_320 = 4.0000000000000000000000000*var_140*var_16 + var_142; + const double var_321 = 0.0761904761904761973489997*var_119; + const double var_322 = 0.1523809523809523946979994*var_118 + 0.0190476190476190493372499*var_320 + var_321; + const double var_323 = 0.0412698412698412689381122*var_44; + const double var_324 = 0.1269841269841269770779490*var_129; + const double var_325 = 0.0952380952380952328084618*var_9 + 0.0158730158730158721347436*var_92; + const double var_326 = var_113 + var_95; + const double var_327 = var_125 + var_326; + const double var_328 = 2.0000000000000000000000000*var_126 + var_96; + const double var_329 = var_328 + var_181; + const double var_330 = 0.1015873015873015872134744*var_121*var_4*var_5 + var_323 + var_322 + 0.0380952380952380986744998*var_48 + 0.0190476190476190493372499*var_88 + 0.0285714285714285705364279*var_103 + var_324 + 0.1650793650793650757524489*var_130 + 0.0253968253968253968033686*var_327 + var_319 + 0.0888888888888888922812370*var_117 + var_173 + var_325 + 0.0349206349206349214719936*var_110 + var_133 + 0.0317460317460317442694873*var_329; + A[193] = 14.2222222222222214327302936*var_14*var_330/(var_15*var_15*var_15); + A[658] = A[193]; + A[451] = 0.0000000000000000000000000; + A[638] = 0.0000000000000000000000000; + const double var_331 = 0.0476190476190476164042309*var_193; + const double var_332 = var_205 + var_125 + var_171 + var_123 + var_300; + const double var_333 = var_32 + var_29; + const double var_334 = 0.3809523809523809312338471*var_17*var_19; + const double var_335 = 0.2380952380952380820211545*var_22 + 0.1333333333333333314829616*var_333 + 0.1047619047619047782937685*var_332 + var_334; + const double var_336 = 0.2095238095238095565875369*var_17*var_176 + 0.0666666666666666657414808*var_174; + const double var_337 = 0.3904761904761905322303051*var_25 + 0.4571428571428571285828468*var_50 + 0.3523809523809524058002296*var_45 + 0.2857142857142856984253854*var_28 + 0.8380952380952382263501477*var_17*var_60 + var_335 + var_336; + A[69] = 0.2962962962962962798485478*var_14*var_337/(var_15*var_15*var_15); + A[272] = A[69]; + const double var_338 = var_66 + var_199; + A[174] = 0.0000000000000000000000000; + A[351] = 0.0000000000000000000000000; + const double var_339 = var_271 + var_186 + var_50 + var_22; + const double var_340 = var_28 + var_29; + const double var_341 = 0.3619047619047619512855363*var_4*var_5*var_58; + const double var_342 = var_125 + 0.6666666666666666296592325*var_85; + const double var_343 = 8.0000000000000000000000000*var_1*var_3*var_82; + const double var_344 = 0.0095238095238095246686250*var_45; + const double var_345 = 0.3333333333333333148296163*var_341 + 0.0730158730158730201464934*var_18*var_75 + 0.0380952380952380986744998*var_215 + 0.0190476190476190493372499*var_342 + 0.0222222222222222230703093*var_103 + 0.1269841269841269770779490*var_340 + var_273 + 0.0063492063492063492008421*var_339 + 0.0095238095238095246686250*var_343 + var_173 + var_344; + const double var_346 = var_87 + var_24; + const double var_347 = var_26 + var_219; + const double var_348 = 0.0634920634920634885389745*var_347 + 0.0920634920634920694837433*var_48 + 0.1015873015873015872134744*var_346 + var_345 + 0.0888888888888888922812370*var_27 + 0.1111111111111111049432054*var_36 + 0.0952380952380952328084618*var_44 + var_157; + A[342] = 14.2222222222222214327302936*var_14*var_348/(var_15*var_15*var_15); + const double var_349 = var_109*var_18 + var_1*var_258*var_3; + const double var_350 = 1.1333333333333333037273860*var_16*var_20; + const double var_351 = 34.6000000000000014210854715*var_82 + 5.0000000000000000000000000*var_81; + const double var_352 = var_176*var_18 + var_30; + const double var_353 = 21.2000000000000028421709430*var_16*var_35 + 6.4000000000000003552713679*var_193 + 11.6000000000000014210854715*var_119 + 43.6000000000000014210854715*var_352 + 16.6000000000000014210854715*var_120 + 14.8000000000000007105427358*var_16*var_31 + var_195 + 29.2000000000000028421709430*var_18*var_75 + var_1*var_3*var_351 + 9.4000000000000003552713679*var_18*var_19 + 2.0000000000000000000000000*var_239 + 38.6000000000000014210854715*var_24; + const double var_354 = 0.3333333333333333148296163*var_350 + 0.2000000000000000111022302*var_349 + 2.7111111111111112492721986*var_77 + 0.0666666666666666657414808*var_72 + 0.0370370370370370349810685*var_353; + A[39] = 0.3809523809523809312338471*var_14*var_354/(var_15*var_15*var_15); + const double var_355 = 0.3174603174603174426948726*var_17*var_65 + 0.4158730158730158943392041*var_17*var_75; + const double var_356 = var_171 + var_298; + const double var_357 = var_355 + 2.2158730158730159942592763*var_18*var_20 + 2.3936507936507935845327211*var_29 + 3.0920634920634921805060458*var_140*var_18 + 1.4539682539682539097469771*var_17*var_19 + 2.1873015873015870802476002*var_22 + 2.8857142857142856762209249*var_33*var_4*var_5 + 1.7587301587301586991429758*var_17*var_60 + 0.1111111111111111049432054*var_126 + 5.0730158730158727564685250*var_32 + 0.0952380952380952328084618*var_28 + 0.3047619047619047893959987*var_50 + 0.9746031746031745823799497*var_45 + 0.2063492063492063377516672*var_59 + 0.6698412698412697929839510*var_356; + A[68] = 0.8888888888888888395456433*var_14*var_357/(var_15*var_15*var_15); + A[242] = A[68]; + const double var_358 = 4.0000000000000000000000000*var_114 + var_93 + var_101 + var_110 + var_17*var_192 + var_106; + const double var_359 = 0.0285714285714285705364279*var_358 + var_99 + 0.1142857142857142821457117*var_22; + const double var_360 = 0.2222222222222222098864108*var_71 + 0.1111111111111111049432054*var_73; + const double var_361 = 1.0158730158730158166235924*var_16*var_198; + const double var_362 = 20.2000000000000028421709430*var_134 + 1.4444444444444444197728217*var_8; + const double var_363 = 1.1111111111111111604543567*var_118; + const double var_364 = var_238 + var_168; + const double var_365 = var_361 + 0.7619047619047618624676943*var_210 + 0.0952380952380952328084618*var_119 + 0.2539682539682539541558981*var_193 + var_363 + 3.0920634920634921805060458*var_18*var_65 + 0.1111111111111111049432054*var_26 + 2.2158730158730159942592763*var_18*var_35 + 0.9238095238095238581621516*var_195 + 0.9047619047619047671915382*var_145 + 3.7904761904761907764793705*var_117 + var_360 + 0.6698412698412697929839510*var_364 + 0.1428571428571428492126927*var_1*var_3*var_362; + A[33] = 0.8888888888888888395456433*var_14*var_365/(var_15*var_15*var_15); + A[143] = 0.0000000000000000000000000; + const double var_366 = 0.0507936507936507936067372*var_77 + 0.0444444444444444461406185*var_232; + const double var_367 = 0.0349206349206349214719936*var_43; + const double var_368 = 0.0158730158730158721347436*var_103; + const double var_369 = 0.0063492063492063492008421*var_156; + const double var_370 = 0.0190476190476190493372499*var_34; + const double var_371 = var_369 + 0.0761904761904761973489997*var_110 + var_266 + var_277 + 0.4000000000000000222044605*var_324 + 0.0222222222222222230703093*var_93 + 0.0285714285714285705364279*var_44 + var_367 + 0.0571428571428571410728559*var_152 + var_370 + 0.0634920634920634885389745*var_92 + 0.0444444444444444461406185*var_113 + var_368 + 0.0698412698412698429439871*var_127 + var_132 + var_366; + A[237] = 0.0000000000000000000000000; + const double var_372 = 0.1396825396825396858879742*var_181; + const double var_373 = 0.0687830687830687792505557*var_161; + const double var_374 = var_110 + var_186; + const double var_375 = var_113 + var_125; + const double var_376 = 0.0888888888888888922812370*var_375 + 0.7079365079365079749251777*var_17*var_75 + 0.9142857142857142571656937*var_126 + 0.7492063492063492091688204*var_118 + 1.0031746031746031633247185*var_177 + var_288 + 0.2063492063492063377516672*var_374; + const double var_377 = 0.1174603174603174593482180*var_18*var_20; + const double var_378 = var_376 + var_377; + const double var_379 = 0.0285714285714285705364279*var_320; + const double var_380 = var_306 + 0.1047619047619047782937685*var_16*var_75 + var_379 + 0.3047619047619047893959987*var_205 + 0.1375661375661375585011115*var_252 + 0.1354497354497354588698244*var_119 + 0.0761904761904761973489997*var_229 + 0.1164021164021163956547866*var_195 + 0.3343915343915344062786232*var_129 + var_373 + 0.3333333333333333148296163*var_378 + 0.1904761904761904656169236*var_145 + var_10 + 0.6095238095238095787919974*var_130 + 0.2063492063492063377516672*var_171 + var_331; + A[93] = 21.3333333333333321490954404*var_14*var_380/(var_15*var_15*var_15); + A[558] = A[93]; + const double var_381 = 3.8666666666666666962726140*var_28 + var_24; + const double var_382 = var_93 + var_168; + const double var_383 = var_36 + var_186; + const double var_384 = var_28 + var_27; + const double var_385 = var_320 + var_276; + const double var_386 = var_271 + var_88; + const double var_387 = 0.0190476190476190493372499*var_202; + const double var_388 = var_59 + var_86; + const double var_389 = var_114 + var_219; + const double var_390 = 0.0317460317460317442694873*var_386 + 0.1174603174603174593482180*var_196 + 0.0444444444444444461406185*var_51 + 0.0190476190476190493372499*var_383 + 0.0126984126984126984016843*var_385 + 0.2793650793650793717759484*var_384 + 0.1523809523809523946979994*var_209 + 0.1619047619047619124277304*var_161 + 0.1142857142857142821457117*var_389 + 0.2476190476190476552620368*var_388 + 0.1333333333333333314829616*var_204 + 0.0285714285714285705364279*var_382 + var_387; + const double var_391 = 1.3333333333333332593184650*var_71 + var_154; + const double var_392 = 0.1142857142857142821457117*var_391; + const double var_393 = 4.0000000000000000000000000*var_28 + var_50; + const double var_394 = 0.2444444444444444641817427*var_43; + const double var_395 = 0.6603174603174603030097956*var_32; + const double var_396 = var_34 + var_77; + const double var_397 = 0.1428571428571428492126927*var_93; + const double var_398 = 0.2666666666666666629659233*var_59 + 0.2285714285714285642914234*var_188 + 0.0444444444444444461406185*var_36 + 0.3682539682539682779349732*var_45 + 0.4698412698412698373928720*var_396 + 0.3650793650793650590991035*var_44 + 0.2253968253968254009667049*var_18*var_20 + var_392 + 0.1206349206349206365507243*var_48 + 0.5841269841269841611719471*var_27 + 0.4317460317460317664739478*var_30 + var_395 + 0.1047619047619047782937685*var_17*var_192 + 0.2349206349206349186964360*var_26 + 0.0825396825396825378762244*var_346 + 2.0000000000000000000000000*var_265 + var_107 + 0.5238095238095238359576911*var_215 + 0.3873015873015873133944353*var_1*var_3*var_82 + var_394 + 0.1904761904761904656169236*var_22 + 0.1238095238095238276310184*var_393 + var_397; + A[129] = 1.7777777777777776790912867*var_14*var_398/(var_15*var_15*var_15); + const double var_399 = 0.0063492063492063492008421*var_9; + const double var_400 = 7.6666666666666660745477202*var_19 + 6.8000000000000007105427358*var_75 + 12.5333333333333332149095440*var_60; + const double var_401 = 0.0476190476190476164042309*var_63; + const double var_402 = 0.0931216931216931331771747*var_119; + const double var_403 = var_17*var_60; + const double var_404 = var_28 + var_403; + const double var_405 = 0.1777777777777777845624740*var_117; + const double var_406 = var_405 + var_36; + const double var_407 = 0.1396825396825396858879742*var_125; + const double var_408 = var_407 + var_318; + const double var_409 = var_178 + var_288 + var_401 + 0.1312169312169312318516745*var_129 + 0.0962962962962962965018932*var_18*var_19 + 0.1079365079365079416184869*var_44 + 0.1693121693121693027705987*var_9 + 0.6666666666666666296592325*var_408 + 0.0010582010582010582724205*var_186 + 0.0476190476190476164042309*var_406 + var_379 + 0.0465608465608465665885873*var_205 + 0.1047619047619047782937685*var_48 + var_173 + 0.1343915343915343951763930*var_50 + 0.0846560846560846513852994*var_113 + 0.0264550264550264535579061*var_18*var_75 + 0.0761904761904761973489997*var_88 + 0.2074074074074074292006742*var_118 + 0.1375661375661375585011115*var_45 + 0.0296296296296296307604123*var_152 + var_402 + 0.1820105820105820115806239*var_25 + 0.1354497354497354588698244*var_404; + A[186] = 21.3333333333333321490954404*var_14*var_409/(var_15*var_15*var_15); + A[651] = A[186]; + const double var_410 = var_87 + var_130; + A[457] = 0.0000000000000000000000000; + const double var_411 = 0.0634920634920634885389745*var_142 + 0.1015873015873015872134744*var_140*var_16; + const double var_412 = var_119 + var_85; + const double var_413 = var_30 + var_412 + var_96; + const double var_414 = 0.0571428571428571410728559*var_87; + const double var_415 = var_120 + var_181; + const double var_416 = var_268 + 0.0698412698412698429439871*var_16*var_35 + var_414 + 0.0126984126984126984016843*var_77 + var_368 + 0.0444444444444444461406185*var_48 + 0.0253968253968253968033686*var_413 + 0.0380952380952380986744998*var_125 + 0.0317460317460317442694873*var_24 + 0.0222222222222222230703093*var_44 + 0.1111111111111111049432054*var_359 + var_399 + 0.0190476190476190493372499*var_415 + var_411; + A[223] = 10.6666666666666660745477202*var_14*var_416/(var_15*var_15*var_15); + A[688] = A[223]; + const double var_417 = var_3*var_5 + var_11; + const double var_418 = var_86 + 0.3333333333333333148296163*var_26 + 1.3333333333333332593184650*var_217; + const double var_419 = var_43 + var_154 + var_358 + var_48; + const double var_420 = var_166 + var_71; + const double var_421 = var_152 + var_44; + const double var_422 = 0.2222222222222222098864108*var_421 + 0.1333333333333333314829616*var_24 + 0.4000000000000000222044605*var_219 + 0.6666666666666666296592325*var_418 + 0.0666666666666666657414808*var_36 + 0.4444444444444444197728217*var_417*var_8 + 0.1111111111111111049432054*var_419 + 0.3333333333333333148296163*var_168 + 2.0000000000000000000000000*var_157 + 0.1777777777777777845624740*var_420; + A[374] = 12.1904761904761897994831088*var_14*var_422/(var_15*var_15*var_15); + const double var_423 = 2.6666666666666665186369300*var_31; + const double var_424 = 138.8000000000000113686837722*var_70 + 98.6000000000000085265128291*var_19 + 27.8666666666666671403618238*var_75 + var_423; + const double var_425 = 24.2000000000000028421709430*var_35 + 69.4666666666666685614472954*var_94 + 20.0000000000000000000000000*var_176 + 68.9333333333333371228945907*var_20; + const double var_426 = 37.0000000000000000000000000*var_121 + 387.4000000000000341060513165*var_124; + const double var_427 = 113.1333333333333257542108186*var_113 + 23.6666666666666642981908808*var_25 + var_17*var_425 + 31.0666666666666664298190881*var_96 + 11.3333333333333321490954404*var_28 + 0.3333333333333333148296163*var_4*var_426*var_5 + 242.2666666666666515084216371*var_85 + 0.5333333333333333259318465*var_110 + 125.4666666666666685614472954*var_129 + var_18*var_424 + 30.5333333333333314385527046*var_123; + A[67] = 0.0105820105820105814231624*var_14*var_427/(var_15*var_15*var_15); + A[212] = A[67]; + const double var_428 = 2.6666666666666665186369300*var_60; + const double var_429 = 27.8666666666666671403618238*var_20 + var_428 + 98.6000000000000085265128291*var_35 + 138.8000000000000113686837722*var_65; + const double var_430 = 24.2000000000000028421709430*var_19 + 68.9333333333333371228945907*var_75 + 20.0000000000000000000000000*var_140 + 69.4666666666666685614472954*var_198; + const double var_431 = 387.4000000000000341060513165*var_134 + 37.0000000000000000000000000*var_8; + const double var_432 = 0.5333333333333333259318465*var_193 + 23.6666666666666642981908808*var_26 + 125.4666666666666685614472954*var_118 + 11.3333333333333321490954404*var_27 + 113.1333333333333257542108186*var_145 + 31.0666666666666664298190881*var_195 + var_16*var_430 + var_18*var_429 + 242.2666666666666515084216371*var_117 + 30.5333333333333314385527046*var_238 + 0.3333333333333333148296163*var_1*var_3*var_431; + A[55] = 0.0000000000000000000000000; + const double var_433 = var_34 + var_22; + const double var_434 = 0.0571428571428571410728559*var_224 + var_189; + const double var_435 = 0.2539682539682539541558981*var_29; + const double var_436 = 0.2857142857142856984253854*var_86; + const double var_437 = var_219 + var_193; + const double var_438 = 1.6000000000000000888178420*var_210 + 5.3333333333333330372738601*var_403; + const double var_439 = var_436 + 0.0476190476190476164042309*var_438 + 0.1523809523809523946979994*var_27 + var_162 + var_401 + 0.2031746031746031744269487*var_25 + 0.0634920634920634885389745*var_77 + 0.0984126984126984100109681*var_17*var_19 + 0.1555555555555555580227178*var_50 + 0.2253968253968254009667049*var_195 + 0.3333333333333333148296163*var_67 + 0.1650793650793650757524489*var_4*var_5*var_58 + var_434 + 0.0222222222222222230703093*var_397 + 0.0888888888888888922812370*var_433 + 0.1904761904761904656169236*var_437 + var_435 + 0.0317460317460317442694873*var_181 + 0.1333333333333333314829616*var_229 + 0.0952380952380952328084618*var_381 + 0.1206349206349206365507243*var_45 + 0.1238095238095238276310184*var_168; + A[192] = 14.2222222222222214327302936*var_14*var_439/(var_15*var_15*var_15); + A[366] = A[192]; + A[884] = 0.0000000000000000000000000; + const double var_440 = var_120 + var_27; + const double var_441 = 4.0000000000000000000000000*var_77 + var_219 + var_346; + const double var_442 = var_345 + 0.0126984126984126984016843*var_440 + 0.0349206349206349214719936*var_16*var_35 + 0.0190476190476190493372499*var_44 + 0.0158730158730158721347436*var_48 + 0.0253968253968253968033686*var_441; + A[344] = 14.2222222222222214327302936*var_14*var_442/(var_15*var_15*var_15); + A[517] = 0.0000000000000000000000000; + A[671] = 0.0000000000000000000000000; + A[52] = 0.0000000000000000000000000; + A[287] = 0.0000000000000000000000000; + A[236] = 0.0000000000000000000000000; + const double var_443 = 83.0000000000000000000000000*var_124 + 137.0000000000000000000000000*var_121; + A[695] = 0.0000000000000000000000000; + const double var_444 = 0.5555555555555555802271783*var_33*var_4*var_5; + const double var_445 = 0.3936507936507936400438723*var_16*var_19 + 0.6603174603174603030097956*var_16*var_70; + const double var_446 = 0.4666666666666666740681535*var_1*var_3*var_82; + const double var_447 = 0.1682539682539682668327430*var_43; + const double var_448 = 0.0190476190476190493372499*var_22 + 0.6666666666666666296592325*var_446 + 0.1904761904761904656169236*var_114 + var_341 + 0.0317460317460317442694873*var_234 + 0.4126984126984126755033344*var_34 + var_397 + 0.2730158730158729896153602*var_24 + 0.5841269841269841611719471*var_77 + var_445 + 0.0063492063492063492008421*var_36 + 0.2444444444444444641817427*var_168 + 0.2000000000000000111022302*var_45 + var_447 + 0.0571428571428571410728559*var_186 + 0.5269841269841269992824095*var_26 + 0.7365079365079365558699465*var_30 + 0.4634920634920635107434350*var_1*var_3*var_81 + var_263 + 0.1333333333333333314829616*var_48 + 0.9904761904761906210481470*var_27 + 0.1396825396825396858879742*var_16*var_31 + 0.4317460317460317664739478*var_32 + 0.3301587301587301515048978*var_28 + 0.3015873015873015705601290*var_44 + 0.0444444444444444461406185*var_61; + A[134] = 10.6666666666666660745477202*var_14*var_448/(var_15*var_15*var_15); + A[424] = A[134]; + const double var_449 = var_152 + var_34; + const double var_450 = 0.0571428571428571410728559*var_449 + 0.0031746031746031746004211*var_382 + 0.0539682539682539708092435*var_43; + const double var_451 = 0.1428571428571428492126927*var_128 + 1.1428571428571427937015414*var_131 + 0.5714285714285713968507707*var_117 + var_205; + const double var_452 = 0.0444444444444444461406185*var_451 + 0.0507936507936507936067372*var_32; + const double var_453 = 0.5714285714285713968507707*var_27 + 1.5714285714285713968507707*var_26 + var_9; + const double var_454 = var_453 + var_193; + const double var_455 = var_184 + var_452 + 0.0476190476190476164042309*var_45 + var_280 + var_392 + 0.0825396825396825378762244*var_283 + 0.1206349206349206365507243*var_16*var_75 + var_450 + 0.0444444444444444461406185*var_454; + A[221] = 1.7777777777777776790912867*var_14*var_455/(var_15*var_15*var_15); + A[353] = 0.0000000000000000000000000; + const double var_456 = var_87 + var_86; + const double var_457 = 0.1650793650793650757524489*var_71; + const double var_458 = 0.2000000000000000111022302*var_142 + var_457; + const double var_459 = 0.5206349206349206726329726*var_17*var_65; + const double var_460 = 0.2402116402116402371635928*var_43; + const double var_461 = var_17*var_69 + var_21; + const double var_462 = var_460 + 0.2402116402116402371635928*var_103 + 0.0423280423280423256926497*var_61 + 0.7915343915343915348614701*var_24 + 0.4264550264550264757623665*var_16*var_35 + var_458 + var_459 + 0.5375661375661375807055720*var_25 + 1.2486772486772486079331657*var_4*var_5*var_58 + 1.7862433862433864106833425*var_28 + 0.3386243386243386055411975*var_120 + 1.3164021164021164622681681*var_29 + 0.0677248677248677294349122*var_461 + 0.3777777777777777679091287*var_63 + 0.4000000000000000222044605*var_45 + 0.1386243386243386221945428*var_193 + 0.1947089947089947203906490*var_119 + 1.1047619047619048338049197*var_1*var_3*var_82 + 0.1597883597883598127964433*var_50 + 0.0751322751322751336555683*var_17*var_20 + 0.9354497354497355310343210*var_30 + 1.8962962962962963686663898*var_77 + 0.8645502645502646243969025*var_18*var_75 + 0.1439153439153439129061240*var_456 + 0.1015873015873015872134744*var_44; + const double var_463 = 0.0871252204585537953773766*var_161; + A[895] = A[314]; + const double var_464 = var_28 + var_77; + const double var_465 = var_59 + 1.3333333333333332593184650*var_464 + 0.3333333333333333148296163*var_25; + const double var_466 = 0.0539682539682539708092435*var_18*var_35; + const double var_467 = var_186 + var_114; + const double var_468 = 0.0835978835978836015696558*var_43; + const double var_469 = var_153 + var_50; + const double var_470 = 0.0687830687830687792505557*var_245 + 0.3195767195767196255928866*var_34 + var_468 + 0.3047619047619047893959987*var_26 + 0.6391534391534392511857732*var_27 + 0.3767195767195767319712729*var_32 + 0.1132275132275132323300681*var_45 + 0.0444444444444444461406185*var_465 + 0.1523809523809523946979994*var_44 + 0.0084656084656084661793640*var_177 + 0.0296296296296296307604123*var_469 + 0.0804232804232804243671495*var_17*var_60 + 0.3343915343915344062786232*var_86 + var_466 + 0.0571428571428571410728559*var_22 + 0.0148148148148148153802062*var_174 + 0.2359788359788359823898674*var_247 + 0.0507936507936507936067372*var_467 + 0.3640211640211640231612478*var_30 + 0.0835978835978836015696558*var_72; + A[266] = 0.0000000000000000000000000; + A[754] = 0.0000000000000000000000000; + A[292] = 0.0000000000000000000000000; + A[885] = A[14]; + A[249] = 7.1111111111111107163651468*var_14*var_371/(var_15*var_15*var_15); + const double var_471 = 0.0095238095238095246686250*var_171; + const double var_472 = 0.0412698412698412689381122*var_195; + const double var_473 = 1.8888888888888888395456433*var_124*var_4*var_5; + const double var_474 = var_473 + var_205; + const double var_475 = var_282 + 0.0444444444444444461406185*var_181 + var_471 + 0.0063492063492063492008421*var_230 + 0.0349206349206349214719936*var_238 + 0.0730158730158730201464934*var_18*var_19 + 0.1206349206349206365507243*var_1*var_3*var_8 + var_472 + 0.1269841269841269770779490*var_231 + 0.0571428571428571410728559*var_474; + const double var_476 = 5.3333333333333330372738601*var_85 + var_92; + const double var_477 = 0.0190476190476190493372499*var_127 + 0.0952380952380952328084618*var_113 + var_278 + var_475 + 0.0380952380952380986744998*var_476; + A[162] = 14.2222222222222214327302936*var_14*var_477/(var_15*var_15*var_15); + const double var_478 = 4.1428571428571423496123316*var_81 + 54.2000000000000028421709430*var_82; + A[195] = 0.0000000000000000000000000; + A[82] = 0.0000000000000000000000000; + A[600] = 0.0000000000000000000000000; + A[263] = 0.0000000000000000000000000; + const double var_479 = var_171 + var_174; + A[523] = 0.0000000000000000000000000; + const double var_480 = var_120 + var_48; + const double var_481 = 0.0730158730158730201464934*var_16*var_19 + var_160; + const double var_482 = 0.2000000000000000111022302*var_174 + var_223; + const double var_483 = 0.1111111111111111049432054*var_367; + const double var_484 = var_444 + var_30; + const double var_485 = var_172 + var_26; + const double var_486 = 0.1724867724867724938508928*var_168 + 0.3809523809523809312338471*var_27 + 0.1382716049382715917115405*var_96 + var_483 + 0.0931216931216931331771747*var_485 + 0.1679012345679012363497407*var_22 + 0.1111111111111111049432054*var_405 + 0.0462081128747795430444789*var_17*var_19 + 0.0296296296296296307604123*var_24 + 0.0959435626102292798966786*var_17*var_94 + 0.0116402116402116416471468*var_210 + 0.1467372134038800735034158*var_130 + 0.0239858906525573199741697*var_44 + var_481 + 0.0042328042328042330896820*var_87 + 0.2299823633156966584678571*var_29 + 0.2878306878306878258122481*var_86 + 0.0532627865961199306599205*var_18*var_35 + 0.2088183421516754956215323*var_126 + 0.1421516754850088160022636*var_110 + 0.3442680776014109822469322*var_32 + 0.0493827160493827133080913*var_181 + 0.0201058201058201060917874*var_48 + 0.3174603174603174426948726*var_484 + 0.3333333333333333148296163*var_482; + A[187] = 16.0000000000000000000000000*var_14*var_486/(var_15*var_15*var_15); + A[681] = A[187]; + const double var_487 = 2.0000000000000000000000000*var_124*var_4*var_5; + const double var_488 = 0.4656084656084655826191465*var_85 + 0.1375661375661375585011115*var_195; + const double var_489 = var_36 + var_193; + const double var_490 = var_145 + var_181; + const double var_491 = 1.0031746031746031633247185*var_141 + 0.0888888888888888922812370*var_490 + 0.7492063492063492091688204*var_129 + var_405 + 0.2063492063492063377516672*var_489 + 0.9142857142857142571656937*var_120 + 0.7079365079365079749251777*var_16*var_20; + const double var_492 = var_76 + var_491; + const double var_493 = 0.0285714285714285705364279*var_276; + const double var_494 = 0.3343915343915344062786232*var_118 + var_488 + 0.3047619047619047893959987*var_9 + 0.1164021164021163956547866*var_96 + 0.1904761904761904656169236*var_113 + var_307 + 0.1375661375661375585011115*var_487 + 0.2063492063492063377516672*var_103 + 0.1354497354497354588698244*var_130 + 0.6095238095238095787919974*var_119 + 0.1047619047619047782937685*var_17*var_20 + 0.0761904761904761973489997*var_127 + var_493 + var_373 + 0.3333333333333333148296163*var_492 + var_256; + A[155] = 21.3333333333333321490954404*var_14*var_494/(var_15*var_15*var_15); + A[620] = A[155]; + A[812] = 0.0000000000000000000000000; + A[167] = 0.0000000000000000000000000; + const double var_495 = 0.1873015873015873022922051*var_16*var_19; + const double var_496 = 0.2095238095238095565875369*var_161; + const double var_497 = 193.0000000000000000000000000*var_81 + 121.0000000000000000000000000*var_134; + const double var_498 = 0.0031746031746031746004211*var_1*var_3*var_497 + 0.1428571428571428492126927*var_444 + var_67 + var_414 + var_496 + 0.1619047619047619124277304*var_174 + 0.1492063492063492036177053*var_4*var_5*var_58 + 0.1269841269841269770779490*var_48 + 0.4571428571428571285828468*var_32 + 0.4984126984126984183376408*var_126 + 0.3365079365079365336654860*var_110 + 0.0349206349206349214719936*var_24 + 0.0126984126984126984016843*var_210 + 0.5460317460317459792307204*var_96 + 0.9269841269841270214868700*var_27 + var_495 + 0.3142857142857142793701541*var_26 + 0.2888888888888889172612551*var_168 + 0.1015873015873015872134744*var_17*var_19 + 0.3777777777777777679091287*var_22 + 0.0825396825396825378762244*var_195 + 0.5269841269841269992824095*var_29 + 0.6476190476190476497109216*var_30 + 0.1746031746031745934821799*var_171 + 0.3492063492063491869643599*var_244 + 0.2349206349206349186964360*var_243; + const double var_499 = 0.2349206349206349186964360*var_177; + A[182] = A[66]; + const double var_500 = 0.1523809523809523946979994*var_177 + 0.0952380952380952328084618*var_174; + const double var_501 = 0.4317460317460317664739478*var_117 + 0.3301587301587301515048978*var_1*var_134*var_3; + const double var_502 = 0.1492063492063492036177053*var_161; + const double var_503 = var_9 + var_283; + const double var_504 = var_210 + var_487; + const double var_505 = 0.0920634920634920694837433*var_504 + var_501 + 0.2603174603174603363164863*var_195 + 0.2412698412698412731014486*var_412 + 0.3047619047619047893959987*var_129 + 0.1396825396825396858879742*var_120 + 0.2476190476190476552620368*var_205 + 0.3809523809523809312338471*var_130 + 0.1809523809523809756427681*var_171 + 0.2031746031746031744269487*var_118 + 0.0380952380952380986744998*var_110 + var_275 + 0.1333333333333333314829616*var_126 + var_500 + 0.1111111111111111049432054*var_193 + 0.0190476190476190493372499*var_95 + var_502 + 0.1015873015873015872134744*var_503 + var_316; + A[283] = 14.2222222222222214327302936*var_14*var_505/(var_15*var_15*var_15); + A[864] = A[283]; + const double var_506 = 0.0666666666666666657414808*var_142 + 0.2095238095238095565875369*var_140*var_16; + const double var_507 = 2.0000000000000000000000000*var_118 + var_210; + const double var_508 = 0.3809523809523809312338471*var_197; + const double var_509 = var_135 + var_126; + const double var_510 = 0.0031746031746031746004211*var_4*var_443*var_5 + 0.2793650793650793717759484*var_16*var_198 + 0.0349206349206349214719936*var_113 + var_508 + 0.2984126984126984072354105*var_85 + 0.1873015873015873022922051*var_174 + 0.7936507936507936067371816*var_117 + var_499 + 0.3333333333333333148296163*var_506 + 0.0571428571428571410728559*var_95 + 0.3142857142857142793701541*var_509 + 0.3396825396825396969902044*var_18*var_35 + 0.2539682539682539541558981*var_119 + 0.2000000000000000111022302*var_145 + 0.7492063492063492091688204*var_130 + 0.1047619047619047782937685*var_9 + 0.1492063492063492036177053*var_120 + 0.4698412698412698373928720*var_129 + var_104 + 0.0126984126984126984016843*var_186 + 0.1523809523809523946979994*var_507; + A[3] = 0.8888888888888888395456433*var_14*var_510/(var_15*var_15*var_15); + A[468] = A[3]; + const double var_511 = var_92 + var_205; + A[490] = 0.0000000000000000000000000; + A[580] = 0.0000000000000000000000000; + A[521] = 0.0000000000000000000000000; + A[876] = 0.0000000000000000000000000; + const double var_512 = var_433 + var_48; + A[669] = 0.0000000000000000000000000; + A[548] = 0.0000000000000000000000000; + const double var_513 = var_28 + var_126; + const double var_514 = var_187 + 4.0000000000000000000000000*var_32 + var_114; + const double var_515 = 0.0158730158730158721347436*var_50 + 0.0190476190476190493372499*var_45 + var_185 + 0.0126984126984126984016843*var_513 + 0.0349206349206349214719936*var_17*var_19 + 0.0253968253968253968033686*var_514; + const double var_516 = 1.2074074074074074847118254*var_161; + const double var_517 = var_125 + var_86; + const double var_518 = 0.3333333333333333148296163*var_20 + var_35; + const double var_519 = 1.0666666666666666518636930*var_50 + 0.8444444444444444419772822*var_22 + 0.7111111111111111382498962*var_114 + 0.2370370370370370460832987*var_85 + 0.2814814814814814991628111*var_346 + 0.3703703703703703498106847*var_48 + 1.7185185185185185563483401*var_27 + 0.1407407407407407495814056*var_96 + 1.0814814814814814880605809*var_517 + 1.3037037037037038089692942*var_117 + 1.3629629629629629317122408*var_30 + 1.5851851851851852526209541*var_1*var_134*var_3 + 0.9777777777777778567269706*var_186 + 0.6370370370370370682877592*var_26 + 1.0222222222222223653176343*var_271 + 0.1925925925925925930037863*var_16*var_35 + 0.0444444444444444461406185*var_276 + var_516 + 0.2666666666666666629659233*var_391 + 0.3777777777777777679091287*var_18*var_518 + 1.6000000000000000888178420*var_28 + 0.5777777777777778345225101*var_59 + 0.8370370370370370238788382*var_195; + A[219] = 0.7619047619047618624676943*var_14*var_519/(var_15*var_15*var_15); + A[742] = A[219]; + A[290] = 0.0000000000000000000000000; + const double var_520 = var_4*var_5*var_57 + var_175*var_18; + const double var_521 = 0.1333333333333333314829616*var_91 + 0.3333333333333333148296163*var_169; + const double var_522 = 0.0571428571428571410728559*var_45; + const double var_523 = var_92 + var_93; + const double var_524 = 0.0476190476190476164042309*var_523 + 0.0761904761904761973489997*var_520 + 0.0222222222222222230703093*var_50 + 0.1396825396825396858879742*var_25 + var_522 + 0.1650793650793650757524489*var_17*var_65 + 0.0825396825396825378762244*var_152 + var_323 + 0.0888888888888888922812370*var_77 + var_218 + 0.2158730158730158832369739*var_28 + 0.3333333333333333148296163*var_521 + var_367 + 0.0507936507936507936067372*var_18*var_94 + var_255; + A[161] = 7.1111111111111107163651468*var_14*var_524/(var_15*var_15*var_15); + A[800] = A[161]; + A[225] = 0.0000000000000000000000000; + const double var_525 = var_228 + var_27; + const double var_526 = 0.0433862433862433893860810*var_43; + const double var_527 = 0.0550264550264550275637809*var_77 + 0.0010582010582010582724205*var_156 + var_526; + const double var_528 = var_22 + var_59 + var_114; + const double var_529 = var_210 + var_24; + const double var_530 = var_331 + 2.9047619047619046561692357*var_26 + 5.0476190476190474498707772*var_33*var_4*var_5 + 7.4285714285714279370154145*var_30 + 9.3333333333333321490954404*var_27 + 1.0476190476190476719153821*var_16*var_198 + var_529 + 1.6190476190476190687661529*var_528 + 3.1428571428571427937015414*var_28 + 2.4761904761904762750646114*var_45 + 1.5238095238095237249353886*var_271; + const double var_531 = 0.2962962962962962798485478*var_32 + 0.0105820105820105814231624*var_152 + 0.1809523809523809756427681*var_18*var_20 + 0.0328042328042328079629186*var_171 + 0.0666666666666666657414808*var_50 + 0.0687830687830687792505557*var_186 + var_436 + var_323 + var_527 + 0.3333333333333333148296163*var_445 + 0.0444444444444444461406185*var_530; + A[224] = 32.0000000000000000000000000*var_14*var_531/(var_15*var_15*var_15); + A[427] = A[224]; + A[789] = 0.0000000000000000000000000; + A[407] = 0.0000000000000000000000000; + const double var_532 = var_26 + var_25; + const double var_533 = 0.3301587301587301515048978*var_124*var_4*var_5 + 0.4317460317460317664739478*var_85; + const double var_534 = var_92 + var_252; + const double var_535 = var_326 + var_205; + const double var_536 = 0.1873015873015873022922051*var_195; + const double var_537 = var_143 + 0.1015873015873015872134744*var_535 + 0.0380952380952380986744998*var_193 + 0.3809523809523809312338471*var_119 + 0.2603174603174603363164863*var_96 + 0.3047619047619047893959987*var_118 + var_536 + 0.2476190476190476552620368*var_9 + 0.2412698412698412731014486*var_244 + 0.2031746031746031744269487*var_129 + 0.1333333333333333314829616*var_120 + var_533 + var_319 + 0.0190476190476190493372499*var_228 + 0.1396825396825396858879742*var_126 + 0.1111111111111111049432054*var_110 + var_502 + 0.1809523809523809756427681*var_103 + 0.0920634920634920694837433*var_534; + A[194] = 14.2222222222222214327302936*var_14*var_537/(var_15*var_15*var_15); + const double var_538 = var_244 + var_412; + const double var_539 = 0.2063492063492063377516672*var_196 + 0.1333333333333333314829616*var_213 + 0.1968253968253968200219362*var_206 + 0.1111111111111111049432054*var_18*var_192 + 0.1365079365079364948076801*var_161 + 0.0825396825396825378762244*var_202 + 0.2793650793650793717759484*var_203 + 0.0444444444444444461406185*var_211 + 0.1142857142857142821457117*var_201 + 0.1015873015873015872134744*var_207 + 0.2476190476190476552620368*var_204 + 0.0634920634920634885389745*var_212 + 0.0698412698412698429439871*var_194 + 0.3301587301587301515048978*var_538; + A[132] = 10.6666666666666660745477202*var_14*var_539/(var_15*var_15*var_15); + A[597] = A[132]; + A[81] = 0.0000000000000000000000000; + const double var_540 = var_18*var_65; + const double var_541 = var_117 + var_540; + const double var_542 = 0.0190476190476190493372499*var_525 + 0.0740740740740740699621369*var_118 + 0.3333333333333333148296163*var_495 + 0.0455026455026455028951560*var_195 + 0.0264550264550264535579061*var_145 + 0.2042328042328042381203801*var_1*var_134*var_3 + 0.2000000000000000111022302*var_169 + 0.0666666666666666657414808*var_26 + 0.0476190476190476164042309*var_9 + 0.0423280423280423256926497*var_16*var_75 + 0.0497354497354497368521997*var_238 + 0.1544973544973544943292865*var_18*var_35 + 0.0783068783068783108580746*var_16*var_70 + 0.0105820105820105814231624*var_239 + 0.0042328042328042330896820*var_48 + 0.2306878306878306916782861*var_541; + const double var_543 = var_195 + var_32; + const double var_544 = var_45 + 4.0000000000000000000000000*var_543; + const double var_545 = 0.1428571428571428492126927*var_339 + var_59 + 1.1428571428571427937015414*var_340; + const double var_546 = 0.1333333333333333314829616*var_545 + 0.3333333333333333148296163*var_397; + const double var_547 = var_546 + 0.0380952380952380986744998*var_152 + 0.1523809523809523946979994*var_77 + 0.0095238095238095246686250*var_544 + var_262 + var_291 + var_370; + A[641] = 0.0000000000000000000000000; + A[118] = 0.0000000000000000000000000; + A[311] = 5.3333333333333330372738601*var_14*var_462/(var_15*var_15*var_15); + A[592] = A[127]; + A[8] = 0.8888888888888888395456433*var_14*var_498/(var_15*var_15*var_15); + A[473] = A[8]; + const double var_548 = 5.3333333333333330372738601*var_117 + var_210; + const double var_549 = 0.0190476190476190493372499*var_229 + var_322 + 0.0380952380952380986744998*var_548 + 0.0952380952380952328084618*var_145 + var_137; + A[102] = 14.2222222222222214327302936*var_14*var_549/(var_15*var_15*var_15); + const double var_550 = 3.2857142857142855874030829*var_17*var_35; + const double var_551 = var_106 + var_550; + const double var_552 = var_315 + 0.5047619047619048560093802*var_25 + 0.1523809523809523946979994*var_110 + 0.5523809523809524169024598*var_28 + 0.8190476190476191353795343*var_17*var_94 + 0.1047619047619047782937685*var_96 + 0.2000000000000000111022302*var_551; + A[73] = 0.5925925925925925596970956*var_14*var_552/(var_15*var_15*var_15); + A[538] = A[73]; + const double var_553 = var_92 + var_50; + const double var_554 = var_177 + var_205; + const double var_555 = var_63 + var_93; + const double var_556 = var_120 + var_487; + const double var_557 = 130.4285714285714163906959584*var_20 + 50.2857142857142846992246632*var_31 + 213.1428571428571387968986528*var_140 + 49.0000000000000000000000000*var_35; + const double var_558 = 0.3841269841269841500697169*var_161; + const double var_559 = 2.5185185185185186007572611*var_118 + 0.2285714285714285642914234*var_117 + 2.0000000000000000000000000*var_536 + 3.2253968253968254842334318*var_412 + 1.6465608465608467803065196*var_129 + 0.1883597883597883659856365*var_45 + 0.2497354497354497548933239*var_145 + 0.5724867724867724882997777*var_553 + 0.6433862433862433949371962*var_28 + 0.9777777777777778567269706*var_25 + 0.0211640211640211628463248*var_152 + 1.5291005291005290711581210*var_18*var_19 + 0.0095238095238095246686250*var_48 + var_558 + 2.2687830687830690123973909*var_1*var_3*var_8 + 0.3343915343915344062786232*var_554 + 0.9566137566137566938806458*var_556 + 1.3121693121693120964721402*var_113 + 0.4052910052910053129160417*var_555 + 0.0074074074074074076901031*var_16*var_557; + A[217] = 4.0000000000000000000000000*var_14*var_559/(var_15*var_15*var_15); + const double var_560 = 0.3174603174603174426948726*var_16*var_70 + 0.4158730158730158943392041*var_16*var_20; + const double var_561 = var_103 + var_349; + const double var_562 = var_560 + 0.1111111111111111049432054*var_120 + 1.4539682539682539097469771*var_16*var_35 + 0.3047619047619047893959987*var_48 + 0.0952380952380952328084618*var_27 + 0.6698412698412697929839510*var_561 + 3.0920634920634921805060458*var_176*var_18 + 0.9746031746031745823799497*var_44 + 2.8857142857142856762209249*var_1*var_3*var_82 + 5.0730158730158727564685250*var_77 + 2.3936507936507935845327211*var_30 + 1.7587301587301586991429758*var_16*var_31 + 2.2158730158730159942592763*var_18*var_75 + 2.1873015873015870802476002*var_24 + 0.2063492063492063377516672*var_86; + A[41] = 0.8888888888888888395456433*var_14*var_562/(var_15*var_15*var_15); + A[331] = A[41]; + A[281] = 7.1111111111111107163651468*var_14*var_257/(var_15*var_15*var_15); + A[804] = A[281]; + A[238] = 0.0000000000000000000000000; + A[760] = 0.0000000000000000000000000; + A[75] = 0.0000000000000000000000000; + const double var_563 = var_1*var_3*var_80 + var_139*var_18; + const double var_564 = var_563 + var_520; + A[354] = 0.0000000000000000000000000; + const double var_565 = 0.0190476190476190493372499*var_152; + const double var_566 = var_521 + 0.0095238095238095246686250*var_98 + 0.0380952380952380986744998*var_34 + var_359 + 0.1523809523809523946979994*var_32 + var_291 + var_565; + A[159] = 2.3703703703703702387883823*var_14*var_566/(var_15*var_15*var_15); + A[624] = A[159]; + A[449] = 0.0000000000000000000000000; + const double var_567 = 5.0000000000000000000000000*var_75 + 11.3333333333333321490954404*var_19 + 16.6666666666666642981908808*var_60; + const double var_568 = var_313 + var_25; + const double var_569 = var_17*var_567 + 4.0000000000000000000000000*var_177 + 0.6666666666666666296592325*var_28 + 5.6666666666666660745477202*var_45 + 12.6666666666666660745477202*var_333 + 5.3333333333333330372738601*var_50 + 12.3333333333333321490954404*var_22 + 0.3333333333333333148296163*var_568; + A[74] = 0.0846560846560846513852994*var_14*var_569/(var_15*var_15*var_15); + A[887] = A[74]; + A[464] = 0.0000000000000000000000000; + A[576] = 0.0000000000000000000000000; + A[787] = 0.0000000000000000000000000; + const double var_570 = 3.9523809523809521060400129*var_1*var_3*var_8; + const double var_571 = 13.0000000000000000000000000*var_33*var_4*var_5; + const double var_572 = 1.8698412698412698595973325*var_43; + const double var_573 = 1.4285714285714286031492293*var_174; + const double var_574 = 0.3809523809523809312338471*var_16*var_35; + const double var_575 = var_446 + 0.9523809523809523280846179*var_141 + 0.9777777777777778567269706*var_18*var_20 + 2.4825396825396826017140484*var_32 + 4.0634920634920632664943696*var_129 + 3.1174603174603174871037936*var_27 + 0.3333333333333333148296163*var_570 + 3.3968253968253967478574395*var_118 + 0.2190476190476190743172680*var_571 + 1.6126984126984127421167159*var_117 + 4.4349206349206351518432712*var_26 + 1.1523809523809525057203018*var_16*var_19 + 0.3650793650793650590991035*var_113 + var_573 + 1.5873015873015872134743631*var_17*var_94 + 1.6190476190476190687661529*var_177 + 6.5396825396825395415589810*var_130 + 5.1523809523809527277649067*var_44 + 2.8412698412698409455856563*var_126 + 1.4031746031746030745068765*var_18*var_35 + 1.4126984126984125644810319*var_110 + 3.2825396825396824240783644*var_48 + 3.3079365079365077306761123*var_16*var_31 + 0.4571428571428571285828468*var_45 + 3.6984126984126981518841148*var_121*var_4*var_5 + 0.1746031746031745934821799*var_92 + 2.0793650793650790831179620*var_145 + var_572 + 0.0666666666666666657414808*var_574; + A[10] = 0.2222222222222222098864108*var_14*var_575/(var_15*var_15*var_15); + A[475] = A[10]; + A[822] = 0.0000000000000000000000000; + const double var_576 = var_100*var_16 + var_144 + var_540; + const double var_577 = var_75 + var_20; + const double var_578 = var_32 + var_77; + const double var_579 = 0.2190476190476190743172680*var_18*var_577 + 1.4285714285714286031492293*var_449 + 0.5904761904761904878213841*var_213 + 0.5523809523809524169024598*var_206 + 0.7238095238095239025710725*var_201 + 0.0761904761904761973489997*var_207 + 1.2095238095238096676098394*var_43 + 0.2666666666666666629659233*var_211 + 1.1428571428571427937015414*var_208 + 0.7619047619047618624676943*var_203 + 0.2095238095238095565875369*var_202 + 0.1333333333333333314829616*var_212 + 0.4571428571428571285828468*var_194 + 0.7523809523809524835158413*var_46 + 1.2190476190476191575839948*var_578; + const double var_580 = 0.0412698412698412689381122*var_161; + const double var_581 = 0.0031746031746031746004211*var_193; + const double var_582 = 0.1904761904761904656169236*var_118 + var_372 + 0.1650793650793650757524489*var_554 + var_104 + 0.2793650793650793717759484*var_130 + 0.0761904761904761973489997*var_9 + 2.0000000000000000000000000*var_318 + 0.0984126984126984100109681*var_479 + 0.0571428571428571410728559*var_328 + 0.0222222222222222230703093*var_320 + 0.0476190476190476164042309*var_548 + 0.0158730158730158721347436*var_374 + 0.0444444444444444461406185*var_195 + var_580 + 0.2158730158730158832369739*var_129 + 0.0253968253968253968033686*var_229 + 0.1015873015873015872134744*var_412 + 0.0507936507936507936067372*var_375 + var_581; + A[403] = 85.3333333333333285963817616*var_14*var_582/(var_15*var_15*var_15); + A[868] = A[403]; + A[483] = 0.0000000000000000000000000; + const double var_583 = 0.3333333333333333148296163*var_471; + const double var_584 = 0.0518518518518518573001685*var_43; + const double var_585 = var_584 + 0.0624338624338624387233310*var_44 + 0.2878306878306878258122481*var_32 + 0.3333333333333333148296163*var_158 + 0.0444444444444444461406185*var_271 + 0.0772486772486772471646432*var_45 + 0.1671957671957672031393116*var_33*var_4*var_5 + 0.1206349206349206365507243*var_22 + 0.0253968253968253968033686*var_393 + var_583 + 0.1777777777777777845624740*var_29 + 0.1862433862433862663543493*var_90 + var_148 + 0.1153439153439153458391431*var_18*var_20 + 0.0021164021164021165448410*var_1*var_191*var_3 + 0.0634920634920634885389745*var_186 + 0.0105820105820105814231624*var_89; + A[164] = 42.6666666666666642981908808*var_14*var_585/(var_15*var_15*var_15); + A[629] = A[164]; + A[27] = 0.0000000000000000000000000; + A[749] = A[284]; + A[168] = 0.0000000000000000000000000; + const double var_586 = 4.1428571428571423496123316*var_58 + 54.2000000000000028421709430*var_33; + const double var_587 = var_245 + var_171 + var_349; + A[99] = 7.1111111111111107163651468*var_14*var_227/(var_15*var_15*var_15); + A[273] = A[99]; + const double var_588 = var_43 + var_63 + var_260 + var_50; + const double var_589 = var_66 + var_403; + const double var_590 = var_45 + var_34; + const double var_591 = 0.2222222222222222098864108*var_590 + 0.4000000000000000222044605*var_114 + 0.6666666666666666296592325*var_465 + 0.1111111111111111049432054*var_588 + 0.4444444444444444197728217*var_121*var_417 + 0.3333333333333333148296163*var_93 + 0.1333333333333333314829616*var_22 + 0.0666666666666666657414808*var_186 + 2.0000000000000000000000000*var_189 + 0.1777777777777777845624740*var_589; + A[373] = 12.1904761904761897994831088*var_14*var_591/(var_15*var_15*var_15); + A[239] = 0.0000000000000000000000000; + A[485] = 0.0000000000000000000000000; + const double var_592 = var_92 + var_22; + A[40] = 0.0105820105820105814231624*var_14*var_432/(var_15*var_15*var_15); + A[301] = A[40]; + A[329] = 0.0000000000000000000000000; + A[524] = 0.0000000000000000000000000; + const double var_593 = 1.5619047619047621289212202*var_17*var_176; + const double var_594 = 0.0141093474426807752308832*var_95; + const double var_595 = 0.0740740740740740699621369*var_379 + var_463 + 0.2462081128747795610856031*var_1*var_134*var_3 + 0.0225749559082892431449707*var_113 + 0.1111111111111111049432054*var_593 + 0.0137566137566137568909452*var_168 + 0.1336860670194003619659640*var_195 + 0.0465608465608465665885873*var_193 + 0.0197530864197530860171259*var_248 + 0.1259259259259259411400933*var_174 + 0.3964726631393298283967397*var_130 + 0.0444444444444444461406185*var_9 + var_318 + 0.3033509700176366674639894*var_117 + 0.1403880070546737190984032*var_96 + 0.1590828924162257518304386*var_18*var_35 + 0.0532627865961199306599205*var_110 + 0.1791887125220458787389077*var_126 + 0.0250440917107583801981541*var_17*var_19 + 0.0507936507936507936067372*var_507 + 0.2222222222222222098864108*var_533 + var_402 + 0.0486772486772486800976623*var_229 + 0.2398589065255731789250149*var_129 + var_594; + const double var_596 = 11.3333333333333321490954404*var_35 + 16.6666666666666642981908808*var_31 + 5.0000000000000000000000000*var_20; + const double var_597 = var_168 + var_349 + var_152 + var_86 + 2.0000000000000000000000000*var_18*var_94; + const double var_598 = var_597 + var_26; + const double var_599 = var_16*var_596 + 4.0000000000000000000000000*var_141 + 0.6666666666666666296592325*var_27 + 12.6666666666666660745477202*var_235 + 5.3333333333333330372738601*var_48 + 5.6666666666666660745477202*var_44 + 12.3333333333333321490954404*var_24 + 0.3333333333333333148296163*var_598; + A[520] = 0.0000000000000000000000000; + A[642] = 0.0000000000000000000000000; + A[511] = 0.0000000000000000000000000; + A[35] = 2.6666666666666665186369300*var_14*var_542/(var_15*var_15*var_15); + A[500] = A[35]; + const double var_600 = var_332 + 2.0000000000000000000000000*var_130 + var_126; + const double var_601 = 0.4000000000000000222044605*var_177 + 0.0716049382716049398478475*var_600 + 0.1086419753086419748289160*var_45 + 0.1802469135802469146767635*var_50 + 0.0641975308641975356271914*var_333 + 0.1358024691358024615972511*var_22 + 0.0370370370370370349810685*var_17*var_400; + A[70] = 0.2857142857142856984253854*var_14*var_601/(var_15*var_15*var_15); + A[767] = A[70]; + A[197] = 0.0000000000000000000000000; + A[682] = A[217]; + A[753] = 0.0000000000000000000000000; + A[790] = 0.0000000000000000000000000; + A[189] = 2.3703703703703702387883823*var_14*var_579/(var_15*var_15*var_15); + A[654] = A[189]; + A[158] = 21.3333333333333321490954404*var_14*var_470/(var_15*var_15*var_15); + A[136] = 0.0000000000000000000000000; + A[849] = 0.0000000000000000000000000; + const double var_602 = var_553 + var_298 + var_103; + const double var_603 = var_18*var_70; + const double var_604 = var_112 + var_603 + var_138*var_17; + const double var_605 = 1.1111111111111111604543567*var_129; + const double var_606 = var_18*var_198 + var_25; + const double var_607 = var_605 + 0.4174603174603174760015634*var_602 + 0.3253968253968254065178201*var_555 + 0.5587301587301587435518968*var_28 + 0.8349206349206349520031267*var_45 + 0.1841269841269841389674866*var_554 + 0.9269841269841270214868700*var_604 + 0.7428571428571428825193834*var_606; + A[2] = 0.1111111111111111049432054*var_14*var_607/(var_15*var_15*var_15); + A[525] = A[2]; + A[253] = 14.2222222222222214327302936*var_14*var_515/(var_15*var_15*var_15); + const double var_608 = 0.0539682539682539708092435*var_18*var_19; + const double var_609 = var_468 + 0.1132275132275132323300681*var_44 + 0.0444444444444444461406185*var_418 + 0.6391534391534392511857732*var_28 + 0.0687830687830687792505557*var_553 + 0.0148148148148148153802062*var_142 + 0.1523809523809523946979994*var_45 + 0.3195767195767196255928866*var_152 + 0.3047619047619047893959987*var_25 + 0.0296296296296296307604123*var_512 + 0.3767195767195767319712729*var_77 + 0.0835978835978836015696558*var_106 + 0.0507936507936507936067372*var_220 + 0.2359788359788359823898674*var_555 + 0.0804232804232804243671495*var_16*var_31 + 0.3343915343915344062786232*var_59 + var_608 + 0.0084656084656084661793640*var_141 + 0.3640211640211640231612478*var_29 + 0.0571428571428571410728559*var_24; + A[101] = 21.3333333333333321490954404*var_14*var_609/(var_15*var_15*var_15); + A[566] = A[101]; + const double var_610 = 11.0000000000000000000000000*var_1*var_3*var_8; + const double var_611 = var_92 + 2.0000000000000000000000000*var_129; + const double var_612 = 1.5619047619047621289212202*var_140*var_16; + const double var_613 = 0.0931216931216931331771747*var_130; + const double var_614 = var_463 + 0.1791887125220458787389077*var_120 + 0.1259259259259259411400933*var_142 + 0.0740740740740740699621369*var_493 + 0.1111111111111111049432054*var_612 + 0.1590828924162257518304386*var_18*var_19 + 0.3033509700176366674639894*var_85 + 0.0465608465608465665885873*var_110 + 0.1336860670194003619659640*var_96 + 0.2398589065255731789250149*var_118 + 0.0507936507936507936067372*var_611 + 0.0444444444444444461406185*var_205 + 0.0197530864197530860171259*var_610 + 0.0250440917107583801981541*var_16*var_35 + var_308 + 0.0225749559082892431449707*var_145 + 0.0486772486772486800976623*var_127 + 0.0532627865961199306599205*var_193 + 0.3964726631393298283967397*var_119 + 0.0137566137566137568909452*var_93 + 0.1403880070546737190984032*var_195 + 0.2222222222222222098864108*var_501 + 0.2462081128747795610856031*var_124*var_4*var_5 + var_613 + var_274; + A[157] = 16.0000000000000000000000000*var_14*var_614/(var_15*var_15*var_15); + A[680] = A[157]; + const double var_615 = var_63 + 1.3333333333333332593184650*var_66; + const double var_616 = 0.1142857142857142821457117*var_615; + const double var_617 = 0.3269841269841269881801793*var_161; + const double var_618 = 0.1269841269841269770779490*var_410 + 0.1523809523809523946979994*var_182 + var_612 + 0.8349206349206349520031267*var_18*var_19 + 0.0507936507936507936067372*var_24 + 0.4793650793650793828781786*var_16*var_35 + 0.1206349206349206365507243*var_326 + 0.2253968253968254009667049*var_193 + 2.5269841269841268882601071*var_119 + 0.1746031746031745934821799*var_93 + 0.5523809523809524169024598*var_195 + 1.1682539682539683223438942*var_1*var_3*var_8 + 1.1619047619047619956944573*var_124*var_4*var_5 + 1.3587301587301587879608178*var_120 + 0.2793650793650793717759484*var_129 + 0.0825396825396825378762244*var_110 + var_350 + 1.2825396825396826461229693*var_85 + 0.4095238095238095676897672*var_96 + 1.1174603174603174871037936*var_118 + 0.0317460317460317442694873*var_25 + var_616 + var_617 + 0.1587301587301587213474363*var_511; + A[881] = 0.0000000000000000000000000; + A[288] = 0.0000000000000000000000000; + const double var_619 = 0.0476190476190476164042309*var_72; + const double var_620 = var_154 + var_193; + const double var_621 = var_219 + var_145; + const double var_622 = var_619 + 0.1238095238095238276310184*var_210 + var_102 + 0.0444444444444444461406185*var_545 + 0.0253968253968253968033686*var_117 + 0.1142857142857142821457117*var_228 + 0.0126984126984126984016843*var_152 + var_583 + 0.0666666666666666657414808*var_168 + 0.1047619047619047782937685*var_620 + 0.0222222222222222230703093*var_544 + 0.0285714285714285705364279*var_259 + var_261 + 0.0063492063492063492008421*var_571 + 0.0380952380952380986744998*var_621; + A[413] = 0.0000000000000000000000000; + A[892] = A[224]; + A[259] = 0.0000000000000000000000000; + A[261] = 0.0000000000000000000000000; + A[477] = A[12]; + const double var_623 = 0.0550264550264550275637809*var_32 + var_526 + 0.0010582010582010582724205*var_224; + const double var_624 = 37.0000000000000000000000000*var_33 + 89.0000000000000000000000000*var_121; + const double var_625 = var_113 + var_252; + const double var_626 = 0.0148148148148148153802062*var_95 + 0.0666666666666666657414808*var_210 + 0.2222222222222222098864108*var_500 + 0.6666666666666666296592325*var_325 + var_623 + 0.1100529100529100551275619*var_117 + 0.0634920634920634885389745*var_145 + 0.1312169312169312318516745*var_119 + 0.0687830687830687792505557*var_193 + 0.0243386243386243400488311*var_45 + 0.0349206349206349214719936*var_168 + 0.2116402116402116284632484*var_129 + 0.0677248677248677294349122*var_229 + 0.0232804232804232832942937*var_625 + 0.0253968253968253968033686*var_195 + 0.0402116402116402121835748*var_126 + 0.0899470899470899420968806*var_18*var_35 + 0.2285714285714285642914234*var_130 + var_280 + 0.0021164021164021165448410*var_4*var_5*var_624 + 0.4000000000000000222044605*var_256; + A[312] = 32.0000000000000000000000000*var_14*var_626/(var_15*var_15*var_15); + A[777] = A[312]; + A[613] = 0.0000000000000000000000000; + A[492] = 0.0000000000000000000000000; + A[296] = 0.0000000000000000000000000; + A[43] = 0.0846560846560846513852994*var_14*var_599/(var_15*var_15*var_15); + A[315] = 0.0000000000000000000000000; + const double var_627 = 0.4666666666666666740681535*var_33*var_4*var_5; + const double var_628 = 3.9523809523809521060400129*var_121*var_4*var_5; + const double var_629 = 1.4285714285714286031492293*var_142; + const double var_630 = var_627 + 0.4571428571428571285828468*var_44 + 0.9523809523809523280846179*var_177 + 3.6984126984126981518841148*var_1*var_3*var_8 + var_629 + 1.6190476190476190687661529*var_141 + 3.1174603174603174871037936*var_28 + 1.1523809523809525057203018*var_17*var_35 + 6.5396825396825395415589810*var_119 + 1.4126984126984125644810319*var_193 + 5.1523809523809527277649067*var_45 + 3.2825396825396824240783644*var_50 + 1.5873015873015872134743631*var_16*var_198 + 2.0793650793650790831179620*var_113 + 0.9777777777777778567269706*var_18*var_75 + 3.3968253968253967478574395*var_129 + 2.8412698412698409455856563*var_120 + 0.3333333333333333148296163*var_628 + 0.1746031746031745934821799*var_210 + 4.0634920634920632664943696*var_118 + 1.4031746031746030745068765*var_18*var_19 + 1.6126984126984127421167159*var_85 + 0.3650793650793650590991035*var_145 + 3.3079365079365077306761123*var_17*var_60 + 4.4349206349206351518432712*var_25 + var_572 + 0.2190476190476190743172680*var_108 + 2.4825396825396826017140484*var_77 + 0.0666666666666666657414808*var_334; + A[7] = 0.2222222222222222098864108*var_14*var_630/(var_15*var_15*var_15); + const double var_631 = 0.2222222222222222098864108*var_66 + 0.1111111111111111049432054*var_550; + const double var_632 = 1.0158730158730158166235924*var_17*var_94; + const double var_633 = 20.2000000000000028421709430*var_124 + 1.4444444444444444197728217*var_121; + const double var_634 = var_123 + var_93; + const double var_635 = var_605 + 0.1111111111111111049432054*var_25 + 0.9047619047619047671915382*var_113 + 0.1428571428571428492126927*var_4*var_5*var_633 + 3.0920634920634921805060458*var_18*var_70 + 0.9238095238095238581621516*var_96 + 3.7904761904761907764793705*var_85 + 0.2539682539682539541558981*var_110 + 0.0952380952380952328084618*var_130 + var_631 + 0.7619047619047618624676943*var_92 + var_632 + 2.2158730158730159942592763*var_18*var_19 + 0.6698412698412697929839510*var_634; + A[65] = 0.8888888888888888395456433*var_14*var_635/(var_15*var_15*var_15); + A[610] = 0.0000000000000000000000000; + A[459] = 0.0000000000000000000000000; + A[140] = 0.0000000000000000000000000; + A[582] = 0.0000000000000000000000000; + const double var_636 = 4.0000000000000000000000000*var_27 + var_48; + const double var_637 = var_32 + var_152; + const double var_638 = var_394 + 0.4698412698412698373928720*var_637 + 0.0444444444444444461406185*var_186 + 0.5238095238095238359576911*var_172 + 0.2285714285714285642914234*var_347 + var_78 + 0.2349206349206349186964360*var_25 + 2.0000000000000000000000000*var_414 + 0.5841269841269841611719471*var_28 + 0.2253968253968254009667049*var_18*var_75 + 0.1206349206349206365507243*var_50 + 0.3650793650793650590991035*var_45 + var_616 + 0.2666666666666666629659233*var_86 + 0.4317460317460317664739478*var_29 + 0.1238095238095238276310184*var_636 + 0.3682539682539682779349732*var_44 + 0.0825396825396825378762244*var_187 + 0.3873015873015873133944353*var_33*var_4*var_5 + 0.1904761904761904656169236*var_24 + 0.1047619047619047782937685*var_16*var_192 + var_619 + var_169; + A[17] = 0.0000000000000000000000000; + A[700] = 0.0000000000000000000000000; + const double var_639 = var_487 + var_145; + A[176] = 0.0000000000000000000000000; + A[378] = 0.0000000000000000000000000; + A[738] = A[99]; + const double var_640 = 0.0126984126984126984016843*var_228; + const double var_641 = var_459 + var_640; + const double var_642 = 0.3936507936507936400438723*var_17*var_35 + 0.6603174603174603030097956*var_17*var_65; + const double var_643 = 0.0317460317460317442694873*var_480 + 0.1333333333333333314829616*var_50 + 0.1904761904761904656169236*var_219 + 0.4317460317460317664739478*var_77 + var_642 + 0.2444444444444444641817427*var_93 + 0.1396825396825396858879742*var_17*var_60 + var_180 + 0.2730158730158729896153602*var_22 + 0.2000000000000000111022302*var_44 + var_447 + 0.0571428571428571410728559*var_36 + 0.3015873015873015705601290*var_45 + 0.0444444444444444461406185*var_87 + 0.9904761904761906210481470*var_28 + 0.5269841269841269992824095*var_25 + 0.4126984126984126755033344*var_152 + 0.5841269841269841611719471*var_32 + 0.3301587301587301515048978*var_27 + var_169 + 0.0190476190476190493372499*var_24 + var_411 + 0.4634920634920635107434350*var_4*var_5*var_58 + 0.7365079365079365558699465*var_29 + 0.0063492063492063492008421*var_186 + 0.6666666666666666296592325*var_627; + A[133] = 10.6666666666666660745477202*var_14*var_643/(var_15*var_15*var_15); + A[859] = A[133]; + A[839] = A[374]; + const double var_644 = 0.0243386243386243400488311*var_161; + const double var_645 = 0.1428571428571428492126927*var_154 + 1.7523809523809525945381438*var_117; + const double var_646 = var_645 + var_160; + const double var_647 = 0.1111111111111111049432054*var_646 + 0.0063492063492063492008421*var_34 + 0.0169312169312169323587280*var_120 + 0.0550264550264550275637809*var_145 + 0.0328042328042328079629186*var_193 + 0.0465608465608465665885873*var_119 + 0.0571428571428571410728559*var_195 + 0.0296296296296296307604123*var_9 + 0.0846560846560846513852994*var_118 + 0.0349206349206349214719936*var_96 + 0.0042328042328042330896820*var_85 + 0.0423280423280423256926497*var_228 + 0.0105820105820105814231624*var_128 + var_644 + 0.0444444444444444461406185*var_628 + 0.0306878306878306909843968*var_18*var_20 + 0.1153439153439153458391431*var_18*var_35 + 0.1862433862433862663543493*var_131 + var_372 + 0.0518518518518518573001685*var_16*var_75; + A[343] = 42.6666666666666642981908808*var_14*var_647/(var_15*var_15*var_15); + A[808] = A[343]; + const double var_648 = 0.5555555555555555802271783*var_1*var_3*var_82; + const double var_649 = var_648 + var_29; + const double var_650 = 0.0931216931216931331771747*var_216 + var_305 + 0.0296296296296296307604123*var_22 + 0.0959435626102292798966786*var_16*var_198 + 0.0462081128747795430444789*var_16*var_35 + 0.1679012345679012363497407*var_24 + 0.1111111111111111049432054*var_288 + 0.0532627865961199306599205*var_18*var_19 + 0.0493827160493827133080913*var_125 + 0.1724867724867724938508928*var_93 + 0.1421516754850088160022636*var_193 + 0.1467372134038800735034158*var_119 + 0.2299823633156966584678571*var_30 + 0.0116402116402116416471468*var_92 + 0.0239858906525573199741697*var_45 + 0.3442680776014109822469322*var_77 + 0.3174603174603174426948726*var_649 + 0.0201058201058201060917874*var_50 + var_483 + 0.1382716049382715917115405*var_195 + 0.2088183421516754956215323*var_120 + 0.2878306878306878258122481*var_59 + 0.3809523809523809312338471*var_28 + 0.0042328042328042330896820*var_61 + 0.3333333333333333148296163*var_458; + A[280] = 16.0000000000000000000000000*var_14*var_650/(var_15*var_15*var_15); + A[745] = A[280]; + const double var_651 = 138.8000000000000113686837722*var_176 + var_428 + 98.6000000000000085265128291*var_75 + 30.5333333333333314385527046*var_19; + const double var_652 = var_119 + var_87; + const double var_653 = 1.6825396825396825573051274*var_30 + 7.2444444444444444641817427*var_77 + 0.7936507936507936067371816*var_652 + 0.0476190476190476164042309*var_18*var_651 + 1.2222222222222220988641084*var_24 + 0.1746031746031745934821799*var_48 + 1.3269841269841269326690281*var_349 + 1.2539682539682539541558981*var_120 + 1.5015873015873015816623592*var_44 + 1.4126984126984125644810319*var_16*var_35 + 0.1111111111111111049432054*var_1*var_3*var_478 + 1.6190476190476190687661529*var_140*var_16 + var_629; + A[34] = 0.2222222222222222098864108*var_14*var_653/(var_15*var_15*var_15); + A[499] = A[34]; + A[636] = 0.0000000000000000000000000; + A[572] = 0.0000000000000000000000000; + A[627] = A[162]; + A[611] = 0.0000000000000000000000000; + A[533] = A[68]; + A[125] = 16.0000000000000000000000000*var_14*var_312/(var_15*var_15*var_15); + A[619] = A[125]; + const double var_654 = 1.5714285714285713968507707*var_25 + 0.5714285714285713968507707*var_28 + var_205; + const double var_655 = var_110 + var_654; + const double var_656 = var_344 + var_366 + var_616 + 0.0825396825396825378762244*var_326 + var_324 + 0.0476190476190476164042309*var_44 + 0.1206349206349206365507243*var_17*var_20 + var_450 + 0.0444444444444444461406185*var_655; + A[250] = 1.7777777777777776790912867*var_14*var_656/(var_15*var_15*var_15); + const double var_657 = var_59 + var_181; + const double var_658 = var_19 + 0.3333333333333333148296163*var_75; + const double var_659 = 0.0444444444444444461406185*var_320 + 0.8444444444444444419772822*var_24 + 0.2814814814814814991628111*var_187 + 1.0814814814814814880605809*var_657 + 0.5777777777777778345225101*var_86 + 1.3629629629629629317122408*var_29 + 1.3037037037037038089692942*var_85 + 1.5851851851851852526209541*var_124*var_4*var_5 + 0.1407407407407407495814056*var_195 + 0.2370370370370370460832987*var_117 + 1.6000000000000000888178420*var_27 + 1.0222222222222223653176343*var_88 + 0.8370370370370370238788382*var_96 + var_516 + 0.7111111111111111382498962*var_219 + 0.2666666666666666629659233*var_615 + 0.1925925925925925930037863*var_17*var_19 + 0.3703703703703703498106847*var_50 + 0.6370370370370370682877592*var_25 + 0.3777777777777777679091287*var_18*var_658 + 1.7185185185185185563483401*var_28 + 1.0666666666666666518636930*var_48 + 0.9777777777777778567269706*var_36; + A[190] = 0.7619047619047618624676943*var_14*var_659/(var_15*var_15*var_15); + A[771] = A[190]; + const double var_660 = 0.0571428571428571410728559*var_204 + 0.0476190476190476164042309*var_18*var_192 + var_291; + A[691] = 0.0000000000000000000000000; + A[456] = 0.0000000000000000000000000; + A[148] = 0.0000000000000000000000000; + A[394] = A[133]; + A[750] = 0.0000000000000000000000000; + A[727] = 0.0000000000000000000000000; + A[502] = A[37]; + A[472] = A[7]; + A[147] = 0.0000000000000000000000000; + A[848] = 0.0000000000000000000000000; + const double var_661 = var_201 + var_209 + var_66 + var_71; + const double var_662 = var_155 + 0.0285714285714285705364279*var_194 + 0.0190476190476190493372499*var_532 + 0.1333333333333333314829616*var_206 + 0.0761904761904761973489997*var_661 + var_660 + 0.1142857142857142821457117*var_208 + 0.1523809523809523946979994*var_203 + 0.0476190476190476164042309*var_211 + var_387 + var_401 + 0.0380952380952380986744998*var_196; + A[404] = 28.4444444444444428654605872*var_14*var_662/(var_15*var_15*var_15); + A[433] = A[404]; + A[77] = 0.0000000000000000000000000; + const double var_663 = var_24 + var_86 + var_219; + const double var_664 = 7.4285714285714279370154145*var_29 + 9.3333333333333321490954404*var_28 + 1.6190476190476190687661529*var_663 + 1.0476190476190476719153821*var_17*var_94 + var_256 + 2.9047619047619046561692357*var_25 + 3.1428571428571427937015414*var_27 + var_592 + 1.5238095238095237249353886*var_88 + 2.4761904761904762750646114*var_44 + 5.0476190476190474498707772*var_1*var_3*var_82; + A[746] = A[281]; + A[875] = 0.0000000000000000000000000; + const double var_665 = 0.1174603174603174593482180*var_16*var_19; + const double var_666 = var_87 + var_343; + const double var_667 = 0.0698412698412698429439871*var_271 + 0.0761904761904761973489997*var_467 + 0.1873015873015873022922051*var_18*var_20 + var_369 + 0.0952380952380952328084618*var_22 + 0.0222222222222222230703093*var_210 + 0.0253968253968253968033686*var_24 + 0.3809523809523809312338471*var_215 + var_665 + var_148 + 0.2793650793650793717759484*var_30 + 0.1746031746031745934821799*var_45 + 0.0634920634920634885389745*var_50 + var_221 + 0.0476190476190476164042309*var_48 + 0.1650793650793650757524489*var_26 + 0.2984126984126984072354105*var_33*var_4*var_5 + 0.3936507936507936400438723*var_32 + var_471 + 0.4190476190476191131750738*var_27 + 0.1269841269841269770779490*var_464 + var_457 + 0.1587301587301587213474363*var_44 + 0.0126984126984126984016843*var_666; + A[156] = 7.1111111111111107163651468*var_14*var_667/(var_15*var_15*var_15); + A[650] = A[156]; + A[821] = 0.0000000000000000000000000; + A[323] = 0.0000000000000000000000000; + const double var_668 = var_631 + var_560; + A[599] = A[134]; + A[172] = 0.0000000000000000000000000; + A[880] = 0.0000000000000000000000000; + const double var_669 = 1.0888888888888890171813273*var_194 + 2.8984126984126983295197988*var_212 + 2.1714285714285712636240078*var_204 + 4.0380952380952388480750415*var_209 + 1.1174603174603174871037936*var_201 + 4.7365079365079365558699465*var_207 + 0.9619047619047620401033782*var_161 + 1.2095238095238096676098394*var_18*var_192 + 2.6666666666666665186369300*var_206 + 4.5333333333333332149095440*var_203 + 1.8666666666666666962726140*var_202 + 6.6539682539682543094272660*var_208 + 0.0285714285714285705364279*var_211 + 3.9873015873015873467011261*var_213 + 2.0507936507936506131954957*var_196; + const double var_670 = var_152 + var_145; + const double var_671 = var_141 + var_556; + const double var_672 = 0.0253968253968253968033686*var_670 + 0.1650793650793650757524489*var_671 + 0.2761904761904762084512299*var_18*var_19 + 0.4444444444444444197728217*var_118 + var_522 + 0.0380952380952380986744998*var_610 + 0.1904761904761904656169236*var_25 + 0.1269841269841269770779490*var_28 + 0.1111111111111111049432054*var_553 + 0.5841269841269841611719471*var_412 + var_640 + var_249 + 0.1015873015873015872134744*var_195 + 0.3174603174603174426948726*var_129 + 0.2539682539682539541558981*var_113 + 0.0634920634920634885389745*var_554 + 0.0222222222222222230703093*var_36 + 0.0793650793650793606737182*var_555 + 0.1174603174603174593482180*var_16*var_20 + var_331; + A[188] = 7.1111111111111107163651468*var_14*var_672/(var_15*var_15*var_15); + A[246] = A[188]; + const double var_673 = 0.1333333333333333314829616*var_235 + 0.2380952380952380820211545*var_24 + var_574 + 0.1047619047619047782937685*var_240; + const double var_674 = 0.2349206349206349186964360*var_141; + const double var_675 = var_414 + 0.0476190476190476164042309*var_195 + 0.1873015873015873022922051*var_16*var_20 + 0.2349206349206349186964360*var_119 + 0.2000000000000000111022302*var_120 + 0.0126984126984126984016843*var_193 + 0.3333333333333333148296163*var_673 + var_674; + A[38] = 0.8888888888888888395456433*var_14*var_675/(var_15*var_15*var_15); + A[241] = A[38]; + A[320] = 0.0000000000000000000000000; + A[711] = A[188]; + A[151] = A[35]; + A[412] = 0.0000000000000000000000000; + const double var_676 = 83.0000000000000000000000000*var_58 + 23.0000000000000000000000000*var_33; + const double var_677 = var_222 + 0.1206349206349206365507243*var_24 + 0.3333333333333333148296163*var_434 + 0.1153439153439153458391431*var_18*var_75 + 0.2878306878306878258122481*var_77 + 0.0634920634920634885389745*var_36 + 0.0624338624338624387233310*var_45 + 0.1777777777777777845624740*var_30 + 0.1862433862433862663543493*var_340 + var_584 + 0.0444444444444444461406185*var_88 + 0.0105820105820105814231624*var_339 + var_105 + 0.1671957671957672031393116*var_1*var_3*var_82 + 0.0253968253968253968033686*var_636 + 0.0772486772486772471646432*var_44 + 0.0021164021164021165448410*var_4*var_5*var_676; + A[103] = 42.6666666666666642981908808*var_14*var_677/(var_15*var_15*var_15); + A[858] = A[103]; + const double var_678 = var_94 + var_198; + const double var_679 = var_61 + var_87 + var_46; + const double var_680 = 0.0666666666666666657414808*var_194 + 0.1238095238095238276310184*var_382 + 0.3523809523809524058002296*var_212 + 0.0380952380952380986744998*var_679 + 0.1047619047619047782937685*var_43 + 0.4952380952380953105240735*var_207 + 0.1523809523809523946979994*var_208 + 0.2285714285714285642914234*var_18*var_678 + 0.1428571428571428492126927*var_383 + 0.4190476190476191131750738*var_213 + 0.2666666666666666629659233*var_564; + A[95] = 2.3703703703703702387883823*var_14*var_680/(var_15*var_15*var_15); + A[609] = 0.0000000000000000000000000; + A[514] = 0.0000000000000000000000000; + A[104] = 14.2222222222222214327302936*var_14*var_147/(var_15*var_15*var_15); + A[569] = A[104]; + const double var_681 = var_210 + var_168; + const double var_682 = 0.0825396825396825378762244*var_34 + 0.3333333333333333148296163*var_546 + 0.0761904761904761973489997*var_563 + var_367 + 0.0507936507936507936067372*var_18*var_198 + var_640 + 0.2158730158730158832369739*var_27 + 0.0222222222222222230703093*var_48 + 0.0888888888888888922812370*var_32 + 0.0476190476190476164042309*var_681 + var_665 + 0.1396825396825396858879742*var_26 + 0.1650793650793650757524489*var_16*var_70 + var_251 + var_279; + const double var_683 = 213.1428571428571387968986528*var_176 + 130.4285714285714163906959584*var_75 + 50.2857142857142846992246632*var_60 + 49.0000000000000000000000000*var_19; + const double var_684 = 2.5185185185185186007572611*var_129 + var_558 + 0.6433862433862433949371962*var_27 + 1.6465608465608467803065196*var_118 + 3.2253968253968254842334318*var_244 + 0.1883597883597883659856365*var_44 + 0.5724867724867724882997777*var_245 + 0.9566137566137566938806458*var_253 + 0.9777777777777778567269706*var_26 + 0.3343915343915344062786232*var_246 + 0.2497354497354497548933239*var_113 + 0.0211640211640211628463248*var_34 + 1.5291005291005290711581210*var_18*var_35 + 0.4052910052910053129160417*var_247 + 0.0095238095238095246686250*var_50 + 1.3121693121693120964721402*var_145 + 0.2285714285714285642914234*var_85 + 2.2687830687830690123973909*var_121*var_4*var_5 + 0.0074074074074074076901031*var_17*var_683 + 2.0000000000000000000000000*var_316; + A[206] = 0.0000000000000000000000000; + const double var_685 = var_113 + var_61; + const double var_686 = 0.1523809523809523946979994*var_130 + var_500 + var_475 + 0.1269841269841269770779490*var_85 + 0.0761904761904761973489997*var_129 + 0.0952380952380952328084618*var_126 + 0.0380952380952380986744998*var_186 + 0.0190476190476190493372499*var_685; + A[874] = 0.0000000000000000000000000; + const double var_687 = var_673 + 0.3904761904761905322303051*var_26 + 0.4571428571428571285828468*var_48 + 0.3523809523809524058002296*var_44 + 0.8380952380952382263501477*var_16*var_31 + 0.2857142857142856984253854*var_27 + var_506; + A[36] = 0.2962962962962962798485478*var_14*var_687/(var_15*var_15*var_15); + A[646] = A[36]; + A[480] = 0.0000000000000000000000000; + A[782] = 0.0000000000000000000000000; + const double var_688 = 0.1873015873015873022922051*var_17*var_35; + A[362] = A[72]; + A[614] = 0.0000000000000000000000000; + const double var_689 = var_372 + var_274; + A[86] = 0.0000000000000000000000000; + const double var_690 = 4.0952380952380948997415544*var_176 + 28.0000000000000000000000000*var_94 + 22.0238095238095219485785492*var_20 + 5.9761904761904762750646114*var_151 + 32.0952380952380948997415544*var_140; + A[62] = 0.0370370370370370349810685*var_14*var_17*var_690/(var_15*var_15*var_15); + const double var_691 = var_210 + var_9; + A[396] = A[193]; + A[256] = 0.0000000000000000000000000; + const double var_692 = 0.2306878306878306916782861*var_161; + const double var_693 = 53.8000000000000042632564146*var_134 + 41.0000000000000000000000000*var_81; + const double var_694 = var_355 + var_360; + const double var_695 = var_692 + 0.2539682539682539541558981*var_48 + 0.3333333333333333148296163*var_694 + 0.0201058201058201060917874*var_168 + 0.0846560846560846513852994*var_36 + 0.1428571428571428492126927*var_528 + 0.3756613756613756405222659*var_26 + 0.5862433862433862330476586*var_17*var_94 + 0.0370370370370370349810685*var_24 + 0.2476190476190476552620368*var_117 + 0.7153439153439153930236216*var_96 + 0.5925925925925925596970956*var_27 + 0.0677248677248677294349122*var_85 + 0.4846560846560846735897599*var_110 + var_466 + 0.6232804232804233235398783*var_126 + 0.0232804232804232832942937*var_44 + 0.4804232804232804743271856*var_130 + 0.2105820105820105925253927*var_124*var_4*var_5 + 0.0052910052910052907115812*var_1*var_3*var_693 + 0.0634920634920634885389745*var_167 + var_163; + A[205] = 0.0000000000000000000000000; + const double var_696 = var_16 + var_17; + const double var_697 = var_403 + var_166 + var_532; + const double var_698 = var_207 + var_202; + const double var_699 = 5.9761904761904762750646114*var_192*var_696 + 56.0000000000000000000000000*var_449 + 12.2857142857142846992246632*var_203 + 4.0952380952380948997415544*var_698 + 44.0476190476190438971570984*var_43 + 28.0000000000000000000000000*var_697 + 8.1904761904761897994831088*var_206 + 11.9523809523809525501292228*var_382 + 19.8095238095238102005168912*var_384 + 66.0714285714285693984493264*var_52 + 51.9047619047619051002584456*var_578; + A[0] = 0.0370370370370370349810685*var_14*var_699/(var_15*var_15*var_15); + A[465] = A[0]; + A[175] = 0.0000000000000000000000000; + A[124] = 1.3333333333333332593184650*var_14*var_669/(var_15*var_15*var_15); + A[589] = A[124]; + const double var_700 = 37.0000000000000000000000000*var_82 + 89.0000000000000000000000000*var_8; + const double var_701 = 0.0402116402116402121835748*var_120 + var_527 + 0.0232804232804232832942937*var_639 + 0.2116402116402116284632484*var_118 + 0.0253968253968253968033686*var_96 + 0.1100529100529100551275619*var_85 + 0.0687830687830687792505557*var_110 + 0.0666666666666666657414808*var_92 + 0.6666666666666666296592325*var_281 + 0.0677248677248677294349122*var_127 + 0.2285714285714285642914234*var_119 + 0.0349206349206349214719936*var_93 + 0.0148148148148148153802062*var_228 + 0.0634920634920634885389745*var_113 + var_324 + 0.0243386243386243400488311*var_44 + 0.0021164021164021165448410*var_1*var_3*var_700 + 0.0899470899470899420968806*var_18*var_19 + 0.1312169312169312318516745*var_130 + 0.2222222222222222098864108*var_143 + 0.4000000000000000222044605*var_331; + A[222] = 32.0000000000000000000000000*var_14*var_701/(var_15*var_15*var_15); + A[51] = 0.0000000000000000000000000; + A[578] = 0.0000000000000000000000000; + A[117] = 0.0000000000000000000000000; + A[321] = 0.0000000000000000000000000; + const double var_702 = var_321 + 0.4000000000000000222044605*var_280 + var_267 + 0.0222222222222222230703093*var_168 + var_225 + 0.0285714285714285705364279*var_45 + 0.0444444444444444461406185*var_145 + var_367 + var_399 + 0.0698412698412698429439871*var_229 + 0.0761904761904761973489997*var_193 + 0.0634920634920634885389745*var_210 + 0.0571428571428571410728559*var_34 + var_452 + var_472 + var_565; + A[191] = 7.1111111111111107163651468*var_14*var_702/(var_15*var_15*var_15); + const double var_703 = var_610 + var_229; + const double var_704 = var_45 + var_320; + const double var_705 = 0.0074074074074074076901031*var_553 + var_292 + 0.1058201058201058142316242*var_113 + 0.0867724867724867787721621*var_1*var_134*var_3 + 0.0148148148148148153802062*var_210 + 0.1820105820105820115806239*var_554 + 0.1439153439153439129061240*var_118 + 0.1142857142857142821457117*var_117 + 0.0179894179894179891132655*var_103 + 0.2582010582010582089296236*var_130 + 0.0211640211640211628463248*var_125 + 0.0095238095238095246686250*var_195 + 0.2878306878306878258122481*var_129 + 0.1269841269841269770779490*var_412 + 0.0761904761904761973489997*var_126 + 0.0042328042328042330896820*var_704 + 0.0835978835978836015696558*var_479 + 0.0275132275132275137818905*var_145 + 0.0105820105820105814231624*var_703 + 2.0000000000000000000000000*var_581; + A[130] = 4.0000000000000000000000000*var_14*var_705/(var_15*var_15*var_15); + A[595] = A[130]; + A[852] = 0.0000000000000000000000000; + const double var_706 = var_140 + var_176; + A[577] = 0.0000000000000000000000000; + A[510] = 0.0000000000000000000000000; + A[623] = A[158]; + A[406] = 0.0000000000000000000000000; + A[289] = 0.0000000000000000000000000; + A[215] = A[157]; + A[617] = A[65]; + A[126] = 1.7777777777777776790912867*var_14*var_638/(var_15*var_15*var_15); + A[591] = A[126]; + A[487] = 0.0000000000000000000000000; + A[891] = A[194]; + A[551] = 0.0000000000000000000000000; + A[633] = 0.0000000000000000000000000; + const double var_707 = var_23 + var_16*var_64; + const double var_708 = 0.8645502645502646243969025*var_18*var_20 + 0.3777777777777777679091287*var_154 + 0.9354497354497355310343210*var_29 + 0.0423280423280423256926497*var_87 + 1.1047619047619048338049197*var_33*var_4*var_5 + 0.5375661375661375807055720*var_26 + 0.0677248677248677294349122*var_707 + 0.0751322751322751336555683*var_16*var_75 + var_460 + var_482 + 1.7862433862433864106833425*var_27 + var_310 + 1.8962962962962963686663898*var_32 + 0.1386243386243386221945428*var_110 + 0.3386243386243386055411975*var_126 + 1.2486772486772486079331657*var_1*var_3*var_81 + 0.1597883597883598127964433*var_48 + 0.4264550264550264757623665*var_17*var_19 + 0.7915343915343915348614701*var_22 + 0.4000000000000000222044605*var_44 + 0.2402116402116402371635928*var_171 + 0.1439153439153439129061240*var_62 + 0.1947089947089947203906490*var_130 + 0.1015873015873015872134744*var_45 + 1.3164021164021164622681681*var_30; + A[218] = 5.3333333333333330372738601*var_14*var_708/(var_15*var_15*var_15); + A[712] = A[218]; + A[347] = 0.0000000000000000000000000; + A[604] = 0.0000000000000000000000000; + A[503] = A[38]; + A[861] = A[193]; + A[739] = A[129]; + A[29] = 0.0000000000000000000000000; + A[50] = 0.0000000000000000000000000; + const double var_709 = 59.0000000000000000000000000*var_33 + 54.3333333333333285963817616*var_58; + const double var_710 = 83.0000000000000000000000000*var_134 + 137.0000000000000000000000000*var_8; + A[850] = 0.0000000000000000000000000; + A[359] = 0.0000000000000000000000000; + A[240] = A[8]; + A[780] = 0.0000000000000000000000000; + A[732] = 0.0000000000000000000000000; + const double var_711 = 138.8000000000000113686837722*var_140 + 30.5333333333333314385527046*var_35 + var_423 + 98.6000000000000085265128291*var_20; + const double var_712 = var_61 + var_130; + const double var_713 = 1.6190476190476190687661529*var_17*var_176 + 0.1111111111111111049432054*var_4*var_5*var_586 + 1.6825396825396825573051274*var_29 + 1.2222222222222220988641084*var_22 + 1.4126984126984125644810319*var_17*var_19 + 0.0476190476190476164042309*var_18*var_711 + 7.2444444444444444641817427*var_32 + 1.2539682539682539541558981*var_126 + 0.1746031746031745934821799*var_50 + 1.5015873015873015816623592*var_45 + 1.3269841269841269326690281*var_298 + var_573 + 0.7936507936507936067371816*var_712; + A[64] = 0.2222222222222222098864108*var_14*var_713/(var_15*var_15*var_15); + A[587] = A[64]; + const double var_714 = var_309 + 0.1509700176366843005215657*var_25 + var_10 + 0.0250440917107583801981541*var_50 + 0.0532627865961199306599205*var_17*var_20 + 0.0846560846560846513852994*var_26 + 0.0663139329805996491362663*var_1*var_134*var_3 + 0.1333333333333333314829616*var_488 + 0.3333333333333333148296163*var_641 + 0.0201058201058201060917874*var_16*var_75 + 0.0056437389770723107862427*var_113 + 0.0363315696649030017706394*var_18*var_35 + 0.0264550264550264535579061*var_18*var_19 + var_481 + 0.0564373897707231009235329*var_125 + 0.0451499118165784862899415*var_117 + 0.0253968253968253968033686*var_27 + 0.0380952380952380986744998*var_118 + 0.0049382716049382715042815*var_96 + 0.1259259259259259411400933*var_17*var_35 + 0.0691358024691357958557703*var_121*var_4*var_5 + 0.0211640211640211628463248*var_381 + 0.0116402116402116416471468*var_48 + var_594 + 0.0747795414462081170503538*var_129; + A[269] = 0.0000000000000000000000000; + const double var_715 = var_209 + var_206; + A[220] = 1.3333333333333332593184650*var_14*var_390/(var_15*var_15*var_15); + A[772] = A[220]; + A[733] = 0.0000000000000000000000000; + A[200] = 0.0000000000000000000000000; + A[840] = 0.0000000000000000000000000; + A[363] = A[102]; + A[819] = 0.0000000000000000000000000; + A[414] = 0.0000000000000000000000000; + A[100] = 16.0000000000000000000000000*var_14*var_595/(var_15*var_15*var_15); + A[565] = A[100]; + A[80] = 0.0000000000000000000000000; + const double var_716 = 0.0476190476190476164042309*var_597 + 0.5238095238095238359576911*var_145 + 0.6666666666666666296592325*var_210 + 0.4761904761904761640423089*var_233; + const double var_717 = 0.5523809523809524169024598*var_27 + var_716 + 0.1523809523809523946979994*var_193 + 0.1047619047619047782937685*var_195 + 0.8190476190476191353795343*var_16*var_198 + 0.5047619047619048560093802*var_26 + 0.2000000000000000111022302*var_74; + A[44] = 0.5925925925925925596970956*var_14*var_717/(var_15*var_15*var_15); + A[421] = A[44]; + const double var_718 = var_28 + var_95; + A[519] = 0.0000000000000000000000000; + A[662] = 0.0000000000000000000000000; + A[115] = 0.0000000000000000000000000; + A[364] = A[132]; + A[144] = 0.0000000000000000000000000; + A[446] = 0.0000000000000000000000000; + A[683] = A[218]; + A[160] = 1.7777777777777776790912867*var_116*var_14/(var_15*var_15*var_15); + A[590] = A[125]; + A[489] = 0.0000000000000000000000000; + A[227] = 0.0000000000000000000000000; + A[673] = 0.0000000000000000000000000; + A[20] = 0.0000000000000000000000000; + A[809] = A[344]; + const double var_719 = var_119 + var_61; + const double var_720 = 0.1206349206349206365507243*var_283 + var_299 + 0.0317460317460317442694873*var_26 + 1.1619047619047619956944573*var_1*var_134*var_3 + 0.8349206349206349520031267*var_18*var_35 + 0.2253968253968254009667049*var_110 + 1.3587301587301587879608178*var_126 + 0.1269841269841269770779490*var_719 + 0.0825396825396825378762244*var_193 + 0.1523809523809523946979994*var_342 + 1.1682539682539683223438942*var_121*var_4*var_5 + 0.1746031746031745934821799*var_168 + 1.2825396825396826461229693*var_117 + 0.5523809523809524169024598*var_96 + 0.2793650793650793717759484*var_118 + 0.4793650793650793828781786*var_17*var_19 + var_617 + 0.0507936507936507936067372*var_22 + var_392 + 1.1174603174603174871037936*var_129 + 0.4095238095238095676897672*var_195 + 2.5269841269841268882601071*var_130 + var_593 + 0.1587301587301587213474363*var_691; + const double var_721 = var_232 + var_451; + const double var_722 = var_660 + 0.0285714285714285705364279*var_196 + 0.1333333333333333314829616*var_721; + A[23] = 0.0000000000000000000000000; + A[25] = 0.0000000000000000000000000; + A[454] = 0.0000000000000000000000000; + A[97] = 1.7777777777777776790912867*var_14*var_622/(var_15*var_15*var_15); + A[213] = A[97]; + A[295] = 0.0000000000000000000000000; + const double var_723 = 0.4952380952380953105240735*var_203 + 0.2285714285714285642914234*var_208 + 0.1904761904761904656169236*var_202 + var_291 + 0.1047619047619047782937685*var_18*var_192 + 0.1142857142857142821457117*var_204 + 0.3047619047619047893959987*var_715 + 0.0666666666666666657414808*var_385 + 0.0095238095238095246686250*var_383 + 0.1428571428571428492126927*var_51 + 0.1333333333333333314829616*var_46 + 0.0761904761904761973489997*var_386; + A[372] = 28.4444444444444428654605872*var_14*var_723/(var_15*var_15*var_15); + const double var_724 = 53.8000000000000042632564146*var_124 + 41.0000000000000000000000000*var_58; + A[419] = 0.0000000000000000000000000; + A[388] = 0.0000000000000000000000000; + A[28] = 0.0000000000000000000000000; + A[84] = 0.0000000000000000000000000; + const double var_725 = var_85 + var_603; + const double var_726 = 0.1544973544973544943292865*var_18*var_19 + 0.0264550264550264535579061*var_113 + 0.0190476190476190493372499*var_718 + 0.0423280423280423256926497*var_17*var_20 + 0.3333333333333333148296163*var_688 + 0.0476190476190476164042309*var_205 + 0.2042328042328042381203801*var_124*var_4*var_5 + 0.0740740740740740699621369*var_129 + 0.0455026455026455028951560*var_96 + 0.2306878306878306916782861*var_725 + 0.0042328042328042330896820*var_50 + 0.0497354497354497368521997*var_123 + 0.2000000000000000111022302*var_397 + 0.0666666666666666657414808*var_25 + 0.0783068783068783108580746*var_17*var_65 + 0.0105820105820105814231624*var_300; + A[63] = 2.6666666666666665186369300*var_14*var_726/(var_15*var_15*var_15); + A[286] = 0.0000000000000000000000000; + A[57] = 0.0000000000000000000000000; + A[251] = 2.3703703703703702387883823*var_14*var_722/(var_15*var_15*var_15); + A[338] = A[251]; + A[306] = A[190]; + A[508] = A[43]; + A[360] = A[12]; + const double var_727 = 0.0666666666666666657414808*var_154 + var_160; + const double var_728 = 0.1206349206349206365507243*var_119 + 0.2031746031746031744269487*var_193 + 0.3333333333333333148296163*var_716 + 0.1365079365079364948076801*var_120 + var_727 + 0.4253968253968253843133596*var_16*var_198 + var_536; + A[42] = 1.7777777777777776790912867*var_14*var_728/(var_15*var_15*var_15); + A[643] = 0.0000000000000000000000000; + A[515] = 0.0000000000000000000000000; + A[324] = 0.0000000000000000000000000; + A[179] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[6] = 2.6666666666666665186369300*var_14*var_695/(var_15*var_15*var_15); + A[471] = A[6]; + const double var_729 = 0.0359788359788359782265310*var_212 + 0.1897707231040564601620702*var_209 + 0.1428571428571428492126927*var_204 + 0.0663139329805996491362663*var_201 + 0.0571428571428571410728559*var_207 + 0.1216931216931216863663678*var_197 + 0.1805996472663139451597658*var_208 + 0.0469135802469135762549080*var_202 + 0.1509700176366843005215657*var_203 + 0.0257495590828924168780301*var_211 + 0.0617283950617283916351141*var_18*var_192 + 0.1040564373897707173277638*var_206 + 0.0765432098765432139542142*var_213; + A[4] = 2.0000000000000000000000000*var_14*var_729/(var_15*var_15*var_15); + A[705] = A[8]; + A[666] = 0.0000000000000000000000000; + A[622] = A[157]; + const double var_730 = 0.1650793650793650757524489*var_246 + 0.1015873015873015872134744*var_244 + 0.0571428571428571410728559*var_285 + var_407 + 0.0222222222222222230703093*var_276 + 0.2158730158730158832369739*var_118 + 0.0444444444444444461406185*var_96 + 0.0507936507936507936067372*var_490 + 0.0984126984126984100109681*var_290 + 0.0158730158730158721347436*var_489 + 0.0761904761904761973489997*var_205 + 0.1904761904761904656169236*var_129 + var_471 + var_295 + 0.2793650793650793717759484*var_119 + 0.0253968253968253968033686*var_127 + var_580 + 0.0476190476190476164042309*var_476 + 2.0000000000000000000000000*var_274; + A[434] = 85.3333333333333285963817616*var_14*var_730/(var_15*var_15*var_15); + A[899] = A[434]; + A[96] = 2.3703703703703702387883823*var_14*var_547/(var_15*var_15*var_15); + const double var_731 = 121.0000000000000000000000000*var_124 + 193.0000000000000000000000000*var_58; + A[555] = A[3]; + A[467] = A[2]; + A[16] = 0.0000000000000000000000000; + A[181] = A[36]; + A[697] = 0.0000000000000000000000000; + A[762] = 0.0000000000000000000000000; + A[704] = 0.0000000000000000000000000; + A[814] = 0.0000000000000000000000000; + A[346] = 0.0000000000000000000000000; + A[670] = 0.0000000000000000000000000; + A[856] = A[43]; + A[184] = A[126]; + A[430] = A[314]; + A[878] = 0.0000000000000000000000000; + A[379] = 0.0000000000000000000000000; + A[94] = 16.0000000000000000000000000*var_14*var_714/(var_15*var_15*var_15); + A[123] = A[94]; + A[339] = A[281]; + A[460] = 0.0000000000000000000000000; + A[631] = 0.0000000000000000000000000; + A[49] = 0.0000000000000000000000000; + A[769] = A[130]; + A[725] = 0.0000000000000000000000000; + A[274] = A[129]; + A[588] = A[94]; + const double var_732 = 0.2126984126984126921566798*var_456 + 0.4222222222222222209886411*var_18*var_75 + 0.6158730158730159054414344*var_29 + 0.9587301587301587657563573*var_28 + 0.5015873015873015816623592*var_27 + 0.2507936507936507908311796*var_24 + 0.2031746031746031744269487*var_16*var_35 + 0.8666666666666666962726140*var_152 + 0.4412698412698412564481032*var_25 + 0.2730158730158729896153602*var_17*var_60 + var_53 + 0.0095238095238095246686250*var_4*var_5*var_709 + 0.0507936507936507936067372*var_186 + 0.2888888888888889172612551*var_26 + 0.4634920634920635107434350*var_30 + 1.1174603174603174871037936*var_77 + var_377 + 0.0666666666666666657414808*var_551 + 0.0984126984126984100109681*var_22 + var_395 + var_727; + A[792] = 0.0000000000000000000000000; + A[397] = A[223]; + A[838] = A[373]; + const double var_733 = var_164 + 0.3333333333333333148296163*var_642 + 0.0328042328042328079629186*var_103 + 0.0666666666666666657414808*var_48 + 0.1809523809523809756427681*var_18*var_75 + 0.0105820105820105814231624*var_34 + var_623 + 0.0687830687830687792505557*var_36 + 0.2962962962962962798485478*var_77 + 0.0444444444444444461406185*var_664 + var_279; + A[313] = 32.0000000000000000000000000*var_14*var_733/(var_15*var_15*var_15); + A[400] = A[313]; + A[163] = 14.2222222222222214327302936*var_14*var_686/(var_15*var_15*var_15); + A[395] = A[163]; + A[761] = 0.0000000000000000000000000; + A[111] = 0.0000000000000000000000000; + A[294] = 0.0000000000000000000000000; + A[883] = 0.0000000000000000000000000; + A[756] = 0.0000000000000000000000000; + A[687] = A[222]; + A[146] = 0.0000000000000000000000000; + A[542] = 0.0000000000000000000000000; + A[560] = A[95]; + A[230] = 0.0000000000000000000000000; + A[260] = 0.0000000000000000000000000; + A[24] = 0.0000000000000000000000000; + A[648] = A[96]; + A[267] = 0.0000000000000000000000000; + A[645] = A[6]; + A[59] = 0.0000000000000000000000000; + A[863] = A[253]; + A[13] = 1.7777777777777776790912867*var_14*var_732/(var_15*var_15*var_15); + A[855] = A[13]; + A[110] = 0.0000000000000000000000000; + A[833] = A[252]; + A[685] = A[220]; + A[401] = A[343]; + A[170] = 0.0000000000000000000000000; + const double var_734 = 5.2000000000000001776356839*var_678 + 6.4888888888888889283634853*var_706 + 2.2777777777777776790912867*var_150 + 2.9222222222222224985443972*var_577; + A[32] = 0.0158730158730158721347436*var_14*var_18*var_734/(var_15*var_15*var_15); + A[497] = A[32]; + A[484] = 0.0000000000000000000000000; + A[114] = 0.0000000000000000000000000; + A[755] = 0.0000000000000000000000000; + const double var_735 = var_26 + var_18*var_94; + const double var_736 = 0.4174603174603174760015634*var_587 + 0.9269841269841270214868700*var_576 + 0.8349206349206349520031267*var_44 + 0.7428571428571428825193834*var_735 + var_363 + 0.1841269841269841389674866*var_246 + 0.5587301587301587435518968*var_27 + 0.3253968253968254065178201*var_247; + A[1] = 0.1111111111111111049432054*var_14*var_736/(var_15*var_15*var_15); + A[495] = A[1]; + A[139] = 0.0000000000000000000000000; + A[546] = 0.0000000000000000000000000; + A[714] = A[249]; + A[579] = 0.0000000000000000000000000; + A[879] = 0.0000000000000000000000000; + A[802] = A[221]; + A[791] = 0.0000000000000000000000000; + A[585] = A[4]; + A[552] = 0.0000000000000000000000000; + A[788] = 0.0000000000000000000000000; + A[716] = A[251]; + A[310] = 4.0000000000000000000000000*var_14*var_684/(var_15*var_15*var_15); + A[824] = 0.0000000000000000000000000; + A[265] = 0.0000000000000000000000000; + A[498] = A[33]; + A[758] = 0.0000000000000000000000000; + A[707] = A[68]; + A[870] = 0.0000000000000000000000000; + A[109] = 0.0000000000000000000000000; + A[820] = 0.0000000000000000000000000; + const double var_737 = var_166 + var_27; + A[531] = A[66]; + const double var_738 = var_120 + var_473; + const double var_739 = 0.0031746031746031746004211*var_1*var_3*var_710 + var_471 + 0.0349206349206349214719936*var_145 + 0.7492063492063492091688204*var_119 + 0.0571428571428571410728559*var_228 + 0.3396825396825396969902044*var_18*var_19 + 0.2539682539682539541558981*var_130 + 0.7936507936507936067371816*var_85 + 0.4698412698412698373928720*var_118 + 0.2984126984126984072354105*var_117 + 0.1047619047619047782937685*var_205 + 0.1523809523809523946979994*var_611 + 0.2000000000000000111022302*var_113 + var_508 + var_674 + 0.2793650793650793717759484*var_17*var_94 + 0.3333333333333333148296163*var_336 + 0.0126984126984126984016843*var_36 + 0.1873015873015873022922051*var_142 + 0.1492063492063492036177053*var_126 + 0.3142857142857142793701541*var_738; + A[5] = 0.8888888888888888395456433*var_14*var_739/(var_15*var_15*var_15); + A[661] = 0.0000000000000000000000000; + A[659] = A[194]; + A[337] = A[221]; + A[297] = 0.0000000000000000000000000; + const double var_740 = var_125 + var_9; + A[393] = A[103]; + A[860] = A[163]; + A[264] = 0.0000000000000000000000000; + A[640] = 0.0000000000000000000000000; + A[655] = A[190]; + A[107] = 0.0000000000000000000000000; + A[798] = A[101]; + A[765] = A[10]; + const double var_741 = 0.2952380952380952439106920*var_161; + const double var_742 = var_205 + var_181; + const double var_743 = 1.0920634920634919584614408*var_742 + 0.7968253968253967700619000*var_18*var_35 + 0.4031746031746031855291790*var_16*var_75 + var_741 + 0.0888888888888888922812370*var_453 + var_581 + var_376 + 0.1142857142857142821457117*var_141 + 0.5015873015873015816623592*var_96 + 0.2063492063492063377516672*var_168 + 0.6603174603174603030097956*var_145 + 1.1809523809523809756427681*var_129 + 0.2984126984126984072354105*var_195 + 2.0063492063492063266494370*var_130 + var_645 + 0.4000000000000000222044605*var_361; + const double var_744 = var_19 + var_150; + const double var_745 = 4.0952380952380948997415544*var_140 + 28.0000000000000000000000000*var_198 + 32.0952380952380948997415544*var_176 + 22.0238095238095219485785492*var_75 + 5.9761904761904762750646114*var_744; + A[775] = A[310]; + A[26] = 0.0000000000000000000000000; + A[575] = 0.0000000000000000000000000; + A[349] = 0.0000000000000000000000000; + A[557] = A[63]; + A[98] = 7.1111111111111107163651468*var_14*var_682/(var_15*var_15*var_15); + A[710] = A[158]; + const double var_746 = 0.5862433862433862330476586*var_16*var_198 + 0.0634920634920634885389745*var_438 + 0.6232804232804233235398783*var_120 + 0.2105820105820105925253927*var_1*var_134*var_3 + 0.0846560846560846513852994*var_186 + 0.0052910052910052907115812*var_4*var_5*var_724 + 0.5925925925925925596970956*var_28 + 0.7153439153439153930236216*var_195 + var_608 + 0.0370370370370370349810685*var_22 + 0.0677248677248677294349122*var_117 + 0.1428571428571428492126927*var_663 + 0.2539682539682539541558981*var_50 + var_692 + 0.0232804232804232832942937*var_45 + 0.4846560846560846735897599*var_193 + 0.0201058201058201060917874*var_93 + 0.4804232804232804743271856*var_119 + var_435 + 0.3756613756613756405222659*var_25 + 0.3333333333333333148296163*var_668 + 0.2476190476190476552620368*var_85; + A[9] = 2.6666666666666665186369300*var_14*var_746/(var_15*var_15*var_15); + A[735] = A[9]; + A[556] = A[33]; + A[581] = 0.0000000000000000000000000; + A[815] = 0.0000000000000000000000000; + A[309] = A[280]; + A[665] = 0.0000000000000000000000000; + A[171] = 0.0000000000000000000000000; + A[888] = A[104]; + A[402] = A[373]; + A[834] = A[282]; + A[385] = 0.0000000000000000000000000; + A[509] = A[44]; + A[441] = 0.0000000000000000000000000; + A[91] = A[33]; + A[207] = 0.0000000000000000000000000; + A[150] = A[5]; + A[333] = A[101]; + A[377] = 0.0000000000000000000000000; + A[375] = 0.0000000000000000000000000; + A[647] = A[66]; + A[173] = 0.0000000000000000000000000; + A[106] = 0.0000000000000000000000000; + A[737] = A[69]; + A[630] = 0.0000000000000000000000000; + A[234] = 0.0000000000000000000000000; + A[896] = A[344]; + A[448] = 0.0000000000000000000000000; + A[478] = A[13]; + A[612] = 0.0000000000000000000000000; + A[865] = A[313]; + A[663] = 0.0000000000000000000000000; + const double var_747 = 0.0476190476190476164042309*var_289 + 0.1375661375661375585011115*var_44 + 0.0465608465608465665885873*var_9 + var_493 + var_272 + 0.1343915343915343951763930*var_48 + 0.1693121693121693027705987*var_205 + 0.2074074074074074292006742*var_129 + var_613 + 0.1820105820105820115806239*var_26 + 0.1079365079365079416184869*var_45 + 0.1354497354497354588698244*var_737 + 0.0010582010582010582724205*var_36 + var_155 + 0.0846560846560846513852994*var_145 + var_173 + 0.1047619047619047782937685*var_50 + 0.1312169312169312318516745*var_118 + 0.0761904761904761973489997*var_271 + 0.0962962962962962965018932*var_18*var_35 + 0.0264550264550264535579061*var_18*var_20 + 0.0296296296296296307604123*var_34 + var_405 + 0.6666666666666666296592325*var_689; + A[279] = 21.3333333333333321490954404*var_14*var_747/(var_15*var_15*var_15); + A[744] = A[279]; + A[810] = 0.0000000000000000000000000; + A[285] = 0.0000000000000000000000000; + A[352] = 0.0000000000000000000000000; + A[180] = A[6]; + A[440] = 0.0000000000000000000000000; + A[462] = 0.0000000000000000000000000; + A[539] = A[74]; + A[411] = 0.0000000000000000000000000; + A[53] = 0.0000000000000000000000000; + A[657] = A[192]; + A[435] = 0.0000000000000000000000000; + A[842] = 0.0000000000000000000000000; + const double var_748 = 0.0031746031746031746004211*var_4*var_5*var_731 + 0.1492063492063492036177053*var_1*var_3*var_81 + 0.9269841269841270214868700*var_28 + 0.3142857142857142793701541*var_25 + 0.1428571428571428492126927*var_648 + 0.1619047619047619124277304*var_142 + 0.5460317460317459792307204*var_195 + 0.3492063492063491869643599*var_412 + 0.0825396825396825378762244*var_96 + var_160 + 0.4984126984126984183376408*var_120 + 0.5269841269841269992824095*var_30 + 0.0126984126984126984016843*var_92 + 0.2888888888888889172612551*var_93 + 0.3365079365079365336654860*var_193 + 0.3777777777777777679091287*var_24 + 0.1015873015873015872134744*var_16*var_35 + var_496 + 0.4571428571428571285828468*var_77 + 0.1269841269841269770779490*var_50 + 0.0349206349206349214719936*var_22 + 0.1746031746031745934821799*var_103 + var_688 + 0.6476190476190476497109216*var_29 + var_265 + 0.2349206349206349186964360*var_338; + A[11] = 0.8888888888888888395456433*var_14*var_748/(var_15*var_15*var_15); + A[795] = A[11]; + A[773] = A[250]; + A[367] = A[222]; + A[845] = 0.0000000000000000000000000; + A[696] = 0.0000000000000000000000000; + A[678] = A[97]; + A[811] = 0.0000000000000000000000000; + A[389] = 0.0000000000000000000000000; + A[541] = 0.0000000000000000000000000; + A[807] = A[342]; + A[573] = 0.0000000000000000000000000; + const double var_749 = 1.7523809523809525945381438*var_85 + 0.1428571428571428492126927*var_63; + const double var_750 = var_67 + var_749; + const double var_751 = 0.0423280423280423256926497*var_95 + 0.0063492063492063492008421*var_152 + 0.0105820105820105814231624*var_230 + 0.1153439153439153458391431*var_18*var_19 + 0.0465608465608465665885873*var_130 + 0.0550264550264550275637809*var_113 + 0.0306878306878306909843968*var_18*var_75 + 0.0349206349206349214719936*var_195 + 0.0571428571428571410728559*var_96 + 0.0042328042328042330896820*var_117 + 0.0444444444444444461406185*var_570 + 0.0846560846560846513852994*var_129 + 0.0328042328042328079629186*var_110 + 0.0169312169312169323587280*var_126 + 0.0296296296296296307604123*var_205 + var_644 + 0.0518518518518518573001685*var_17*var_20 + 0.1111111111111111049432054*var_750 + 0.1862433862433862663543493*var_231 + var_407; + A[254] = 42.6666666666666642981908808*var_14*var_751/(var_15*var_15*var_15); + A[428] = A[254]; + A[330] = A[11]; + A[54] = 0.0000000000000000000000000; + A[816] = 0.0000000000000000000000000; + A[785] = 0.0000000000000000000000000; + A[474] = A[9]; + A[90] = A[3]; + A[30] = A[1]; + A[166] = 0.0000000000000000000000000; + A[432] = A[374]; + A[743] = A[249]; + A[409] = 0.0000000000000000000000000; + A[625] = A[160]; + A[862] = A[223]; + A[564] = A[99]; + A[854] = 0.0000000000000000000000000; + A[60] = A[2]; + A[450] = 0.0000000000000000000000000; + A[846] = 0.0000000000000000000000000; + A[847] = 0.0000000000000000000000000; + A[178] = 0.0000000000000000000000000; + A[690] = 0.0000000000000000000000000; + A[718] = A[253]; + A[340] = A[311]; + A[626] = A[161]; + A[245] = A[158]; + A[632] = 0.0000000000000000000000000; + const double var_752 = 1.0920634920634919584614408*var_740 + 0.0888888888888888922812370*var_654 + 0.6603174603174603030097956*var_113 + 0.2063492063492063377516672*var_93 + 0.4000000000000000222044605*var_632 + 2.0063492063492063266494370*var_119 + 0.1142857142857142821457117*var_177 + var_741 + 0.4031746031746031855291790*var_17*var_20 + var_749 + 0.7968253968253967700619000*var_18*var_19 + 1.1809523809523809756427681*var_118 + var_491 + 0.5015873015873015816623592*var_195 + 0.2984126984126984072354105*var_96 + var_295; + A[386] = 0.0000000000000000000000000; + A[871] = 0.0000000000000000000000000; + A[494] = 0.0000000000000000000000000; + A[131] = 1.7777777777777776790912867*var_14*var_720/(var_15*var_15*var_15); + A[334] = A[131]; + A[562] = A[97]; + A[764] = 0.0000000000000000000000000; + A[526] = A[32]; + A[601] = 0.0000000000000000000000000; + A[458] = 0.0000000000000000000000000; + A[141] = 0.0000000000000000000000000; + A[248] = 7.1111111111111107163651468*var_14*var_752/(var_15*var_15*var_15); + A[79] = 0.0000000000000000000000000; + A[553] = 0.0000000000000000000000000; + A[214] = A[127]; + A[387] = 0.0000000000000000000000000; + A[507] = A[42]; + A[303] = A[100]; + A[637] = 0.0000000000000000000000000; + A[231] = 0.0000000000000000000000000; + A[747] = A[282]; + A[672] = 0.0000000000000000000000000; + A[602] = 0.0000000000000000000000000; + A[21] = 0.0000000000000000000000000; + A[88] = 0.0000000000000000000000000; + A[137] = 0.0000000000000000000000000; + A[830] = A[162]; + A[829] = A[132]; + A[493] = 0.0000000000000000000000000; + A[425] = A[164]; + A[628] = A[163]; + A[437] = 0.0000000000000000000000000; + A[204] = 0.0000000000000000000000000; + A[426] = A[194]; + A[813] = 0.0000000000000000000000000; + A[58] = 0.0000000000000000000000000; + A[547] = 0.0000000000000000000000000; + A[469] = A[4]; + A[554] = 0.0000000000000000000000000; + A[583] = 0.0000000000000000000000000; + A[783] = 0.0000000000000000000000000; + A[423] = A[104]; + const double var_753 = var_265 + 0.2000000000000000111022302*var_126 + 0.1873015873015873022922051*var_17*var_75 + 0.3333333333333333148296163*var_335 + 0.2349206349206349186964360*var_130 + 0.0476190476190476164042309*var_96 + 0.0126984126984126984016843*var_110 + var_499; + A[71] = 0.8888888888888888395456433*var_14*var_753/(var_15*var_15*var_15); + A[536] = A[71]; + A[345] = 0.0000000000000000000000000; + A[706] = A[38]; + A[300] = A[10]; + A[278] = A[249]; + A[684] = A[219]; + A[748] = A[283]; + A[528] = A[63]; + A[135] = 0.0000000000000000000000000; + A[571] = 0.0000000000000000000000000; + A[692] = 0.0000000000000000000000000; + A[703] = 0.0000000000000000000000000; + A[390] = A[13]; + A[293] = 0.0000000000000000000000000; + A[759] = 0.0000000000000000000000000; + A[491] = 0.0000000000000000000000000; + A[305] = A[160]; + A[652] = A[187]; + A[476] = A[11]; + A[616] = A[35]; + A[243] = A[98]; + A[768] = A[100]; + A[570] = 0.0000000000000000000000000; + A[778] = A[313]; + A[766] = A[40]; + A[298] = 0.0000000000000000000000000; + A[543] = 0.0000000000000000000000000; + A[445] = 0.0000000000000000000000000; + A[420] = A[14]; + A[544] = 0.0000000000000000000000000; + A[723] = 0.0000000000000000000000000; + A[128] = 1.7777777777777776790912867*var_14*var_618/(var_15*var_15*var_15); + A[709] = A[128]; + A[270] = A[9]; + A[392] = A[73]; + A[453] = 0.0000000000000000000000000; + A[444] = 0.0000000000000000000000000; + A[154] = A[125]; + A[322] = 0.0000000000000000000000000; + A[516] = 0.0000000000000000000000000; + A[31] = 0.0370370370370370349810685*var_14*var_16*var_745/(var_15*var_15*var_15); + A[229] = 0.0000000000000000000000000; + A[567] = A[102]; + A[505] = A[40]; + A[667] = 0.0000000000000000000000000; + A[512] = 0.0000000000000000000000000; + A[138] = 0.0000000000000000000000000; + A[770] = A[160]; + A[291] = 0.0000000000000000000000000; + A[177] = 0.0000000000000000000000000; + A[169] = 0.0000000000000000000000000; + A[731] = 0.0000000000000000000000000; + A[382] = 0.0000000000000000000000000; + A[794] = 0.0000000000000000000000000; + A[482] = 0.0000000000000000000000000; + A[786] = 0.0000000000000000000000000; + A[596] = A[131]; + A[247] = A[218]; + A[275] = A[159]; + A[563] = A[98]; + A[882] = 0.0000000000000000000000000; + A[708] = A[98]; + A[530] = A[65]; + A[621] = A[156]; + A[886] = A[44]; + A[481] = 0.0000000000000000000000000; + A[693] = 0.0000000000000000000000000; + A[48] = 0.0000000000000000000000000; + A[877] = 0.0000000000000000000000000; + A[201] = 0.0000000000000000000000000; + A[56] = 0.0000000000000000000000000; + A[209] = 0.0000000000000000000000000; + A[461] = 0.0000000000000000000000000; + A[893] = A[254]; + A[584] = 0.0000000000000000000000000; + A[540] = 0.0000000000000000000000000; + A[656] = A[191]; + A[302] = A[70]; + A[501] = A[36]; + A[348] = 0.0000000000000000000000000; + A[470] = A[5]; + A[299] = 0.0000000000000000000000000; + A[897] = A[374]; + A[797] = A[71]; + A[781] = 0.0000000000000000000000000; + A[644] = 0.0000000000000000000000000; + A[649] = A[126]; + A[664] = 0.0000000000000000000000000; + A[898] = A[404]; + A[674] = 0.0000000000000000000000000; + A[729] = 0.0000000000000000000000000; + A[452] = 0.0000000000000000000000000; + A[606] = 0.0000000000000000000000000; + A[639] = 0.0000000000000000000000000; + A[257] = 0.0000000000000000000000000; + A[381] = 0.0000000000000000000000000; + A[211] = A[37]; + A[701] = 0.0000000000000000000000000; + A[277] = A[219]; + A[776] = A[311]; + A[268] = 0.0000000000000000000000000; + A[447] = 0.0000000000000000000000000; + A[113] = 0.0000000000000000000000000; + A[699] = 0.0000000000000000000000000; + A[532] = A[67]; + A[208] = 0.0000000000000000000000000; + A[165] = 0.0000000000000000000000000; + A[85] = 0.0000000000000000000000000; + A[92] = A[63]; + A[196] = 0.0000000000000000000000000; + A[45] = 0.0000000000000000000000000; + A[466] = A[1]; + A[741] = A[189]; + A[702] = 0.0000000000000000000000000; + A[488] = 0.0000000000000000000000000; + A[308] = A[250]; + A[89] = 0.0000000000000000000000000; + A[436] = 0.0000000000000000000000000; + A[226] = 0.0000000000000000000000000; + A[844] = 0.0000000000000000000000000; + A[889] = A[134]; + A[836] = A[342]; + A[757] = 0.0000000000000000000000000; + A[799] = A[131]; + A[720] = 0.0000000000000000000000000; + A[698] = 0.0000000000000000000000000; + A[199] = 0.0000000000000000000000000; + A[120] = A[4]; + A[740] = A[159]; + A[391] = A[43]; + A[559] = A[94]; + A[796] = A[41]; + A[843] = 0.0000000000000000000000000; + A[326] = 0.0000000000000000000000000; + A[715] = A[250]; + A[537] = A[72]; + A[823] = 0.0000000000000000000000000; + A[826] = A[42]; + A[203] = 0.0000000000000000000000000; + A[763] = 0.0000000000000000000000000; + A[728] = 0.0000000000000000000000000; + A[105] = 0.0000000000000000000000000; + A[356] = 0.0000000000000000000000000; + A[233] = 0.0000000000000000000000000; + A[415] = 0.0000000000000000000000000; + A[332] = A[71]; + A[357] = 0.0000000000000000000000000; + A[399] = A[283]; + A[78] = 0.0000000000000000000000000; + A[304] = A[130]; + A[529] = A[64]; + A[506] = A[41]; + A[549] = 0.0000000000000000000000000; + A[872] = 0.0000000000000000000000000; + A[319] = 0.0000000000000000000000000; + A[152] = A[65]; + A[384] = 0.0000000000000000000000000; + A[803] = A[251]; + A[675] = A[7]; + A[869] = A[404]; + A[784] = 0.0000000000000000000000000; + A[145] = 0.0000000000000000000000000; + A[568] = A[103]; + A[121] = A[34]; + A[801] = A[191]; + A[235] = 0.0000000000000000000000000; + A[734] = 0.0000000000000000000000000; + A[676] = A[37]; + A[721] = 0.0000000000000000000000000; + A[380] = 0.0000000000000000000000000; + A[603] = 0.0000000000000000000000000; + A[410] = 0.0000000000000000000000000; + A[724] = 0.0000000000000000000000000; + A[61] = A[32]; + A[19] = 0.0000000000000000000000000; + A[618] = A[95]; + A[805] = A[311]; + A[890] = A[164]; + A[149] = 0.0000000000000000000000000; + A[635] = 0.0000000000000000000000000; + A[726] = 0.0000000000000000000000000; + A[608] = 0.0000000000000000000000000; + A[518] = 0.0000000000000000000000000; + A[486] = 0.0000000000000000000000000; + A[598] = A[133]; + A[736] = A[39]; + A[276] = A[189]; + A[183] = A[96]; + A[504] = A[39]; + A[561] = A[96]; + A[316] = 0.0000000000000000000000000; + A[405] = 0.0000000000000000000000000; + A[418] = 0.0000000000000000000000000; + A[841] = 0.0000000000000000000000000; + A[442] = 0.0000000000000000000000000; + A[307] = A[220]; + A[668] = 0.0000000000000000000000000; + A[677] = A[67]; + A[831] = A[192]; + A[605] = 0.0000000000000000000000000; + A[832] = A[222]; + A[228] = 0.0000000000000000000000000; + A[262] = 0.0000000000000000000000000; + A[527] = A[62]; + A[341] = 7.1111111111111107163651468*var_14*var_743/(var_15*var_15*var_15); + A[87] = 0.0000000000000000000000000; + A[365] = A[162]; + A[325] = 0.0000000000000000000000000; + A[371] = A[342]; + A[455] = 0.0000000000000000000000000; + A[429] = A[284]; + A[153] = A[95]; + A[417] = 0.0000000000000000000000000; + A[76] = 0.0000000000000000000000000; + A[867] = A[373]; + A[422] = A[74]; + A[119] = 0.0000000000000000000000000; + A[122] = A[64]; + A[717] = A[252]; + A[210] = A[7]; + A[837] = A[372]; + A[828] = A[102]; + A[607] = 0.0000000000000000000000000; + A[185] = A[156]; + A[835] = A[312]; + A[694] = 0.0000000000000000000000000; + A[350] = 0.0000000000000000000000000; + A[439] = 0.0000000000000000000000000; + A[112] = 0.0000000000000000000000000; + A[335] = A[161]; + A[216] = A[187]; + A[660] = 0.0000000000000000000000000; + A[271] = A[39]; + A[255] = 0.0000000000000000000000000; + A[513] = 0.0000000000000000000000000; + A[431] = A[344]; + A[443] = 0.0000000000000000000000000; + A[866] = A[343]; + A[336] = A[191]; + A[806] = A[341]; + A[232] = 0.0000000000000000000000000; + A[328] = 0.0000000000000000000000000; + A[774] = A[280]; + A[361] = A[42]; + A[686] = A[221]; + A[244] = A[128]; + A[15] = 0.0000000000000000000000000; + A[722] = 0.0000000000000000000000000; + A[496] = A[31]; + A[752] = 0.0000000000000000000000000; + A[751] = 0.0000000000000000000000000; + A[83] = 0.0000000000000000000000000; + A[653] = A[188]; + A[383] = 0.0000000000000000000000000; + A[857] = A[73]; + A[318] = 0.0000000000000000000000000; + A[327] = 0.0000000000000000000000000; + A[615] = A[5]; + A[817] = 0.0000000000000000000000000; + A[398] = A[253]; + A[851] = 0.0000000000000000000000000; + A[586] = A[34]; + A[376] = 0.0000000000000000000000000; + A[317] = 0.0000000000000000000000000; + A[689] = A[224]; + A[719] = A[254]; + A[142] = 0.0000000000000000000000000; + A[853] = 0.0000000000000000000000000; + A[818] = 0.0000000000000000000000000; + A[593] = A[128]; + A[634] = 0.0000000000000000000000000; + A[713] = A[248]; + A[198] = 0.0000000000000000000000000; + A[370] = A[312]; + A[22] = 0.0000000000000000000000000; + A[438] = 0.0000000000000000000000000; + A[416] = 0.0000000000000000000000000; + A[550] = 0.0000000000000000000000000; + A[534] = A[69]; + A[730] = 0.0000000000000000000000000; + A[368] = A[252]; + A[47] = 0.0000000000000000000000000; + A[793] = 0.0000000000000000000000000; + A[594] = A[129]; + A[535] = A[70]; + A[463] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q4_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q4_quadrature.h new file mode 100644 index 0000000..e137e8e --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q4_quadrature.h @@ -0,0 +1,19944 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P2_Q4_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P2_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q4_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 15; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q4_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 30; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 15: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 20: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 21: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 22: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 23: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 24: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 25: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 26: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 27: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 28: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 29: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[20] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[21] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[22] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[23] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[24] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[25] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[26] = vals[1]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[27] = vals[1]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[28] = vals[1]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[29] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[15]; + vertex_values[3] = dof_values[16]; + vertex_values[5] = dof_values[17]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q4_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q4_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 3*m.num_entities[1] + 3*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 15; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 15; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 5; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 3; + break; + } + case 2: + { + return 3; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q4_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q4_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 6*m.num_entities[1] + 6*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 30; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 30; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 10; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 6; + break; + } + case 2: + { + return 6; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + dofs[15] = offset + c.entity_indices[0][0]; + dofs[16] = offset + c.entity_indices[0][1]; + dofs[17] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[18] = offset + 3*c.entity_indices[1][0]; + dofs[19] = offset + 3*c.entity_indices[1][0] + 1; + dofs[20] = offset + 3*c.entity_indices[1][0] + 2; + dofs[21] = offset + 3*c.entity_indices[1][1]; + dofs[22] = offset + 3*c.entity_indices[1][1] + 1; + dofs[23] = offset + 3*c.entity_indices[1][1] + 2; + dofs[24] = offset + 3*c.entity_indices[1][2]; + dofs[25] = offset + 3*c.entity_indices[1][2] + 1; + dofs[26] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[27] = offset + 3*c.entity_indices[2][0]; + dofs[28] = offset + 3*c.entity_indices[2][0] + 1; + dofs[29] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + dofs[5] = 16; + dofs[6] = 17; + dofs[7] = 18; + dofs[8] = 19; + dofs[9] = 20; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + dofs[5] = 15; + dofs[6] = 17; + dofs[7] = 21; + dofs[8] = 22; + dofs[9] = 23; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + dofs[5] = 15; + dofs[6] = 16; + dofs[7] = 24; + dofs[8] = 25; + dofs[9] = 26; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 15; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 16; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 17; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + dofs[3] = 18; + dofs[4] = 19; + dofs[5] = 20; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + dofs[3] = 21; + dofs[4] = 22; + dofs[5] = 23; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + dofs[3] = 24; + dofs[4] = 25; + dofs[5] = 26; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + dofs[3] = 27; + dofs[4] = 28; + dofs[5] = 29; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + coordinates[15][0] = x[0][0]; + coordinates[15][1] = x[0][1]; + coordinates[16][0] = x[1][0]; + coordinates[16][1] = x[1][1]; + coordinates[17][0] = x[2][0]; + coordinates[17][1] = x[2][1]; + coordinates[18][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[18][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[19][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[19][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[20][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[20][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[21][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[21][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[22][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[22][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[23][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[23][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[24][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[24][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[25][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[25][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[26][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[26][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[27][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[27][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[28][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[28][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[29][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[29][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p2_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W16[16] = {0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525}; + // Quadrature points on the UFC reference element: (0.0654669945550145, 0.0571041961145177), (0.0502101232113698, 0.276843013638124), (0.028912084224389, 0.583590432368917), (0.00970378512694614, 0.860240135656219), (0.311164552244357, 0.0571041961145177), (0.238648659731443, 0.276843013638124), (0.137419104134574, 0.583590432368917), (0.0461220799064521, 0.860240135656219), (0.631731251641125, 0.0571041961145177), (0.484508326630433, 0.276843013638124), (0.278990463496509, 0.583590432368917), (0.0936377844373285, 0.860240135656219), (0.877428809330468, 0.0571041961145177), (0.672946863150506, 0.276843013638124), (0.387497483406694, 0.583590432368917), (0.130056079216834, 0.860240135656219) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[16][5] = \ + {{-2.50971523732187, -0.771583215541929, 0.261867978220057, 3.2812984528638, -0.261867978220058}, + {-1.69178745260203, 0.107372054552495, 0.200840492845479, 1.58441539804953, -0.200840492845479}, + {-0.549989933626777, 1.33436172947567, 0.115648336897555, -0.78437179584889, -0.115648336897555}, + {0.479775683132663, 2.44096054262488, 0.0388151405077828, -2.92073622575754, -0.0388151405077833}, + {-1.5269250065645, -0.771583215541929, 1.24465820897743, 2.29850822210643, -1.24465820897743}, + {-0.938033306521733, 0.107372054552495, 0.954594638925771, 0.830661251969238, -0.954594638925771}, + {-0.115961853986035, 1.33436172947567, 0.549676416538297, -1.21839987548963, -0.549676416538297}, + {0.625448862250687, 2.44096054262488, 0.184488319625806, -3.06640940487556, -0.184488319625807}, + {-0.244658208977428, -0.771583215541929, 2.5269250065645, 1.01624142451936, -2.5269250065645}, + {0.0454053610742283, 0.107372054552495, 1.93803330652173, -0.152777415626723, -1.93803330652173}, + {0.450323583461703, 1.33436172947567, 1.11596185398603, -1.78468531293737, -1.11596185398603}, + {0.815511680374192, 2.44096054262488, 0.374551137749312, -3.25647222299907, -0.374551137749313}, + {0.738132021779942, -0.771583215541929, 3.50971523732187, 0.0334511937619886, -3.50971523732187}, + {0.799159507154521, 0.107372054552495, 2.69178745260202, -0.906531561707015, -2.69178745260202}, + {0.884351663102444, 1.33436172947567, 1.54998993362678, -2.21871339257811, -1.54998993362678}, + {0.961184859492216, 2.44096054262488, 0.520224316867337, -3.40214540211709, -0.520224316867337}}; + + // Array of non-zero columns + static const unsigned int nzc4[5] = {6, 8, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc1[5] = {0, 2, 3, 4, 5}; + + static const double FE0_C0_D10[16][5] = \ + {{-2.50971523732187, -0.738132021779942, 0.228416784458069, -0.228416784458069, 3.24784725910181}, + {-1.69178745260203, -0.799159507154521, 1.10737205455249, -1.10737205455249, 2.49094695975655}, + {-0.549989933626776, -0.884351663102445, 2.33436172947567, -2.33436172947567, 1.43434159672922}, + {0.479775683132663, -0.961184859492216, 3.44096054262488, -3.44096054262488, 0.481409176359553}, + {-1.5269250065645, 0.244658208977428, 0.228416784458069, -0.228416784458069, 1.28226679758707}, + {-0.938033306521733, -0.0454053610742285, 1.10737205455249, -1.10737205455249, 0.983438667595962}, + {-0.115961853986035, -0.450323583461703, 2.33436172947567, -2.33436172947567, 0.566285437447738}, + {0.625448862250687, -0.815511680374192, 3.44096054262488, -3.44096054262488, 0.190062818123506}, + {-0.244658208977428, 1.5269250065645, 0.228416784458069, -0.228416784458069, -1.28226679758707}, + {0.0454053610742284, 0.938033306521733, 1.10737205455249, -1.10737205455249, -0.983438667595961}, + {0.450323583461703, 0.115961853986035, 2.33436172947567, -2.33436172947567, -0.566285437447738}, + {0.815511680374193, -0.625448862250686, 3.44096054262488, -3.44096054262488, -0.190062818123506}, + {0.738132021779942, 2.50971523732187, 0.228416784458069, -0.228416784458069, -3.24784725910181}, + {0.79915950715452, 1.69178745260202, 1.10737205455249, -1.10737205455249, -2.49094695975655}, + {0.884351663102444, 0.549989933626777, 2.33436172947567, -2.33436172947567, -1.43434159672922}, + {0.961184859492217, -0.479775683132662, 3.44096054262488, -3.44096054262488, -0.481409176359554}}; + + // Array of non-zero columns + static const unsigned int nzc5[5] = {6, 7, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc2[5] = {0, 1, 3, 4, 5}; + + static const double FE1_C0_D01[16][14] = \ + {{-3.73667068880549, -0.311049493080665, 0.223979331051489, 0.104990345117057, 0.137222657043635, 6.14026988141177, -3.72353966515001, 1.6309899656244, -3.12426160441429, 1.1635146186775, -0.223979331051489, 3.89316339902554, -1.26850496379455, -0.906124451654892}, + {-0.135353153966954, 0.286839134679349, 0.192514372389236, -0.194970789566955, -0.129262778980056, -3.50043481058447, 5.01065174007844, -1.66170291020636, -1.01577547644434, 0.703579506158886, -0.192514372389235, -0.12063127175725, -0.508608716591934, 1.26566952718165}, + {0.0415749950107144, -0.308068880728994, 0.128479868913391, -0.375214285885602, 0.334729745719718, -0.111745376126847, -3.41368229886306, 3.79192156070819, 0.00713420856908595, 0.21477291899535, -0.128479868913389, -0.936666822030393, 0.160441366890248, 0.594802867741591}, + {-0.189449171833466, 3.25735599136755, 0.0487792767304758, -0.219445802063643, 0.436666840246954, 0.95608648483319, -1.80781257328652, -2.21618073108076, 0.00800745691652438, 0.00150907887808238, -0.0487792767304776, -0.0301805673092463, 0.217936723185553, -0.414493729854227}, + {0.133791234088099, -0.311049493080665, -0.153342364114824, -0.165402786473892, 0.652219136176813, 0.442570807553647, -1.3813060350523, 1.11599348649123, -4.97406902858338, -1.23446157521331, 0.153342364114824, 7.29981484256821, 1.3998643616872, -2.97796495016165}, + {0.308996527150275, 0.286839134679349, 0.0302078341708109, -0.0526515215640031, -0.614385844601294, -1.28562081113318, 1.86636499388868, -1.17657984458512, -1.04351159908944, 0.124659409468331, -0.0302078341708105, -2.60973956167772, -0.0720078879043259, 4.26763700536846}, + {-0.282271801510133, -0.308068880728994, 0.239334576747593, -0.908127385775844, 1.59097010879606, 1.41719178937472, -3.36253230476743, 2.53568119763184, 0.351667780172716, 0.304940851746767, -0.239334576747592, -3.01920386250499, 0.603186534029077, 1.07656597353622}, + {0.0124813340807398, 3.25735599136756, 0.18209870160566, -0.884949023586165, 2.07547700561112, -0.144284842667495, 0.72943841366413, -3.85499089644493, -0.0213463855701444, -0.0377481596742715, -0.182098701605662, 0.23211087524138, 0.922697183260432, -2.28624149528236}, + {-0.201686066324276, -0.311049493080666, 1.3554004060624, -2.0957669272062, 1.32414572376389, -0.0284094867612285, 0.0970781472620237, 0.444066898904147, 1.38210514028492, -5.746415673492, -1.3554004060624, -0.180265872305136, 7.8421826006982, -2.52598499174367}, + {-0.346344400331788, 0.28683913467935, -0.0751011451800905, 2.20833165141887, -1.24733596999111, 0.763889850402159, -0.160754865554418, -0.543629719195304, 1.2840311239631, -1.65285136545305, 0.0751011451800913, -4.07046884580067, -0.555480285965825, 4.03377369182868}, + {-0.219768719105238, -0.308068880728994, -0.0762683315720014, 0.474765854519233, 3.23001296550025, 0.848799090920449, -1.21759983201387, 0.896638340927649, 0.29135979252359, -0.0128571513285976, 0.0762683315720014, -1.07011301851141, -0.461908703190635, -2.45125973951242}, + {0.421464492679141, 3.25735599136756, 0.253854565960165, -1.37791402619754, 4.21366661803254, -2.10081322861208, 4.41517325343173, -5.99318050886635, -0.248496677091294, -0.147825162397021, -0.253854565960168, 1.51384139149734, 1.52573918859456, -5.47901133243858}, + {0.233570224452106, -0.311049493080667, 8.86543618214378, -4.7844194839011, 1.83914220289708, 0.127356496601796, 0.0210523522557917, -0.0709295802290264, -1.48464849089744, 4.19511744299535, -8.86543618214378, -0.593187071957072, 0.589302040905737, 0.238693359957438}, + {0.379194714537726, 0.286839134679351, 2.10023545454793, 5.53186235862513, -1.73245903561235, -0.483697023102141, -0.123830172540867, -0.0585066535740698, -1.64372700413302, 2.72470424750157, -2.10023545454793, 2.70286774813649, -8.25656660612669, 0.673318291608882}, + {0.615048549486148, -0.308068880728992, -0.255749379128854, 3.12750919457463, 4.48625332857659, -1.96658424863585, 2.0192066020274, -0.359602022148699, -1.39109901070619, 0.655303335752943, 0.255749379128853, 5.24565519573868, -3.78281253032758, -8.34080951360908}, + {0.862158677217334, 3.25735599136756, 0.246225772336431, -1.46807443034702, 5.85247678339671, -4.01529105210979, 7.52776705775542, -7.63199067423052, -0.614429658327018, -0.230215159323225, -0.246225772336434, 3.2633976075431, 1.69828958967025, -8.5014447326128}}; + + // Array of non-zero columns + static const unsigned int nzc10[14] = {15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; + + // Array of non-zero columns + static const unsigned int nzc7[14] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + + static const double FE1_C0_D10[16][14] = \ + {{-3.73667068880549, -0.233570224452107, 0.0966228344496946, 0.0839379928612569, 0.208152237272668, -2.725166300732, 1.06087981875107, -0.208152237272668, 5.74117457772949, -3.03160282431785, 1.26066915984596, 3.30386135811979, -0.675317891837485, -1.14481781161233}, + {-0.135353153966955, -0.379194714537727, 0.676211395491376, -0.0711406170260824, -0.0707561254059923, -5.6006702651324, -0.521210618546693, 0.070756125405991, 1.08445997810359, -2.02112474134269, 1.45121263174378, 8.13593533436945, -3.21147646472843, 0.592351235572778}, + {0.0415749950107149, -0.615048549486149, 2.09506411754924, -2.39442088791299, 0.694331767868412, 0.144004003002005, -6.54119149343769, -0.694331767868411, -0.248615170559768, -0.440530416757595, 1.2626191417928, 2.84614570829718, -5.08521382884843, 8.93561238135068}, + {-0.189449171833467, -0.86215867721733, 4.06407032884026, -7.74721285981905, 8.06865751447747, 0.709860712496763, -0.339738142939498, -8.06865751447746, 0.254233229252959, 0.231724238201303, 0.565650381596535, -1.7284701569795, -3.04546088435752, 8.08695100275854}, + {0.133791234088098, 0.201686066324276, -0.124932877353594, -0.262480933735916, 0.208152237272667, -0.912829598508755, 0.714460892153898, -0.208152237272667, -3.61866862252097, 4.51195409827869, -1.22876277617009, -0.542367758129989, 1.58013023399234, -0.451979958417981}, + {0.308996527150275, 0.346344400331788, -0.733682016231347, 0.108103343990414, -0.0707561254059911, -1.21051966595309, -0.341966657530196, 0.0707561254059907, -1.11861274426953, 1.77751077492138, -1.31423895813391, -2.0542592757119, 3.99846095789633, 0.233863313539781}, + {-0.282271801510132, 0.219768719105237, -0.609464514172856, 0.309472446238023, 0.694331767868412, 1.49346012094672, -3.83729815928667, -0.694331767868411, 0.275399448600715, 0.317798003075364, -0.530694369271184, -2.55729515931436, 1.67329955254049, 3.52782571304864}, + {0.0124813340807383, -0.421464492679139, 2.28291193021773, -5.30012227701789, 8.06865751447747, -0.398139408627658, 2.10735243986167, -8.06865751447747, 0.232508180390025, 0.110077002722745, 0.06639797548563, -1.29362831335318, -0.591144208236892, 3.19276983715621}, + {-0.201686066324277, -0.133791234088099, 0.912829598508756, -0.714460892153894, 0.208152237272666, 0.124932877353596, 0.262480933735919, -0.208152237272666, 1.22876277617009, -4.51195409827869, 3.61866862252098, -1.58013023399234, 0.542367758129989, 0.451979958417975}, + {-0.346344400331789, -0.308996527150274, 1.21051966595309, 0.341966657530194, -0.0707561254059904, 0.733682016231346, -0.108103343990415, 0.0707561254059907, 1.31423895813391, -1.77751077492138, 1.11861274426953, -3.99846095789633, 2.0542592757119, -0.23386331353978}, + {-0.219768719105238, 0.282271801510132, -1.49346012094673, 3.83729815928666, 0.694331767868412, 0.609464514172855, -0.309472446238026, -0.694331767868411, 0.530694369271184, -0.317798003075364, -0.275399448600715, -1.67329955254049, 2.55729515931436, -3.52782571304864}, + {0.42146449267914, -0.012481334080738, 0.398139408627662, -2.10735243986166, 8.06865751447747, -2.28291193021774, 5.30012227701789, -8.06865751447747, -0.0663979754856289, -0.110077002722752, -0.232508180390022, 0.591144208236898, 1.29362831335318, -3.19276983715624}, + {0.233570224452107, 3.73667068880549, 2.725166300732, -1.06087981875107, 0.208152237272666, -0.0966228344496921, -0.0839379928612601, -0.208152237272666, -1.26066915984595, 3.03160282431785, -5.74117457772949, 0.675317891837489, -3.3038613581198, 1.14481781161233}, + {0.379194714537727, 0.135353153966955, 5.6006702651324, 0.521210618546686, -0.070756125405989, -0.676211395491381, 0.0711406170260862, 0.0707561254059894, -1.45121263174378, 2.02112474134268, -1.08445997810359, 3.21147646472842, -8.13593533436944, -0.592351235572775}, + {0.615048549486148, -0.0415749950107151, -0.144004003002004, 6.54119149343768, 0.694331767868413, -2.09506411754925, 2.394420887913, -0.694331767868413, -1.2626191417928, 0.440530416757598, 0.248615170559768, 5.08521382884843, -2.84614570829718, -8.93561238135068}, + {0.862158677217332, 0.189449171833466, -0.709860712496757, 0.339738142939503, 8.06865751447747, -4.06407032884026, 7.74721285981907, -8.06865751447747, -0.565650381596537, -0.231724238201309, -0.254233229252954, 3.04546088435754, 1.72847015697949, -8.08695100275858}}; + + // Array of non-zero columns + static const unsigned int nzc11[14] = {15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; + + // Array of non-zero columns + static const unsigned int nzc8[14] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 900; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 60. + double G[12]; + G[0] = K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 76288 + for (unsigned int ip = 0; ip < 16; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 40 + for (unsigned int r = 0; r < 5; r++) + { + F0 += FE0_C0_D10[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D10[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 24 + double I[3]; + // Number of operations: 8 + I[0] = W16[ip]*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 8 + I[1] = W16[ip]*(F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 8 + I[2] = W16[ip]*(F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 4704 + for (unsigned int j = 0; j < 14; j++) + { + for (unsigned int k = 0; k < 14; k++) + { + // Number of operations to compute entry: 3 + A[nzc10[j]*30 + nzc10[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc10[j]*30 + nzc11[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*30 + nzc10[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*30 + nzc11[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc7[j]*30 + nzc7[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc7[j]*30 + nzc8[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*30 + nzc7[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*30 + nzc8[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p2_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q4_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q4_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p2_q4_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p2_q4_tensor.h new file mode 100644 index 0000000..9ea9f5a --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p2_q4_tensor.h @@ -0,0 +1,20745 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P2_Q4_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P2_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q4_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 15; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p2_q4_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 30; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 15: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 20: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 21: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 22: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 23: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 24: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 25: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 26: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 27: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 28: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 29: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[20] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[21] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[22] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[23] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[24] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[25] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[26] = vals[1]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[27] = vals[1]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[28] = vals[1]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[29] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[15]; + vertex_values[3] = dof_values[16]; + vertex_values[5] = dof_values[17]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q4_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q4_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 3*m.num_entities[1] + 3*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 15; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 15; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 5; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 3; + break; + } + case 2: + { + return 3; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p2_q4_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p2_q4_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 6*m.num_entities[1] + 6*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 30; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 30; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 10; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 6; + break; + } + case 2: + { + return 6; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + dofs[15] = offset + c.entity_indices[0][0]; + dofs[16] = offset + c.entity_indices[0][1]; + dofs[17] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[18] = offset + 3*c.entity_indices[1][0]; + dofs[19] = offset + 3*c.entity_indices[1][0] + 1; + dofs[20] = offset + 3*c.entity_indices[1][0] + 2; + dofs[21] = offset + 3*c.entity_indices[1][1]; + dofs[22] = offset + 3*c.entity_indices[1][1] + 1; + dofs[23] = offset + 3*c.entity_indices[1][1] + 2; + dofs[24] = offset + 3*c.entity_indices[1][2]; + dofs[25] = offset + 3*c.entity_indices[1][2] + 1; + dofs[26] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[27] = offset + 3*c.entity_indices[2][0]; + dofs[28] = offset + 3*c.entity_indices[2][0] + 1; + dofs[29] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + dofs[5] = 16; + dofs[6] = 17; + dofs[7] = 18; + dofs[8] = 19; + dofs[9] = 20; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + dofs[5] = 15; + dofs[6] = 17; + dofs[7] = 21; + dofs[8] = 22; + dofs[9] = 23; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + dofs[5] = 15; + dofs[6] = 16; + dofs[7] = 24; + dofs[8] = 25; + dofs[9] = 26; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 15; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 16; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 17; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + dofs[3] = 18; + dofs[4] = 19; + dofs[5] = 20; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + dofs[3] = 21; + dofs[4] = 22; + dofs[5] = 23; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + dofs[3] = 24; + dofs[4] = 25; + dofs[5] = 26; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + dofs[3] = 27; + dofs[4] = 28; + dofs[5] = 29; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + coordinates[15][0] = x[0][0]; + coordinates[15][1] = x[0][1]; + coordinates[16][0] = x[1][0]; + coordinates[16][1] = x[1][1]; + coordinates[17][0] = x[2][0]; + coordinates[17][1] = x[2][1]; + coordinates[18][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[18][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[19][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[19][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[20][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[20][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[21][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[21][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[22][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[22][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[23][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[23][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[24][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[24][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[25][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[25][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[26][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[26][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[27][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[27][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[28][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[28][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[29][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[29][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p2_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 240 + // Number of operations (multiply-add pairs) for tensor contraction: 9723 + // Total number of operations (multiply-add pairs): 9974 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0 = det*(w[0][3]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1 = det*(w[0][3]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0 = det*(w[0][4]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1 = det*(w[0][4]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0 = det*(w[0][5]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1 = det*(w[0][5]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0 = det*(w[0][6]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1 = det*(w[0][6]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0 = det*(w[0][7]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1 = det*(w[0][8]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0 = det*(w[0][9]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1 = det*(w[0][9]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0 = det*(w[0][10]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1 = det*(w[0][10]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0 = det*(w[0][11]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1 = det*(w[0][11]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0 = det*(w[0][3]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1 = det*(w[0][3]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0 = det*(w[0][4]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1 = det*(w[0][4]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0 = det*(w[0][5]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1 = det*(w[0][5]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0 = det*(w[0][6]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1 = det*(w[0][6]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0 = det*(w[0][7]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1 = det*(w[0][8]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0 = det*(w[0][9]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1 = det*(w[0][9]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0 = det*(w[0][10]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1 = det*(w[0][10]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0 = det*(w[0][11]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1 = det*(w[0][11]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0 = det*(w[0][3]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1 = det*(w[0][3]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0 = det*(w[0][4]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1 = det*(w[0][4]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0 = det*(w[0][5]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1 = det*(w[0][5]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0 = det*(w[0][6]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1 = det*(w[0][6]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0 = det*(w[0][7]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1 = det*(w[0][8]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0 = det*(w[0][9]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1 = det*(w[0][9]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0 = det*(w[0][10]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1 = det*(w[0][10]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0 = det*(w[0][11]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1 = det*(w[0][11]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0 = det*(w[0][3]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1 = det*(w[0][3]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0 = det*(w[0][4]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1 = det*(w[0][4]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0 = det*(w[0][5]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1 = det*(w[0][5]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0 = det*(w[0][6]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1 = det*(w[0][6]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0 = det*(w[0][7]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1 = det*(w[0][8]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0 = det*(w[0][9]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1 = det*(w[0][9]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0 = det*(w[0][10]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1 = det*(w[0][10]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0 = det*(w[0][11]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1 = det*(w[0][11]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[213] = 0.186243386243386*G0_0_0_0_0_0 + 0.186243386243386*G0_0_0_0_0_1 + 0.22010582010582*G0_0_0_1_0_0 - 0.186243386243385*G0_0_0_2_0_1 - 0.338624338624336*G0_0_0_3_0_0 + 0.0677248677248692*G0_0_0_3_0_1 + 0.338624338624336*G0_0_0_4_0_0 - 0.406349206349206*G0_0_0_5_0_0 - 0.0677248677248692*G0_0_0_5_0_1 + 0.186243386243386*G0_0_0_6_1_0 + 0.186243386243386*G0_0_0_6_1_1 + 0.22010582010582*G0_0_0_7_1_0 - 0.186243386243385*G0_0_0_8_1_1 - 0.338624338624336*G0_0_0_9_1_0 + 0.0677248677248692*G0_0_0_9_1_1 + 0.338624338624336*G0_0_0_10_1_0 - 0.406349206349206*G0_0_0_11_1_0 - 0.0677248677248692*G0_0_0_11_1_1 + 0.0141093474426797*G0_0_1_0_0_0 + 0.0141093474426797*G0_0_1_0_0_1 - 0.00282186948853863*G0_0_1_1_0_0 - 0.0253968253968252*G0_0_1_2_0_1 - 0.0677248677248688*G0_0_1_3_0_0 - 0.0451499118165822*G0_0_1_3_0_1 + 0.0677248677248688*G0_0_1_4_0_0 + 0.0112874779541455*G0_0_1_4_0_1 - 0.0112874779541411*G0_0_1_5_0_0 + 0.0451499118165822*G0_0_1_5_0_1 + 0.0141093474426797*G0_0_1_6_1_0 + 0.0141093474426797*G0_0_1_6_1_1 - 0.00282186948853863*G0_0_1_7_1_0 - 0.0253968253968252*G0_0_1_8_1_1 - 0.0677248677248688*G0_0_1_9_1_0 - 0.0451499118165822*G0_0_1_9_1_1 + 0.0677248677248688*G0_0_1_10_1_0 + 0.0112874779541455*G0_0_1_10_1_1 - 0.0112874779541411*G0_0_1_11_1_0 + 0.0451499118165822*G0_0_1_11_1_1 - 0.0423280423280418*G0_1_0_0_0_0 - 0.0423280423280417*G0_1_0_0_0_1 + 0.00846560846560771*G0_1_0_1_0_0 - 0.0931216931216923*G0_1_0_2_0_1 - 0.135449735449735*G0_1_0_3_0_0 - 0.0338624338624351*G0_1_0_3_0_1 + 0.135449735449735*G0_1_0_4_0_0 + 0.135449735449734*G0_1_0_4_0_1 + 0.0338624338624341*G0_1_0_5_0_0 + 0.0338624338624351*G0_1_0_5_0_1 - 0.0423280423280418*G0_1_0_6_1_0 - 0.0423280423280417*G0_1_0_6_1_1 + 0.00846560846560771*G0_1_0_7_1_0 - 0.0931216931216923*G0_1_0_8_1_1 - 0.135449735449735*G0_1_0_9_1_0 - 0.0338624338624351*G0_1_0_9_1_1 + 0.135449735449735*G0_1_0_10_1_0 + 0.135449735449734*G0_1_0_10_1_1 + 0.0338624338624341*G0_1_0_11_1_0 + 0.0338624338624351*G0_1_0_11_1_1 - 0.0112874779541456*G0_1_1_0_0_0 - 0.0112874779541456*G0_1_1_0_0_1 - 0.0112874779541436*G0_1_1_2_0_1 - 0.0112874779541457*G0_1_1_3_0_0 + 0.0112874779541457*G0_1_1_4_0_0 + 0.0225749559082892*G0_1_1_4_0_1 + 0.0112874779541495*G0_1_1_5_0_0 - 0.0112874779541456*G0_1_1_6_1_0 - 0.0112874779541456*G0_1_1_6_1_1 - 0.0112874779541436*G0_1_1_8_1_1 - 0.0112874779541457*G0_1_1_9_1_0 + 0.0112874779541457*G0_1_1_10_1_0 + 0.0225749559082892*G0_1_1_10_1_1 + 0.0112874779541495*G0_1_1_11_1_0; + A[489] = 0.0; + A[208] = 0.0; + A[574] = 0.0; + A[530] = 0.595414462081129*G0_1_0_0_0_0 + 0.595414462081129*G0_1_0_0_0_1 - 0.595414462081129*G0_1_0_1_0_0 + 1.96966490299824*G0_1_0_2_0_1 + 2.74850088183421*G0_1_0_3_0_0 + 0.183421516754849*G0_1_0_3_0_1 - 2.74850088183421*G0_1_0_4_0_0 - 2.56507936507936*G0_1_0_4_0_1 - 0.18342151675485*G0_1_0_5_0_1 + 0.595414462081129*G0_1_0_6_1_0 + 0.595414462081129*G0_1_0_6_1_1 - 0.595414462081129*G0_1_0_7_1_0 + 1.96966490299824*G0_1_0_8_1_1 + 2.74850088183421*G0_1_0_9_1_0 + 0.183421516754849*G0_1_0_9_1_1 - 2.74850088183421*G0_1_0_10_1_0 - 2.56507936507936*G0_1_0_10_1_1 - 0.18342151675485*G0_1_0_11_1_1 + 0.225749559082893*G0_1_1_0_0_0 + 0.225749559082892*G0_1_1_0_0_1 - 0.324514991181658*G0_1_1_1_0_0 + 0.677248677248677*G0_1_1_2_0_1 + 0.804232804232804*G0_1_1_3_0_0 - 0.197530864197531*G0_1_1_3_0_1 - 0.804232804232804*G0_1_1_4_0_0 - 0.90299823633157*G0_1_1_4_0_1 + 0.0987654320987656*G0_1_1_5_0_0 + 0.197530864197531*G0_1_1_5_0_1 + 0.225749559082893*G0_1_1_6_1_0 + 0.225749559082892*G0_1_1_6_1_1 - 0.324514991181658*G0_1_1_7_1_0 + 0.677248677248677*G0_1_1_8_1_1 + 0.804232804232804*G0_1_1_9_1_0 - 0.197530864197531*G0_1_1_9_1_1 - 0.804232804232804*G0_1_1_10_1_0 - 0.90299823633157*G0_1_1_10_1_1 + 0.0987654320987656*G0_1_1_11_1_0 + 0.197530864197531*G0_1_1_11_1_1; + A[235] = 0.0; + A[607] = 0.0; + A[716] = 0.0451499118165783*G0_0_0_0_0_0 + 0.0451499118165783*G0_0_0_0_0_1 + 0.045149911816578*G0_0_0_1_0_0 + 0.0451499118165781*G0_0_0_3_0_1 - 0.0451499118165788*G0_0_0_4_0_1 - 0.0902998236331563*G0_0_0_5_0_0 - 0.0451499118165782*G0_0_0_5_0_1 + 0.0451499118165783*G0_0_0_6_1_0 + 0.0451499118165783*G0_0_0_6_1_1 + 0.045149911816578*G0_0_0_7_1_0 + 0.0451499118165781*G0_0_0_9_1_1 - 0.0451499118165788*G0_0_0_10_1_1 - 0.0902998236331563*G0_0_0_11_1_0 - 0.0451499118165782*G0_0_0_11_1_1 + 0.0564373897707227*G0_0_1_0_0_0 + 0.0564373897707227*G0_0_1_0_0_1 + 0.0790123456790109*G0_0_1_1_0_0 + 0.0790123456790124*G0_0_1_2_0_1 + 0.180599647266313*G0_0_1_3_0_0 + 0.180599647266312*G0_0_1_3_0_1 - 0.180599647266313*G0_0_1_4_0_0 - 0.135449735449735*G0_0_1_4_0_1 - 0.135449735449734*G0_0_1_5_0_0 - 0.180599647266312*G0_0_1_5_0_1 + 0.0564373897707227*G0_0_1_6_1_0 + 0.0564373897707227*G0_0_1_6_1_1 + 0.0790123456790109*G0_0_1_7_1_0 + 0.0790123456790124*G0_0_1_8_1_1 + 0.180599647266313*G0_0_1_9_1_0 + 0.180599647266312*G0_0_1_9_1_1 - 0.180599647266313*G0_0_1_10_1_0 - 0.135449735449735*G0_0_1_10_1_1 - 0.135449735449734*G0_0_1_11_1_0 - 0.180599647266312*G0_0_1_11_1_1 - 0.0338624338624349*G0_1_0_0_0_0 - 0.033862433862435*G0_1_0_0_0_1 + 0.033862433862432*G0_1_0_1_0_0 + 0.0338624338624339*G0_1_0_2_0_1 + 0.135449735449735*G0_1_0_3_0_0 + 0.135449735449733*G0_1_0_3_0_1 - 0.135449735449735*G0_1_0_4_0_0 - 0.135449735449733*G0_1_0_5_0_1 - 0.0338624338624349*G0_1_0_6_1_0 - 0.033862433862435*G0_1_0_6_1_1 + 0.033862433862432*G0_1_0_7_1_0 + 0.0338624338624339*G0_1_0_8_1_1 + 0.135449735449735*G0_1_0_9_1_0 + 0.135449735449733*G0_1_0_9_1_1 - 0.135449735449735*G0_1_0_10_1_0 - 0.135449735449733*G0_1_0_11_1_1 + 0.0451499118165779*G0_1_1_0_0_0 + 0.0451499118165779*G0_1_1_0_0_1 + 0.0451499118165799*G0_1_1_2_0_1 + 0.0451499118165785*G0_1_1_3_0_0 - 0.0451499118165785*G0_1_1_4_0_0 - 0.0902998236331578*G0_1_1_4_0_1 - 0.0451499118165746*G0_1_1_5_0_0 + 0.0451499118165779*G0_1_1_6_1_0 + 0.0451499118165779*G0_1_1_6_1_1 + 0.0451499118165799*G0_1_1_8_1_1 + 0.0451499118165785*G0_1_1_9_1_0 - 0.0451499118165785*G0_1_1_10_1_0 - 0.0902998236331578*G0_1_1_10_1_1 - 0.0451499118165746*G0_1_1_11_1_0; + A[625] = -A[716] + 0.0338624338624332*G0_0_0_0_0_0 + 0.0338624338624332*G0_0_0_0_0_1 + 0.0338624338624341*G0_0_0_1_0_0 + 0.0338624338624336*G0_0_0_3_0_1 - 0.0338624338624319*G0_0_0_4_0_1 - 0.0677248677248673*G0_0_0_5_0_0 - 0.0338624338624336*G0_0_0_5_0_1 + 0.0338624338624332*G0_0_0_6_1_0 + 0.0338624338624332*G0_0_0_6_1_1 + 0.0338624338624341*G0_0_0_7_1_0 + 0.0338624338624336*G0_0_0_9_1_1 - 0.0338624338624319*G0_0_0_10_1_1 - 0.0677248677248673*G0_0_0_11_1_0 - 0.0338624338624336*G0_0_0_11_1_1 + 0.0705467372134035*G0_0_1_0_0_0 + 0.0705467372134035*G0_0_1_0_0_1 + 0.0536155202821857*G0_0_1_1_0_0 + 0.0761904761904771*G0_0_1_2_0_1 + 0.135449735449736*G0_0_1_3_0_0 + 0.112874779541445*G0_0_1_3_0_1 - 0.135449735449736*G0_0_1_4_0_0 - 0.146737213403881*G0_0_1_4_0_1 - 0.124162257495589*G0_0_1_5_0_0 - 0.112874779541445*G0_0_1_5_0_1 + 0.0705467372134035*G0_0_1_6_1_0 + 0.0705467372134035*G0_0_1_6_1_1 + 0.0536155202821857*G0_0_1_7_1_0 + 0.0761904761904771*G0_0_1_8_1_1 + 0.135449735449736*G0_0_1_9_1_0 + 0.112874779541445*G0_0_1_9_1_1 - 0.135449735449736*G0_0_1_10_1_0 - 0.146737213403881*G0_0_1_10_1_1 - 0.124162257495589*G0_0_1_11_1_0 - 0.112874779541445*G0_0_1_11_1_1 - 0.0761904761904769*G0_1_0_0_0_0 - 0.0761904761904769*G0_1_0_0_0_1 - 0.0592592592592593*G0_1_0_1_0_0 + 0.042328042328041*G0_1_0_2_0_1 + 0.1015873015873*G0_1_0_3_0_0 - 0.1015873015873*G0_1_0_4_0_0 + 0.0338624338624358*G0_1_0_4_0_1 + 0.135449735449736*G0_1_0_5_0_0 - 0.0761904761904769*G0_1_0_6_1_0 - 0.0761904761904769*G0_1_0_6_1_1 - 0.0592592592592593*G0_1_0_7_1_0 + 0.042328042328041*G0_1_0_8_1_1 + 0.1015873015873*G0_1_0_9_1_0 - 0.1015873015873*G0_1_0_10_1_0 + 0.0338624338624358*G0_1_0_10_1_1 + 0.135449735449736*G0_1_0_11_1_0 + 0.231393298059965*G0_1_1_0_0_0 + 0.231393298059965*G0_1_1_0_0_1 - 0.186243386243388*G0_1_1_1_0_0 + 0.2652557319224*G0_1_1_2_0_1 + 0.112874779541447*G0_1_1_3_0_0 - 0.338624338624341*G0_1_1_3_0_1 - 0.112874779541447*G0_1_1_4_0_0 - 0.496649029982364*G0_1_1_4_0_1 - 0.0451499118165765*G0_1_1_5_0_0 + 0.338624338624341*G0_1_1_5_0_1 + 0.231393298059965*G0_1_1_6_1_0 + 0.231393298059965*G0_1_1_6_1_1 - 0.186243386243388*G0_1_1_7_1_0 + 0.2652557319224*G0_1_1_8_1_1 + 0.112874779541447*G0_1_1_9_1_0 - 0.338624338624341*G0_1_1_9_1_1 - 0.112874779541447*G0_1_1_10_1_0 - 0.496649029982364*G0_1_1_10_1_1 - 0.0451499118165765*G0_1_1_11_1_0 + 0.338624338624341*G0_1_1_11_1_1; + A[636] = 0.0; + A[270] = A[530] + 1.29241622574956*G0_0_0_0_0_0 + 1.29241622574956*G0_0_0_0_0_1 + 0.270899470899471*G0_0_0_1_0_0 + 0.369664902998237*G0_0_0_2_0_1 - 0.282186948853614*G0_0_0_3_0_0 - 0.38095238095238*G0_0_0_3_0_1 + 0.282186948853614*G0_0_0_4_0_0 - 1.6620811287478*G0_0_0_4_0_1 - 1.56331569664903*G0_0_0_5_0_0 + 0.380952380952381*G0_0_0_5_0_1 + 1.29241622574956*G0_0_0_6_1_0 + 1.29241622574956*G0_0_0_6_1_1 + 0.270899470899471*G0_0_0_7_1_0 + 0.369664902998237*G0_0_0_8_1_1 - 0.282186948853614*G0_0_0_9_1_0 - 0.38095238095238*G0_0_0_9_1_1 + 0.282186948853614*G0_0_0_10_1_0 - 1.6620811287478*G0_0_0_10_1_1 - 1.56331569664903*G0_0_0_11_1_0 + 0.380952380952381*G0_0_0_11_1_1 + 1.29241622574956*G0_0_1_0_0_0 + 1.29241622574956*G0_0_1_0_0_1 + 0.270899470899471*G0_0_1_1_0_0 + 0.369664902998236*G0_0_1_2_0_1 - 0.282186948853614*G0_0_1_3_0_0 - 0.38095238095238*G0_0_1_3_0_1 + 0.282186948853614*G0_0_1_4_0_0 - 1.6620811287478*G0_0_1_4_0_1 - 1.56331569664903*G0_0_1_5_0_0 + 0.38095238095238*G0_0_1_5_0_1 + 1.29241622574956*G0_0_1_6_1_0 + 1.29241622574956*G0_0_1_6_1_1 + 0.270899470899471*G0_0_1_7_1_0 + 0.369664902998236*G0_0_1_8_1_1 - 0.282186948853614*G0_0_1_9_1_0 - 0.38095238095238*G0_0_1_9_1_1 + 0.282186948853614*G0_0_1_10_1_0 - 1.6620811287478*G0_0_1_10_1_1 - 1.56331569664903*G0_0_1_11_1_0 + 0.38095238095238*G0_0_1_11_1_1 - 1.27266313932981*G0_1_0_0_0_0 - 1.2726631393298*G0_1_0_0_0_1 + 0.270899470899472*G0_1_0_1_0_0 - 2.19541446208113*G0_1_0_2_0_1 - 2.84726631393298*G0_1_0_3_0_0 - 0.38095238095238*G0_1_0_3_0_1 + 2.84726631393298*G0_1_0_4_0_0 + 3.46807760141093*G0_1_0_4_0_1 + 1.00176366843033*G0_1_0_5_0_0 + 0.38095238095238*G0_1_0_5_0_1 - 1.27266313932981*G0_1_0_6_1_0 - 1.2726631393298*G0_1_0_6_1_1 + 0.270899470899472*G0_1_0_7_1_0 - 2.19541446208113*G0_1_0_8_1_1 - 2.84726631393298*G0_1_0_9_1_0 - 0.38095238095238*G0_1_0_9_1_1 + 2.84726631393298*G0_1_0_10_1_0 + 3.46807760141093*G0_1_0_10_1_1 + 1.00176366843033*G0_1_0_11_1_0 + 0.38095238095238*G0_1_0_11_1_1 - 0.902998236331568*G0_1_1_0_0_0 - 0.902998236331568*G0_1_1_0_0_1 - 0.90299823633157*G0_1_1_2_0_1 - 0.90299823633157*G0_1_1_3_0_0 + 0.90299823633157*G0_1_1_4_0_0 + 1.80599647266314*G0_1_1_4_0_1 + 0.902998236331567*G0_1_1_5_0_0 - 0.902998236331568*G0_1_1_6_1_0 - 0.902998236331568*G0_1_1_6_1_1 - 0.90299823633157*G0_1_1_8_1_1 - 0.90299823633157*G0_1_1_9_1_0 + 0.90299823633157*G0_1_1_10_1_0 + 1.80599647266314*G0_1_1_10_1_1 + 0.902998236331567*G0_1_1_11_1_0; + A[352] = 0.0; + A[17] = 0.0; + A[734] = 0.0; + A[421] = 0.090299823633157*G0_0_0_0_0_0 + 0.0902998236331571*G0_0_0_0_0_1 + 0.395061728395061*G0_0_0_1_0_0 - 0.389417989417988*G0_0_0_2_0_1 - 0.474074074074072*G0_0_0_3_0_0 + 0.310405643738977*G0_0_0_3_0_1 + 0.474074074074072*G0_0_0_4_0_0 + 0.299118165784831*G0_0_0_4_0_1 - 0.485361552028218*G0_0_0_5_0_0 - 0.310405643738977*G0_0_0_5_0_1 + 0.090299823633157*G0_0_0_6_1_0 + 0.0902998236331571*G0_0_0_6_1_1 + 0.395061728395061*G0_0_0_7_1_0 - 0.389417989417988*G0_0_0_8_1_1 - 0.474074074074072*G0_0_0_9_1_0 + 0.310405643738977*G0_0_0_9_1_1 + 0.474074074074072*G0_0_0_10_1_0 + 0.299118165784831*G0_0_0_10_1_1 - 0.485361552028218*G0_0_0_11_1_0 - 0.310405643738977*G0_0_0_11_1_1 - 0.0282186948853618*G0_1_0_0_0_0 - 0.0282186948853618*G0_1_0_0_0_1 - 0.028218694885361*G0_1_0_2_0_1 - 0.0282186948853613*G0_1_0_3_0_0 + 0.0282186948853613*G0_1_0_4_0_0 + 0.0564373897707229*G0_1_0_4_0_1 + 0.0282186948853628*G0_1_0_5_0_0 - 0.0282186948853618*G0_1_0_6_1_0 - 0.0282186948853618*G0_1_0_6_1_1 - 0.028218694885361*G0_1_0_8_1_1 - 0.0282186948853613*G0_1_0_9_1_0 + 0.0282186948853613*G0_1_0_10_1_0 + 0.0564373897707229*G0_1_0_10_1_1 + 0.0282186948853628*G0_1_0_11_1_0; + A[377] = 0.0; + A[58] = 0.0; + A[454] = 0.0; + A[410] = 0.0; + A[87] = 0.0; + A[792] = 0.0; + A[887] = -0.0282186948853634*G0_0_1_0_0_0 - 0.0282186948853635*G0_0_1_0_0_1 - 0.0282186948853606*G0_0_1_1_0_0 - 0.0282186948853628*G0_0_1_3_0_1 + 0.0282186948853685*G0_0_1_4_0_1 + 0.056437389770724*G0_0_1_5_0_0 + 0.0282186948853628*G0_0_1_5_0_1 - 0.0282186948853634*G0_0_1_6_1_0 - 0.0282186948853635*G0_0_1_6_1_1 - 0.0282186948853606*G0_0_1_7_1_0 - 0.0282186948853628*G0_0_1_9_1_1 + 0.0282186948853685*G0_0_1_10_1_1 + 0.056437389770724*G0_0_1_11_1_0 + 0.0282186948853628*G0_0_1_11_1_1 - 0.451499118165786*G0_1_1_0_0_0 - 0.451499118165785*G0_1_1_0_0_1 + 0.423280423280424*G0_1_1_1_0_0 - 0.959435626102294*G0_1_1_2_0_1 - 1.04409171075838*G0_1_1_3_0_0 + 0.338624338624338*G0_1_1_3_0_1 + 1.04409171075838*G0_1_1_4_0_0 + 1.41093474426808*G0_1_1_4_0_1 + 0.028218694885362*G0_1_1_5_0_0 - 0.338624338624338*G0_1_1_5_0_1 - 0.451499118165786*G0_1_1_6_1_0 - 0.451499118165785*G0_1_1_6_1_1 + 0.423280423280424*G0_1_1_7_1_0 - 0.959435626102294*G0_1_1_8_1_1 - 1.04409171075838*G0_1_1_9_1_0 + 0.338624338624338*G0_1_1_9_1_1 + 1.04409171075838*G0_1_1_10_1_0 + 1.41093474426808*G0_1_1_10_1_1 + 0.028218694885362*G0_1_1_11_1_0 - 0.338624338624338*G0_1_1_11_1_1; + A[811] = 0.0; + A[850] = 0.0; + A[174] = 0.0; + A[881] = 0.0; + A[480] = 0.0; + A[203] = 0.0; + A[583] = 0.0; + A[523] = 0.0; + A[232] = 0.0; + A[614] = 0.0; + A[550] = 0.0; + A[672] = 0.0; + A[699] = 0.0; + A[258] = 0.0; + A[345] = 0.0; + A[289] = 0.0; + A[51] = 0.0; + A[766] = 0.00564373897707244*G0_0_0_0_0_0 + 0.00564373897707264*G0_0_0_0_0_1 + 0.729453262786597*G0_0_0_1_0_0 - 0.256084656084656*G0_0_0_2_0_1 + 0.211640211640211*G0_0_0_3_0_0 + 1.19717813051146*G0_0_0_3_0_1 - 0.211640211640211*G0_0_0_4_0_0 + 0.250440917107584*G0_0_0_4_0_1 - 0.735097001763669*G0_0_0_5_0_0 - 1.19717813051146*G0_0_0_5_0_1 + 0.00564373897707244*G0_0_0_6_1_0 + 0.00564373897707264*G0_0_0_6_1_1 + 0.729453262786597*G0_0_0_7_1_0 - 0.256084656084656*G0_0_0_8_1_1 + 0.211640211640211*G0_0_0_9_1_0 + 1.19717813051146*G0_0_0_9_1_1 - 0.211640211640211*G0_0_0_10_1_0 + 0.250440917107584*G0_0_0_10_1_1 - 0.735097001763669*G0_0_0_11_1_0 - 1.19717813051146*G0_0_0_11_1_1 + 0.323104056437389*G0_1_0_0_0_0 + 0.323104056437389*G0_1_0_0_0_1 + 1.04338624338624*G0_1_0_1_0_0 - 0.294885361552028*G0_1_0_2_0_1 + 0.130511463844796*G0_1_0_3_0_0 + 1.46878306878307*G0_1_0_3_0_1 - 0.130511463844796*G0_1_0_4_0_0 - 0.0282186948853607*G0_1_0_4_0_1 - 1.36649029982363*G0_1_0_5_0_0 - 1.46878306878307*G0_1_0_5_0_1 + 0.323104056437389*G0_1_0_6_1_0 + 0.323104056437389*G0_1_0_6_1_1 + 1.04338624338624*G0_1_0_7_1_0 - 0.294885361552028*G0_1_0_8_1_1 + 0.130511463844796*G0_1_0_9_1_0 + 1.46878306878307*G0_1_0_9_1_1 - 0.130511463844796*G0_1_0_10_1_0 - 0.0282186948853607*G0_1_0_10_1_1 - 1.36649029982363*G0_1_0_11_1_0 - 1.46878306878307*G0_1_0_11_1_1; + A[765] = A[766] - 0.735097001763669*G0_0_0_0_0_0 - 0.735097001763669*G0_0_0_0_0_1 - 0.735097001763669*G0_0_0_1_0_0 - 0.735097001763669*G0_0_0_3_0_1 + 0.735097001763669*G0_0_0_4_0_1 + 1.47019400352734*G0_0_0_5_0_0 + 0.735097001763669*G0_0_0_5_0_1 - 0.735097001763669*G0_0_0_6_1_0 - 0.735097001763669*G0_0_0_6_1_1 - 0.735097001763669*G0_0_0_7_1_0 - 0.735097001763669*G0_0_0_9_1_1 + 0.735097001763669*G0_0_0_10_1_1 + 1.47019400352734*G0_0_0_11_1_0 + 0.735097001763669*G0_0_0_11_1_1 - 0.729453262786597*G0_0_1_0_0_0 - 0.729453262786597*G0_0_1_0_0_1 - 0.00564373897707268*G0_0_1_1_0_0 - 0.256084656084656*G0_0_1_2_0_1 + 0.211640211640211*G0_0_1_3_0_0 + 0.462081128747795*G0_0_1_3_0_1 - 0.211640211640211*G0_0_1_4_0_0 + 0.985537918871253*G0_0_1_4_0_1 + 0.735097001763669*G0_0_1_5_0_0 - 0.462081128747795*G0_0_1_5_0_1 - 0.729453262786597*G0_0_1_6_1_0 - 0.729453262786597*G0_0_1_6_1_1 - 0.00564373897707268*G0_0_1_7_1_0 - 0.256084656084656*G0_0_1_8_1_1 + 0.211640211640211*G0_0_1_9_1_0 + 0.462081128747795*G0_0_1_9_1_1 - 0.211640211640211*G0_0_1_10_1_0 + 0.985537918871253*G0_0_1_10_1_1 + 0.735097001763669*G0_0_1_11_1_0 - 0.462081128747795*G0_0_1_11_1_1 - 0.00917107583774357*G0_1_0_0_0_0 - 0.00917107583774379*G0_1_0_0_0_1 - 0.725925925925926*G0_1_0_1_0_0 + 0.3336860670194*G0_1_0_2_0_1 - 0.049382716049382*G0_1_0_3_0_0 - 1.10899470899471*G0_1_0_3_0_1 + 0.049382716049382*G0_1_0_4_0_0 - 0.324514991181656*G0_1_0_4_0_1 + 0.735097001763669*G0_1_0_5_0_0 + 1.10899470899471*G0_1_0_5_0_1 - 0.00917107583774357*G0_1_0_6_1_0 - 0.00917107583774379*G0_1_0_6_1_1 - 0.725925925925926*G0_1_0_7_1_0 + 0.3336860670194*G0_1_0_8_1_1 - 0.049382716049382*G0_1_0_9_1_0 - 1.10899470899471*G0_1_0_9_1_1 + 0.049382716049382*G0_1_0_10_1_0 - 0.324514991181656*G0_1_0_10_1_1 + 0.735097001763669*G0_1_0_11_1_0 + 1.10899470899471*G0_1_0_11_1_1 + 0.313932980599645*G0_1_1_0_0_0 + 0.313932980599645*G0_1_1_0_0_1 + 0.317460317460316*G0_1_1_1_0_0 + 0.0388007054673716*G0_1_1_2_0_1 + 0.0811287477954141*G0_1_1_3_0_0 + 0.359788359788359*G0_1_1_3_0_1 - 0.0811287477954141*G0_1_1_4_0_0 - 0.352733686067017*G0_1_1_4_0_1 - 0.631393298059962*G0_1_1_5_0_0 - 0.359788359788359*G0_1_1_5_0_1 + 0.313932980599645*G0_1_1_6_1_0 + 0.313932980599645*G0_1_1_6_1_1 + 0.317460317460316*G0_1_1_7_1_0 + 0.0388007054673716*G0_1_1_8_1_1 + 0.0811287477954141*G0_1_1_9_1_0 + 0.359788359788359*G0_1_1_9_1_1 - 0.0811287477954141*G0_1_1_10_1_0 - 0.352733686067017*G0_1_1_10_1_1 - 0.631393298059962*G0_1_1_11_1_0 - 0.359788359788359*G0_1_1_11_1_1; + A[463] = 0.0; + A[78] = 0.0; + A[803] = A[716] - 0.0902998236331576*G0_0_1_0_0_0 - 0.0902998236331576*G0_0_1_0_0_1 - 0.0451499118165789*G0_0_1_1_0_0 - 0.0451499118165785*G0_0_1_2_0_1 - 0.0451499118165783*G0_0_1_3_0_0 - 0.0451499118165788*G0_0_1_3_0_1 + 0.0451499118165783*G0_0_1_4_0_0 + 0.135449735449736*G0_0_1_4_0_1 + 0.135449735449737*G0_0_1_5_0_0 + 0.0451499118165788*G0_0_1_5_0_1 - 0.0902998236331576*G0_0_1_6_1_0 - 0.0902998236331576*G0_0_1_6_1_1 - 0.0451499118165789*G0_0_1_7_1_0 - 0.0451499118165785*G0_0_1_8_1_1 - 0.0451499118165783*G0_0_1_9_1_0 - 0.0451499118165788*G0_0_1_9_1_1 + 0.0451499118165783*G0_0_1_10_1_0 + 0.135449735449736*G0_0_1_10_1_1 + 0.135449735449737*G0_0_1_11_1_0 + 0.0451499118165788*G0_0_1_11_1_1 + 0.0902998236331576*G0_1_0_0_0_0 + 0.0902998236331577*G0_1_0_0_0_1 + 0.045149911816579*G0_1_0_1_0_0 + 0.0451499118165785*G0_1_0_2_0_1 + 0.0451499118165784*G0_1_0_3_0_0 + 0.0451499118165788*G0_1_0_3_0_1 - 0.0451499118165784*G0_1_0_4_0_0 - 0.135449735449736*G0_1_0_4_0_1 - 0.135449735449737*G0_1_0_5_0_0 - 0.0451499118165789*G0_1_0_5_0_1 + 0.0902998236331576*G0_1_0_6_1_0 + 0.0902998236331577*G0_1_0_6_1_1 + 0.045149911816579*G0_1_0_7_1_0 + 0.0451499118165785*G0_1_0_8_1_1 + 0.0451499118165784*G0_1_0_9_1_0 + 0.0451499118165788*G0_1_0_9_1_1 - 0.0451499118165784*G0_1_0_10_1_0 - 0.135449735449736*G0_1_0_10_1_1 - 0.135449735449737*G0_1_0_11_1_0 - 0.0451499118165789*G0_1_0_11_1_1; + A[14] = A[421] - 0.48536155202822*G0_0_0_0_0_0 - 0.48536155202822*G0_0_0_0_0_1 - 0.485361552028219*G0_0_0_1_0_0 - 0.485361552028218*G0_0_0_3_0_1 + 0.485361552028221*G0_0_0_4_0_1 + 0.970723104056438*G0_0_0_5_0_0 + 0.485361552028218*G0_0_0_5_0_1 - 0.48536155202822*G0_0_0_6_1_0 - 0.48536155202822*G0_0_0_6_1_1 - 0.485361552028219*G0_0_0_7_1_0 - 0.485361552028218*G0_0_0_9_1_1 + 0.485361552028221*G0_0_0_10_1_1 + 0.970723104056438*G0_0_0_11_1_0 + 0.485361552028218*G0_0_0_11_1_1 - 0.395061728395064*G0_0_1_0_0_0 - 0.395061728395064*G0_0_1_0_0_1 - 0.118518518518519*G0_0_1_1_0_0 - 0.361199294532628*G0_0_1_2_0_1 - 0.445855379188712*G0_0_1_3_0_0 - 0.203174603174603*G0_0_1_3_0_1 + 0.445855379188712*G0_0_1_4_0_0 + 0.756261022927692*G0_0_1_4_0_1 + 0.513580246913583*G0_0_1_5_0_0 + 0.203174603174603*G0_0_1_5_0_1 - 0.395061728395064*G0_0_1_6_1_0 - 0.395061728395064*G0_0_1_6_1_1 - 0.118518518518519*G0_0_1_7_1_0 - 0.361199294532628*G0_0_1_8_1_1 - 0.445855379188712*G0_0_1_9_1_0 - 0.203174603174603*G0_0_1_9_1_1 + 0.445855379188712*G0_0_1_10_1_0 + 0.756261022927692*G0_0_1_10_1_1 + 0.513580246913583*G0_0_1_11_1_0 + 0.203174603174603*G0_0_1_11_1_1 - 0.366843033509701*G0_1_0_0_0_0 - 0.366843033509701*G0_1_0_0_0_1 - 0.090299823633156*G0_1_0_1_0_0 - 0.361199294532629*G0_1_0_2_0_1 - 0.445855379188712*G0_1_0_3_0_0 - 0.17495590828924*G0_1_0_3_0_1 + 0.445855379188712*G0_1_0_4_0_0 + 0.728042328042329*G0_1_0_4_0_1 + 0.457142857142857*G0_1_0_5_0_0 + 0.17495590828924*G0_1_0_5_0_1 - 0.366843033509701*G0_1_0_6_1_0 - 0.366843033509701*G0_1_0_6_1_1 - 0.090299823633156*G0_1_0_7_1_0 - 0.361199294532629*G0_1_0_8_1_1 - 0.445855379188712*G0_1_0_9_1_0 - 0.17495590828924*G0_1_0_9_1_1 + 0.445855379188712*G0_1_0_10_1_0 + 0.728042328042329*G0_1_0_10_1_1 + 0.457142857142857*G0_1_0_11_1_0 + 0.17495590828924*G0_1_0_11_1_1 - 0.395061728395064*G0_1_1_0_0_0 - 0.395061728395064*G0_1_1_0_0_1 - 0.118518518518519*G0_1_1_1_0_0 - 0.361199294532629*G0_1_1_2_0_1 - 0.445855379188712*G0_1_1_3_0_0 - 0.203174603174602*G0_1_1_3_0_1 + 0.445855379188712*G0_1_1_4_0_0 + 0.756261022927692*G0_1_1_4_0_1 + 0.513580246913583*G0_1_1_5_0_0 + 0.203174603174602*G0_1_1_5_0_1 - 0.395061728395064*G0_1_1_6_1_0 - 0.395061728395064*G0_1_1_6_1_1 - 0.118518518518519*G0_1_1_7_1_0 - 0.361199294532629*G0_1_1_8_1_1 - 0.445855379188712*G0_1_1_9_1_0 - 0.203174603174602*G0_1_1_9_1_1 + 0.445855379188712*G0_1_1_10_1_0 + 0.756261022927692*G0_1_1_10_1_1 + 0.513580246913583*G0_1_1_11_1_0 + 0.203174603174602*G0_1_1_11_1_1; + A[816] = 0.0; + A[45] = 0.0; + A[841] = 0.0; + A[874] = 0.0; + A[107] = 0.0; + A[487] = 0.0; + A[516] = 0.0; + A[225] = 0.0; + A[545] = 0.0; + A[509] = A[421] - 0.0282186948853621*G0_0_1_0_0_0 - 0.028218694885362*G0_0_1_0_0_1 - 0.0282186948853611*G0_0_1_2_0_1 - 0.0282186948853614*G0_0_1_3_0_0 + 0.0282186948853614*G0_0_1_4_0_0 + 0.0564373897707231*G0_0_1_4_0_1 + 0.0282186948853634*G0_0_1_5_0_0 - 0.0282186948853621*G0_0_1_6_1_0 - 0.028218694885362*G0_0_1_6_1_1 - 0.0282186948853611*G0_0_1_8_1_1 - 0.0282186948853614*G0_0_1_9_1_0 + 0.0282186948853614*G0_0_1_10_1_0 + 0.0564373897707231*G0_0_1_10_1_1 + 0.0282186948853634*G0_0_1_11_1_0 + 0.028218694885362*G0_1_0_0_0_0 + 0.028218694885362*G0_1_0_0_0_1 + 0.0282186948853611*G0_1_0_2_0_1 + 0.0282186948853614*G0_1_0_3_0_0 - 0.0282186948853614*G0_1_0_4_0_0 - 0.0564373897707231*G0_1_0_4_0_1 - 0.0282186948853633*G0_1_0_5_0_0 + 0.028218694885362*G0_1_0_6_1_0 + 0.028218694885362*G0_1_0_6_1_1 + 0.0282186948853611*G0_1_0_8_1_1 + 0.0282186948853614*G0_1_0_9_1_0 - 0.0282186948853614*G0_1_0_10_1_0 - 0.0564373897707231*G0_1_0_10_1_1 - 0.0282186948853633*G0_1_0_11_1_0; + A[638] = 0.0; + A[534] = 0.0310405643738978*G0_1_0_0_0_0 + 0.0310405643738978*G0_1_0_0_0_1 + 0.0310405643738976*G0_1_0_1_0_0 + 0.0310405643738978*G0_1_0_3_0_1 - 0.0310405643738982*G0_1_0_4_0_1 - 0.0620811287477954*G0_1_0_5_0_0 - 0.0310405643738978*G0_1_0_5_0_1 + 0.0310405643738978*G0_1_0_6_1_0 + 0.0310405643738978*G0_1_0_6_1_1 + 0.0310405643738976*G0_1_0_7_1_0 + 0.0310405643738978*G0_1_0_9_1_1 - 0.0310405643738982*G0_1_0_10_1_1 - 0.0620811287477954*G0_1_0_11_1_0 - 0.0310405643738978*G0_1_0_11_1_1 - 0.135449735449736*G0_1_1_0_0_0 - 0.135449735449736*G0_1_1_0_0_1 + 0.019753086419753*G0_1_1_1_0_0 - 0.112874779541446*G0_1_1_2_0_1 - 0.0705467372134039*G0_1_1_3_0_0 + 0.0620811287477953*G0_1_1_3_0_1 + 0.0705467372134039*G0_1_1_4_0_0 + 0.248324514991182*G0_1_1_4_0_1 + 0.115696649029983*G0_1_1_5_0_0 - 0.0620811287477953*G0_1_1_5_0_1 - 0.135449735449736*G0_1_1_6_1_0 - 0.135449735449736*G0_1_1_6_1_1 + 0.019753086419753*G0_1_1_7_1_0 - 0.112874779541446*G0_1_1_8_1_1 - 0.0705467372134039*G0_1_1_9_1_0 + 0.0620811287477953*G0_1_1_9_1_1 + 0.0705467372134039*G0_1_1_10_1_0 + 0.248324514991182*G0_1_1_10_1_1 + 0.115696649029983*G0_1_1_11_1_0 - 0.0620811287477953*G0_1_1_11_1_1; + A[667] = 0.0; + A[696] = 0.0; + A[265] = 0.0; + A[290] = 0.0; + A[439] = 0.0; + A[319] = 0.0; + A[460] = 0.0; + A[356] = 0.0; + A[5] = A[534] + 0.112874779541446*G0_0_0_0_0_0 + 0.112874779541446*G0_0_0_0_0_1 - 0.0112874779541446*G0_0_0_1_0_0 + 0.166490299823633*G0_0_0_2_0_1 + 0.208818342151676*G0_0_0_3_0_0 + 0.0310405643738977*G0_0_0_3_0_1 - 0.208818342151676*G0_0_0_4_0_0 - 0.27936507936508*G0_0_0_4_0_1 - 0.101587301587302*G0_0_0_5_0_0 - 0.0310405643738978*G0_0_0_5_0_1 + 0.112874779541446*G0_0_0_6_1_0 + 0.112874779541446*G0_0_0_6_1_1 - 0.0112874779541446*G0_0_0_7_1_0 + 0.166490299823633*G0_0_0_8_1_1 + 0.208818342151676*G0_0_0_9_1_0 + 0.0310405643738977*G0_0_0_9_1_1 - 0.208818342151676*G0_0_0_10_1_0 - 0.27936507936508*G0_0_0_10_1_1 - 0.101587301587302*G0_0_0_11_1_0 - 0.0310405643738978*G0_0_0_11_1_1 + 0.112874779541446*G0_0_1_0_0_0 + 0.112874779541446*G0_0_1_0_0_1 + 0.0197530864197533*G0_0_1_1_0_0 + 0.135449735449735*G0_0_1_2_0_1 + 0.177777777777777*G0_0_1_3_0_0 + 0.0620811287477955*G0_0_1_3_0_1 - 0.177777777777777*G0_0_1_4_0_0 - 0.248324514991181*G0_0_1_4_0_1 - 0.132627865961199*G0_0_1_5_0_0 - 0.0620811287477956*G0_0_1_5_0_1 + 0.112874779541446*G0_0_1_6_1_0 + 0.112874779541446*G0_0_1_6_1_1 + 0.0197530864197533*G0_0_1_7_1_0 + 0.135449735449735*G0_0_1_8_1_1 + 0.177777777777777*G0_0_1_9_1_0 + 0.0620811287477955*G0_0_1_9_1_1 - 0.177777777777777*G0_0_1_10_1_0 - 0.248324514991181*G0_0_1_10_1_1 - 0.132627865961199*G0_0_1_11_1_0 - 0.0620811287477956*G0_0_1_11_1_1 + 0.0818342151675487*G0_1_0_0_0_0 + 0.0818342151675487*G0_1_0_0_0_1 - 0.0423280423280426*G0_1_0_1_0_0 + 0.166490299823634*G0_1_0_2_0_1 + 0.208818342151676*G0_1_0_3_0_0 - 0.208818342151676*G0_1_0_4_0_0 - 0.248324514991182*G0_1_0_4_0_1 - 0.0395061728395061*G0_1_0_5_0_0 + 0.0818342151675487*G0_1_0_6_1_0 + 0.0818342151675487*G0_1_0_6_1_1 - 0.0423280423280426*G0_1_0_7_1_0 + 0.166490299823634*G0_1_0_8_1_1 + 0.208818342151676*G0_1_0_9_1_0 - 0.208818342151676*G0_1_0_10_1_0 - 0.248324514991182*G0_1_0_10_1_1 - 0.0395061728395061*G0_1_0_11_1_0 + 0.248324514991182*G0_1_1_0_0_0 + 0.248324514991182*G0_1_1_0_0_1 + 0.248324514991182*G0_1_1_2_0_1 + 0.248324514991182*G0_1_1_3_0_0 - 0.248324514991182*G0_1_1_4_0_0 - 0.496649029982363*G0_1_1_4_0_1 - 0.248324514991182*G0_1_1_5_0_0 + 0.248324514991182*G0_1_1_6_1_0 + 0.248324514991182*G0_1_1_6_1_1 + 0.248324514991182*G0_1_1_8_1_1 + 0.248324514991182*G0_1_1_9_1_0 - 0.248324514991182*G0_1_1_10_1_0 - 0.496649029982363*G0_1_1_10_1_1 - 0.248324514991182*G0_1_1_11_1_0; + A[722] = 0.0; + A[389] = 0.0; + A[753] = 0.0; + A[67] = 0.32310405643739*G0_1_0_0_0_0 + 0.32310405643739*G0_1_0_0_0_1 - 0.294885361552028*G0_1_0_1_0_0 + 1.04338624338624*G0_1_0_2_0_1 + 1.46878306878307*G0_1_0_3_0_0 + 0.130511463844797*G0_1_0_3_0_1 - 1.46878306878307*G0_1_0_4_0_0 - 1.36649029982363*G0_1_0_4_0_1 - 0.0282186948853621*G0_1_0_5_0_0 - 0.130511463844797*G0_1_0_5_0_1 + 0.32310405643739*G0_1_0_6_1_0 + 0.32310405643739*G0_1_0_6_1_1 - 0.294885361552028*G0_1_0_7_1_0 + 1.04338624338624*G0_1_0_8_1_1 + 1.46878306878307*G0_1_0_9_1_0 + 0.130511463844797*G0_1_0_9_1_1 - 1.46878306878307*G0_1_0_10_1_0 - 1.36649029982363*G0_1_0_10_1_1 - 0.0282186948853621*G0_1_0_11_1_0 - 0.130511463844797*G0_1_0_11_1_1 + 0.00564373897707346*G0_1_1_0_0_0 + 0.00564373897707338*G0_1_1_0_0_1 - 0.256084656084656*G0_1_1_1_0_0 + 0.729453262786597*G0_1_1_2_0_1 + 1.19717813051146*G0_1_1_3_0_0 + 0.211640211640211*G0_1_1_3_0_1 - 1.19717813051146*G0_1_1_4_0_0 - 0.73509700176367*G0_1_1_4_0_1 + 0.250440917107582*G0_1_1_5_0_0 - 0.211640211640212*G0_1_1_5_0_1 + 0.00564373897707346*G0_1_1_6_1_0 + 0.00564373897707338*G0_1_1_6_1_1 - 0.256084656084656*G0_1_1_7_1_0 + 0.729453262786597*G0_1_1_8_1_1 + 1.19717813051146*G0_1_1_9_1_0 + 0.211640211640211*G0_1_1_9_1_1 - 1.19717813051146*G0_1_1_10_1_0 - 0.73509700176367*G0_1_1_10_1_1 + 0.250440917107582*G0_1_1_11_1_0 - 0.211640211640212*G0_1_1_11_1_1; + A[160] = A[625]; + A[112] = 0.0; + A[181] = -0.135449735449735*G0_0_0_0_0_0 - 0.135449735449735*G0_0_0_0_0_1 - 0.112874779541445*G0_0_0_1_0_0 + 0.0197530864197529*G0_0_0_2_0_1 + 0.062081128747795*G0_0_0_3_0_0 - 0.0705467372134032*G0_0_0_3_0_1 - 0.062081128747795*G0_0_0_4_0_0 + 0.115696649029982*G0_0_0_4_0_1 + 0.24832451499118*G0_0_0_5_0_0 + 0.0705467372134032*G0_0_0_5_0_1 - 0.135449735449735*G0_0_0_6_1_0 - 0.135449735449735*G0_0_0_6_1_1 - 0.112874779541445*G0_0_0_7_1_0 + 0.0197530864197529*G0_0_0_8_1_1 + 0.062081128747795*G0_0_0_9_1_0 - 0.0705467372134032*G0_0_0_9_1_1 - 0.062081128747795*G0_0_0_10_1_0 + 0.115696649029982*G0_0_0_10_1_1 + 0.24832451499118*G0_0_0_11_1_0 + 0.0705467372134032*G0_0_0_11_1_1 + 0.0310405643738985*G0_1_0_0_0_0 + 0.0310405643738985*G0_1_0_0_0_1 + 0.0310405643738976*G0_1_0_2_0_1 + 0.0310405643738977*G0_1_0_3_0_0 - 0.0310405643738977*G0_1_0_4_0_0 - 0.0620811287477961*G0_1_0_4_0_1 - 0.0310405643738995*G0_1_0_5_0_0 + 0.0310405643738985*G0_1_0_6_1_0 + 0.0310405643738985*G0_1_0_6_1_1 + 0.0310405643738976*G0_1_0_8_1_1 + 0.0310405643738977*G0_1_0_9_1_0 - 0.0310405643738977*G0_1_0_10_1_0 - 0.0620811287477961*G0_1_0_10_1_1 - 0.0310405643738995*G0_1_0_11_1_0; + A[137] = 0.0; + A[170] = 0.0; + A[207] = 0.0; + A[571] = 0.0; + A[527] = 0.221340388007055*G0_1_1_0_0_0 + 0.221340388007055*G0_1_1_0_0_1 - 0.221340388007055*G0_1_1_1_0_0 + 0.815696649029982*G0_1_1_2_0_1 + 1.18871252204585*G0_1_1_3_0_0 + 0.151675485008818*G0_1_1_3_0_1 - 1.18871252204585*G0_1_1_4_0_0 - 1.03703703703704*G0_1_1_4_0_1 - 0.151675485008818*G0_1_1_5_0_1 + 0.221340388007055*G0_1_1_6_1_0 + 0.221340388007055*G0_1_1_6_1_1 - 0.221340388007055*G0_1_1_7_1_0 + 0.815696649029982*G0_1_1_8_1_1 + 1.18871252204585*G0_1_1_9_1_0 + 0.151675485008818*G0_1_1_9_1_1 - 1.18871252204585*G0_1_1_10_1_0 - 1.03703703703704*G0_1_1_10_1_1 - 0.151675485008818*G0_1_1_11_1_1; + A[562] = A[213] - 0.0564373897707215*G0_0_1_0_0_0 - 0.0564373897707214*G0_0_1_0_0_1 + 0.0112874779541464*G0_0_1_1_0_0 - 0.0677248677248671*G0_0_1_2_0_1 - 0.0677248677248663*G0_0_1_3_0_0 + 0.0112874779541471*G0_0_1_3_0_1 + 0.0677248677248663*G0_0_1_4_0_0 + 0.124162257495588*G0_0_1_4_0_1 + 0.0451499118165751*G0_0_1_5_0_0 - 0.0112874779541471*G0_0_1_5_0_1 - 0.0564373897707215*G0_0_1_6_1_0 - 0.0564373897707214*G0_0_1_6_1_1 + 0.0112874779541464*G0_0_1_7_1_0 - 0.0677248677248671*G0_0_1_8_1_1 - 0.0677248677248663*G0_0_1_9_1_0 + 0.0112874779541471*G0_0_1_9_1_1 + 0.0677248677248663*G0_0_1_10_1_0 + 0.124162257495588*G0_0_1_10_1_1 + 0.0451499118165751*G0_0_1_11_1_0 - 0.0112874779541471*G0_0_1_11_1_1 + 0.0564373897707215*G0_1_0_0_0_0 + 0.0564373897707214*G0_1_0_0_0_1 - 0.0112874779541463*G0_1_0_1_0_0 + 0.067724867724867*G0_1_0_2_0_1 + 0.0677248677248662*G0_1_0_3_0_0 - 0.0112874779541471*G0_1_0_3_0_1 - 0.0677248677248662*G0_1_0_4_0_0 - 0.124162257495588*G0_1_0_4_0_1 - 0.0451499118165752*G0_1_0_5_0_0 + 0.0112874779541471*G0_1_0_5_0_1 + 0.0564373897707215*G0_1_0_6_1_0 + 0.0564373897707214*G0_1_0_6_1_1 - 0.0112874779541463*G0_1_0_7_1_0 + 0.067724867724867*G0_1_0_8_1_1 + 0.0677248677248662*G0_1_0_9_1_0 - 0.0112874779541471*G0_1_0_9_1_1 - 0.0677248677248662*G0_1_0_10_1_0 - 0.124162257495588*G0_1_0_10_1_1 - 0.0451499118165752*G0_1_0_11_1_0 + 0.0112874779541471*G0_1_0_11_1_1; + A[299] = 0.0; + A[446] = 0.0; + A[326] = 0.0; + A[349] = 0.0; + A[28] = 0.0; + A[729] = 0.0; + A[380] = 0.0; + A[55] = 0.0; + A[754] = 0.0; + A[415] = 0.0; + A[783] = 0.0; + A[820] = 0.0; + A[144] = 0.0; + A[853] = 0.0; + A[179] = 0.0; + A[491] = 0.0; + A[198] = 0.0; + A[656] = A[716] + 0.496649029982362*G0_0_0_0_0_0 + 0.496649029982361*G0_0_0_0_0_1 + 0.406349206349206*G0_0_0_1_0_0 - 0.045149911816579*G0_0_0_2_0_1 - 0.180599647266314*G0_0_0_3_0_0 + 0.270899470899471*G0_0_0_3_0_1 + 0.180599647266314*G0_0_0_4_0_0 - 0.451499118165782*G0_0_0_4_0_1 - 0.902998236331567*G0_0_0_5_0_0 - 0.270899470899471*G0_0_0_5_0_1 + 0.496649029982362*G0_0_0_6_1_0 + 0.496649029982361*G0_0_0_6_1_1 + 0.406349206349206*G0_0_0_7_1_0 - 0.045149911816579*G0_0_0_8_1_1 - 0.180599647266314*G0_0_0_9_1_0 + 0.270899470899471*G0_0_0_9_1_1 + 0.180599647266314*G0_0_0_10_1_0 - 0.451499118165782*G0_0_0_10_1_1 - 0.902998236331567*G0_0_0_11_1_0 - 0.270899470899471*G0_0_0_11_1_1 - 0.0902998236331569*G0_0_1_0_0_0 - 0.0902998236331568*G0_0_1_0_0_1 - 0.0902998236331565*G0_0_1_2_0_1 - 0.0902998236331561*G0_0_1_3_0_0 + 0.0902998236331561*G0_0_1_4_0_0 + 0.180599647266313*G0_0_1_4_0_1 + 0.0902998236331567*G0_0_1_5_0_0 - 0.0902998236331569*G0_0_1_6_1_0 - 0.0902998236331568*G0_0_1_6_1_1 - 0.0902998236331565*G0_0_1_8_1_1 - 0.0902998236331561*G0_0_1_9_1_0 + 0.0902998236331561*G0_0_1_10_1_0 + 0.180599647266313*G0_0_1_10_1_1 + 0.0902998236331567*G0_0_1_11_1_0 - 0.180599647266315*G0_1_0_0_0_0 - 0.180599647266315*G0_1_0_0_0_1 - 0.180599647266314*G0_1_0_2_0_1 - 0.180599647266313*G0_1_0_3_0_0 + 0.180599647266313*G0_1_0_4_0_0 + 0.361199294532629*G0_1_0_4_0_1 + 0.180599647266315*G0_1_0_5_0_0 - 0.180599647266315*G0_1_0_6_1_0 - 0.180599647266315*G0_1_0_6_1_1 - 0.180599647266314*G0_1_0_8_1_1 - 0.180599647266313*G0_1_0_9_1_0 + 0.180599647266313*G0_1_0_10_1_0 + 0.361199294532629*G0_1_0_10_1_1 + 0.180599647266315*G0_1_0_11_1_0; + A[576] = 0.0; + A[520] = 0.0; + A[237] = 0.0; + A[677] = 0.32310405643739*G0_0_1_0_0_0 + 0.32310405643739*G0_0_1_0_0_1 - 0.294885361552028*G0_0_1_1_0_0 + 1.04338624338624*G0_0_1_2_0_1 + 1.46878306878307*G0_0_1_3_0_0 + 0.130511463844797*G0_0_1_3_0_1 - 1.46878306878307*G0_0_1_4_0_0 - 1.36649029982363*G0_0_1_4_0_1 - 0.0282186948853621*G0_0_1_5_0_0 - 0.130511463844797*G0_0_1_5_0_1 + 0.32310405643739*G0_0_1_6_1_0 + 0.32310405643739*G0_0_1_6_1_1 - 0.294885361552028*G0_0_1_7_1_0 + 1.04338624338624*G0_0_1_8_1_1 + 1.46878306878307*G0_0_1_9_1_0 + 0.130511463844797*G0_0_1_9_1_1 - 1.46878306878307*G0_0_1_10_1_0 - 1.36649029982363*G0_0_1_10_1_1 - 0.0282186948853621*G0_0_1_11_1_0 - 0.130511463844797*G0_0_1_11_1_1 + 0.00564373897707343*G0_1_1_0_0_0 + 0.0056437389770734*G0_1_1_0_0_1 - 0.256084656084656*G0_1_1_1_0_0 + 0.729453262786596*G0_1_1_2_0_1 + 1.19717813051146*G0_1_1_3_0_0 + 0.211640211640211*G0_1_1_3_0_1 - 1.19717813051146*G0_1_1_4_0_0 - 0.73509700176367*G0_1_1_4_0_1 + 0.250440917107582*G0_1_1_5_0_0 - 0.211640211640212*G0_1_1_5_0_1 + 0.00564373897707343*G0_1_1_6_1_0 + 0.0056437389770734*G0_1_1_6_1_1 - 0.256084656084656*G0_1_1_7_1_0 + 0.729453262786596*G0_1_1_8_1_1 + 1.19717813051146*G0_1_1_9_1_0 + 0.211640211640211*G0_1_1_9_1_1 - 1.19717813051146*G0_1_1_10_1_0 - 0.73509700176367*G0_1_1_10_1_1 + 0.250440917107582*G0_1_1_11_1_0 - 0.211640211640212*G0_1_1_11_1_1; + A[601] = 0.0; + A[634] = 0.0; + A[671] = 0.0; + A[449] = 0.0; + A[305] = A[625] - 0.0564373897707228*G0_0_1_0_0_0 - 0.0564373897707228*G0_0_1_0_0_1 - 0.0677248677248661*G0_0_1_1_0_0 + 0.0112874779541425*G0_0_1_2_0_1 + 0.0112874779541416*G0_0_1_3_0_0 - 0.067724867724867*G0_0_1_3_0_1 - 0.0112874779541416*G0_0_1_4_0_0 + 0.0451499118165803*G0_0_1_4_0_1 + 0.124162257495589*G0_0_1_5_0_0 + 0.0677248677248669*G0_0_1_5_0_1 - 0.0564373897707228*G0_0_1_6_1_0 - 0.0564373897707228*G0_0_1_6_1_1 - 0.0677248677248661*G0_0_1_7_1_0 + 0.0112874779541425*G0_0_1_8_1_1 + 0.0112874779541416*G0_0_1_9_1_0 - 0.067724867724867*G0_0_1_9_1_1 - 0.0112874779541416*G0_0_1_10_1_0 + 0.0451499118165803*G0_0_1_10_1_1 + 0.124162257495589*G0_0_1_11_1_0 + 0.0677248677248669*G0_0_1_11_1_1 + 0.0564373897707228*G0_1_0_0_0_0 + 0.0564373897707228*G0_1_0_0_0_1 + 0.0677248677248661*G0_1_0_1_0_0 - 0.0112874779541425*G0_1_0_2_0_1 - 0.0112874779541416*G0_1_0_3_0_0 + 0.067724867724867*G0_1_0_3_0_1 + 0.0112874779541416*G0_1_0_4_0_0 - 0.0451499118165803*G0_1_0_4_0_1 - 0.124162257495589*G0_1_0_5_0_0 - 0.0677248677248669*G0_1_0_5_0_1 + 0.0564373897707228*G0_1_0_6_1_0 + 0.0564373897707228*G0_1_0_6_1_1 + 0.0677248677248661*G0_1_0_7_1_0 - 0.0112874779541425*G0_1_0_8_1_1 - 0.0112874779541416*G0_1_0_9_1_0 + 0.067724867724867*G0_1_0_9_1_1 + 0.0112874779541416*G0_1_0_10_1_0 - 0.0451499118165803*G0_1_0_10_1_1 - 0.124162257495589*G0_1_0_11_1_0 - 0.0677248677248669*G0_1_0_11_1_1; + A[474] = A[270] - 1.96966490299823*G0_0_1_0_0_0 - 1.96966490299823*G0_0_1_0_0_1 - 0.595414462081128*G0_0_1_1_0_0 - 0.595414462081128*G0_0_1_2_0_1 + 0.183421516754849*G0_0_1_3_0_0 + 0.183421516754849*G0_0_1_3_0_1 - 0.183421516754849*G0_0_1_4_0_0 + 2.56507936507936*G0_0_1_4_0_1 + 2.56507936507936*G0_0_1_5_0_0 - 0.18342151675485*G0_0_1_5_0_1 - 1.96966490299823*G0_0_1_6_1_0 - 1.96966490299823*G0_0_1_6_1_1 - 0.595414462081128*G0_0_1_7_1_0 - 0.595414462081128*G0_0_1_8_1_1 + 0.183421516754849*G0_0_1_9_1_0 + 0.183421516754849*G0_0_1_9_1_1 - 0.183421516754849*G0_0_1_10_1_0 + 2.56507936507936*G0_0_1_10_1_1 + 2.56507936507936*G0_0_1_11_1_0 - 0.18342151675485*G0_0_1_11_1_1 + 1.96966490299823*G0_1_0_0_0_0 + 1.96966490299823*G0_1_0_0_0_1 + 0.595414462081128*G0_1_0_1_0_0 + 0.595414462081128*G0_1_0_2_0_1 - 0.183421516754848*G0_1_0_3_0_0 - 0.183421516754849*G0_1_0_3_0_1 + 0.183421516754848*G0_1_0_4_0_0 - 2.56507936507936*G0_1_0_4_0_1 - 2.56507936507936*G0_1_0_5_0_0 + 0.18342151675485*G0_1_0_5_0_1 + 1.96966490299823*G0_1_0_6_1_0 + 1.96966490299823*G0_1_0_6_1_1 + 0.595414462081128*G0_1_0_7_1_0 + 0.595414462081128*G0_1_0_8_1_1 - 0.183421516754848*G0_1_0_9_1_0 - 0.183421516754849*G0_1_0_9_1_1 + 0.183421516754848*G0_1_0_10_1_0 - 2.56507936507936*G0_1_0_10_1_1 - 2.56507936507936*G0_1_0_11_1_0 + 0.18342151675485*G0_1_0_11_1_1; + A[645] = A[474] - 1.96966490299823*G0_0_0_0_0_0 - 1.96966490299823*G0_0_0_0_0_1 - 0.496649029982363*G0_0_0_1_0_0 - 0.694179894179894*G0_0_0_2_0_1 + 0.0846560846560832*G0_0_0_3_0_0 + 0.282186948853615*G0_0_0_3_0_1 - 0.0846560846560832*G0_0_0_4_0_0 + 2.66384479717813*G0_0_0_4_0_1 + 2.4663139329806*G0_0_0_5_0_0 - 0.282186948853615*G0_0_0_5_0_1 - 1.96966490299823*G0_0_0_6_1_0 - 1.96966490299823*G0_0_0_6_1_1 - 0.496649029982363*G0_0_0_7_1_0 - 0.694179894179894*G0_0_0_8_1_1 + 0.0846560846560832*G0_0_0_9_1_0 + 0.282186948853615*G0_0_0_9_1_1 - 0.0846560846560832*G0_0_0_10_1_0 + 2.66384479717813*G0_0_0_10_1_1 + 2.4663139329806*G0_0_0_11_1_0 - 0.282186948853615*G0_0_0_11_1_1 + 0.0987654320987658*G0_0_1_1_0_0 - 0.0987654320987653*G0_0_1_2_0_1 - 0.0987654320987659*G0_0_1_3_0_0 + 0.0987654320987652*G0_0_1_3_0_1 + 0.0987654320987659*G0_0_1_4_0_0 + 0.0987654320987645*G0_0_1_4_0_1 - 0.0987654320987662*G0_0_1_5_0_0 - 0.0987654320987652*G0_0_1_5_0_1 + 0.0987654320987658*G0_0_1_7_1_0 - 0.0987654320987653*G0_0_1_8_1_1 - 0.0987654320987659*G0_0_1_9_1_0 + 0.0987654320987652*G0_0_1_9_1_1 + 0.0987654320987659*G0_0_1_10_1_0 + 0.0987654320987645*G0_0_1_10_1_1 - 0.0987654320987662*G0_0_1_11_1_0 - 0.0987654320987652*G0_0_1_11_1_1 + 0.098765432098765*G0_1_0_1_0_0 - 0.0987654320987658*G0_1_0_2_0_1 - 0.0987654320987655*G0_1_0_3_0_0 + 0.0987654320987651*G0_1_0_3_0_1 + 0.0987654320987655*G0_1_0_4_0_0 + 0.0987654320987672*G0_1_0_4_0_1 - 0.0987654320987637*G0_1_0_5_0_0 - 0.0987654320987652*G0_1_0_5_0_1 + 0.098765432098765*G0_1_0_7_1_0 - 0.0987654320987658*G0_1_0_8_1_1 - 0.0987654320987655*G0_1_0_9_1_0 + 0.0987654320987651*G0_1_0_9_1_1 + 0.0987654320987655*G0_1_0_10_1_0 + 0.0987654320987672*G0_1_0_10_1_1 - 0.0987654320987637*G0_1_0_11_1_0 - 0.0987654320987652*G0_1_0_11_1_1 + 1.96966490299823*G0_1_1_0_0_0 + 1.96966490299823*G0_1_1_0_0_1 + 0.694179894179893*G0_1_1_1_0_0 + 0.496649029982362*G0_1_1_2_0_1 - 0.282186948853615*G0_1_1_3_0_0 - 0.0846560846560843*G0_1_1_3_0_1 + 0.282186948853615*G0_1_1_4_0_0 - 2.46631393298059*G0_1_1_4_0_1 - 2.66384479717813*G0_1_1_5_0_0 + 0.0846560846560847*G0_1_1_5_0_1 + 1.96966490299823*G0_1_1_6_1_0 + 1.96966490299823*G0_1_1_6_1_1 + 0.694179894179893*G0_1_1_7_1_0 + 0.496649029982362*G0_1_1_8_1_1 - 0.282186948853615*G0_1_1_9_1_0 - 0.0846560846560843*G0_1_1_9_1_1 + 0.282186948853615*G0_1_1_10_1_0 - 2.46631393298059*G0_1_1_10_1_1 - 2.66384479717813*G0_1_1_11_1_0 + 0.0846560846560847*G0_1_1_11_1_1; + A[338] = A[803]; + A[19] = 0.0; + A[379] = 0.0; + A[48] = 0.0; + A[763] = 0.0; + A[456] = 0.0; + A[408] = 0.0; + A[85] = 0.0; + A[790] = 0.0; + A[9] = A[474]; + A[813] = 0.0; + A[844] = 0.0; + A[879] = 0.0; + A[482] = 0.0; + A[201] = 0.0; + A[513] = 0.0; + A[226] = 0.0; + A[608] = 0.0; + A[548] = 0.0; + A[643] = 0.0; + A[662] = 0.0; + A[285] = 0.0; + A[701] = 0.0; + A[260] = 0.0; + A[331] = -0.270899470899471*G0_0_0_0_0_0 - 0.270899470899471*G0_0_0_0_0_1 - 1.29241622574956*G0_0_0_1_0_0 + 0.369664902998236*G0_0_0_2_0_1 - 0.282186948853614*G0_0_0_3_0_0 - 1.94426807760141*G0_0_0_3_0_1 + 0.282186948853614*G0_0_0_4_0_0 - 0.0987654320987662*G0_0_0_4_0_1 + 1.56331569664903*G0_0_0_5_0_0 + 1.94426807760141*G0_0_0_5_0_1 - 0.270899470899471*G0_0_0_6_1_0 - 0.270899470899471*G0_0_0_6_1_1 - 1.29241622574956*G0_0_0_7_1_0 + 0.369664902998236*G0_0_0_8_1_1 - 0.282186948853614*G0_0_0_9_1_0 - 1.94426807760141*G0_0_0_9_1_1 + 0.282186948853614*G0_0_0_10_1_0 - 0.0987654320987662*G0_0_0_10_1_1 + 1.56331569664903*G0_0_0_11_1_0 + 1.94426807760141*G0_0_0_11_1_1 - 0.595414462081128*G0_1_0_0_0_0 - 0.595414462081128*G0_1_0_0_0_1 - 1.96966490299823*G0_1_0_1_0_0 + 0.595414462081128*G0_1_0_2_0_1 - 0.183421516754848*G0_1_0_3_0_0 - 2.74850088183421*G0_1_0_3_0_1 + 0.183421516754848*G0_1_0_4_0_0 + 2.56507936507936*G0_1_0_5_0_0 + 2.74850088183421*G0_1_0_5_0_1 - 0.595414462081128*G0_1_0_6_1_0 - 0.595414462081128*G0_1_0_6_1_1 - 1.96966490299823*G0_1_0_7_1_0 + 0.595414462081128*G0_1_0_8_1_1 - 0.183421516754848*G0_1_0_9_1_0 - 2.74850088183421*G0_1_0_9_1_1 + 0.183421516754848*G0_1_0_10_1_0 + 2.56507936507936*G0_1_0_11_1_0 + 2.74850088183421*G0_1_0_11_1_1; + A[287] = 0.0; + A[743] = A[803] - 0.180599647266313*G0_0_1_0_0_0 - 0.180599647266313*G0_0_1_0_0_1 - 0.180599647266312*G0_0_1_1_0_0 - 0.180599647266311*G0_0_1_3_0_1 + 0.180599647266313*G0_0_1_4_0_1 + 0.361199294532625*G0_0_1_5_0_0 + 0.180599647266311*G0_0_1_5_0_1 - 0.180599647266313*G0_0_1_6_1_0 - 0.180599647266313*G0_0_1_6_1_1 - 0.180599647266312*G0_0_1_7_1_0 - 0.180599647266311*G0_0_1_9_1_1 + 0.180599647266313*G0_0_1_10_1_1 + 0.361199294532625*G0_0_1_11_1_0 + 0.180599647266311*G0_0_1_11_1_1 - 0.090299823633156*G0_1_0_0_0_0 - 0.090299823633156*G0_1_0_0_0_1 - 0.0902998236331553*G0_1_0_1_0_0 - 0.0902998236331548*G0_1_0_3_0_1 + 0.090299823633156*G0_1_0_4_0_1 + 0.180599647266311*G0_1_0_5_0_0 + 0.0902998236331548*G0_1_0_5_0_1 - 0.090299823633156*G0_1_0_6_1_0 - 0.090299823633156*G0_1_0_6_1_1 - 0.0902998236331553*G0_1_0_7_1_0 - 0.0902998236331548*G0_1_0_9_1_1 + 0.090299823633156*G0_1_0_10_1_1 + 0.180599647266311*G0_1_0_11_1_0 + 0.0902998236331548*G0_1_0_11_1_1 + 0.496649029982363*G0_1_1_0_0_0 + 0.496649029982363*G0_1_1_0_0_1 - 0.0451499118165756*G0_1_1_1_0_0 + 0.406349206349205*G0_1_1_2_0_1 + 0.270899470899472*G0_1_1_3_0_0 - 0.180599647266309*G0_1_1_3_0_1 - 0.270899470899472*G0_1_1_4_0_0 - 0.902998236331569*G0_1_1_4_0_1 - 0.451499118165788*G0_1_1_5_0_0 + 0.180599647266309*G0_1_1_5_0_1 + 0.496649029982363*G0_1_1_6_1_0 + 0.496649029982363*G0_1_1_6_1_1 - 0.0451499118165756*G0_1_1_7_1_0 + 0.406349206349205*G0_1_1_8_1_1 + 0.270899470899472*G0_1_1_9_1_0 - 0.180599647266309*G0_1_1_9_1_1 - 0.270899470899472*G0_1_1_10_1_0 - 0.902998236331569*G0_1_1_10_1_1 - 0.451499118165788*G0_1_1_11_1_0 + 0.180599647266309*G0_1_1_11_1_1; + A[322] = 0.0; + A[465] = A[527] - 0.815696649029982*G0_0_0_0_0_0 - 0.815696649029982*G0_0_0_0_0_1 - 0.221340388007055*G0_0_0_1_0_0 - 0.221340388007055*G0_0_0_2_0_1 + 0.151675485008818*G0_0_0_3_0_0 + 0.151675485008818*G0_0_0_3_0_1 - 0.151675485008818*G0_0_0_4_0_0 + 1.03703703703704*G0_0_0_4_0_1 + 1.03703703703704*G0_0_0_5_0_0 - 0.151675485008818*G0_0_0_5_0_1 - 0.815696649029982*G0_0_0_6_1_0 - 0.815696649029982*G0_0_0_6_1_1 - 0.221340388007055*G0_0_0_7_1_0 - 0.221340388007055*G0_0_0_8_1_1 + 0.151675485008818*G0_0_0_9_1_0 + 0.151675485008818*G0_0_0_9_1_1 - 0.151675485008818*G0_0_0_10_1_0 + 1.03703703703704*G0_0_0_10_1_1 + 1.03703703703704*G0_0_0_11_1_0 - 0.151675485008818*G0_0_0_11_1_1 - 0.815696649029982*G0_0_1_0_0_0 - 0.815696649029982*G0_0_1_0_0_1 - 0.221340388007055*G0_0_1_1_0_0 - 0.221340388007054*G0_0_1_2_0_1 + 0.151675485008818*G0_0_1_3_0_0 + 0.151675485008818*G0_0_1_3_0_1 - 0.151675485008818*G0_0_1_4_0_0 + 1.03703703703704*G0_0_1_4_0_1 + 1.03703703703704*G0_0_1_5_0_0 - 0.151675485008818*G0_0_1_5_0_1 - 0.815696649029982*G0_0_1_6_1_0 - 0.815696649029982*G0_0_1_6_1_1 - 0.221340388007055*G0_0_1_7_1_0 - 0.221340388007054*G0_0_1_8_1_1 + 0.151675485008818*G0_0_1_9_1_0 + 0.151675485008818*G0_0_1_9_1_1 - 0.151675485008818*G0_0_1_10_1_0 + 1.03703703703704*G0_0_1_10_1_1 + 1.03703703703704*G0_0_1_11_1_0 - 0.151675485008818*G0_0_1_11_1_1 - 0.815696649029982*G0_1_0_0_0_0 - 0.815696649029982*G0_1_0_0_0_1 - 0.221340388007055*G0_1_0_1_0_0 - 0.221340388007054*G0_1_0_2_0_1 + 0.151675485008818*G0_1_0_3_0_0 + 0.151675485008818*G0_1_0_3_0_1 - 0.151675485008818*G0_1_0_4_0_0 + 1.03703703703704*G0_1_0_4_0_1 + 1.03703703703704*G0_1_0_5_0_0 - 0.151675485008818*G0_1_0_5_0_1 - 0.815696649029982*G0_1_0_6_1_0 - 0.815696649029982*G0_1_0_6_1_1 - 0.221340388007055*G0_1_0_7_1_0 - 0.221340388007054*G0_1_0_8_1_1 + 0.151675485008818*G0_1_0_9_1_0 + 0.151675485008818*G0_1_0_9_1_1 - 0.151675485008818*G0_1_0_10_1_0 + 1.03703703703704*G0_1_0_10_1_1 + 1.03703703703704*G0_1_0_11_1_0 - 0.151675485008818*G0_1_0_11_1_1 - 1.03703703703704*G0_1_1_0_0_0 - 1.03703703703704*G0_1_1_0_0_1 - 1.03703703703704*G0_1_1_2_0_1 - 1.03703703703704*G0_1_1_3_0_0 + 1.03703703703704*G0_1_1_4_0_0 + 2.07407407407407*G0_1_1_4_0_1 + 1.03703703703704*G0_1_1_5_0_0 - 1.03703703703704*G0_1_1_6_1_0 - 1.03703703703704*G0_1_1_6_1_1 - 1.03703703703704*G0_1_1_8_1_1 - 1.03703703703704*G0_1_1_9_1_0 + 1.03703703703704*G0_1_1_10_1_0 + 2.07407407407407*G0_1_1_10_1_1 + 1.03703703703704*G0_1_1_11_1_0; + A[76] = 0.0; + A[0] = A[465]; + A[43] = A[509] - 0.541798941798941*G0_0_0_0_0_0 - 0.541798941798941*G0_0_0_0_0_1 - 1.35449735449735*G0_0_0_1_0_0 + 0.812698412698411*G0_0_0_2_0_1 + 0.812698412698411*G0_0_0_3_0_0 - 1.35449735449735*G0_0_0_3_0_1 - 0.812698412698411*G0_0_0_4_0_0 - 0.27089947089947*G0_0_0_4_0_1 + 1.89629629629629*G0_0_0_5_0_0 + 1.35449735449735*G0_0_0_5_0_1 - 0.541798941798941*G0_0_0_6_1_0 - 0.541798941798941*G0_0_0_6_1_1 - 1.35449735449735*G0_0_0_7_1_0 + 0.812698412698411*G0_0_0_8_1_1 + 0.812698412698411*G0_0_0_9_1_0 - 1.35449735449735*G0_0_0_9_1_1 - 0.812698412698411*G0_0_0_10_1_0 - 0.27089947089947*G0_0_0_10_1_1 + 1.89629629629629*G0_0_0_11_1_0 + 1.35449735449735*G0_0_0_11_1_1; + A[843] = 0.0; + A[70] = 0.0204585537918867*G0_1_0_0_0_0 + 0.0204585537918867*G0_1_0_0_0_1 + 0.0204585537918872*G0_1_0_1_0_0 + 0.0204585537918869*G0_1_0_3_0_1 - 0.0204585537918859*G0_1_0_4_0_1 - 0.0409171075837739*G0_1_0_5_0_0 - 0.0204585537918869*G0_1_0_5_0_1 + 0.0204585537918867*G0_1_0_6_1_0 + 0.0204585537918867*G0_1_0_6_1_1 + 0.0204585537918872*G0_1_0_7_1_0 + 0.0204585537918869*G0_1_0_9_1_1 - 0.0204585537918859*G0_1_0_10_1_1 - 0.0409171075837739*G0_1_0_11_1_0 - 0.0204585537918869*G0_1_0_11_1_1 - 0.0514991181657851*G0_1_1_0_0_0 - 0.051499118165785*G0_1_1_0_0_1 + 0.0719576719576718*G0_1_1_1_0_0 - 0.0811287477954142*G0_1_1_2_0_1 - 0.0388007054673717*G0_1_1_3_0_0 + 0.114285714285714*G0_1_1_3_0_1 + 0.0388007054673717*G0_1_1_4_0_0 + 0.132627865961199*G0_1_1_4_0_1 - 0.0204585537918867*G0_1_1_5_0_0 - 0.114285714285714*G0_1_1_5_0_1 - 0.0514991181657851*G0_1_1_6_1_0 - 0.051499118165785*G0_1_1_6_1_1 + 0.0719576719576718*G0_1_1_7_1_0 - 0.0811287477954142*G0_1_1_8_1_1 - 0.0388007054673717*G0_1_1_9_1_0 + 0.114285714285714*G0_1_1_9_1_1 + 0.0388007054673717*G0_1_1_10_1_0 + 0.132627865961199*G0_1_1_10_1_1 - 0.0204585537918867*G0_1_1_11_1_0 - 0.114285714285714*G0_1_1_11_1_1; + A[469] = A[70] + 0.0811287477954147*G0_0_0_0_0_0 + 0.0811287477954147*G0_0_0_0_0_1 + 0.0514991181657847*G0_0_0_1_0_0 + 0.0719576719576717*G0_0_0_2_0_1 + 0.114285714285713*G0_0_0_3_0_0 + 0.0938271604938264*G0_0_0_3_0_1 - 0.114285714285713*G0_0_0_4_0_0 - 0.153086419753086*G0_0_0_4_0_1 - 0.132627865961199*G0_0_0_5_0_0 - 0.0938271604938264*G0_0_0_5_0_1 + 0.0811287477954147*G0_0_0_6_1_0 + 0.0811287477954147*G0_0_0_6_1_1 + 0.0514991181657847*G0_0_0_7_1_0 + 0.0719576719576717*G0_0_0_8_1_1 + 0.114285714285713*G0_0_0_9_1_0 + 0.0938271604938264*G0_0_0_9_1_1 - 0.114285714285713*G0_0_0_10_1_0 - 0.153086419753086*G0_0_0_10_1_1 - 0.132627865961199*G0_0_0_11_1_0 - 0.0938271604938264*G0_0_0_11_1_1 + 0.0811287477954147*G0_0_1_0_0_0 + 0.0811287477954147*G0_0_1_0_0_1 + 0.0719576719576711*G0_0_1_1_0_0 + 0.051499118165785*G0_0_1_2_0_1 + 0.0938271604938264*G0_0_1_3_0_0 + 0.114285714285713*G0_0_1_3_0_1 - 0.0938271604938264*G0_0_1_4_0_0 - 0.1326278659612*G0_0_1_4_0_1 - 0.153086419753086*G0_0_1_5_0_0 - 0.114285714285712*G0_0_1_5_0_1 + 0.0811287477954147*G0_0_1_6_1_0 + 0.0811287477954147*G0_0_1_6_1_1 + 0.0719576719576711*G0_0_1_7_1_0 + 0.051499118165785*G0_0_1_8_1_1 + 0.0938271604938264*G0_0_1_9_1_0 + 0.114285714285713*G0_0_1_9_1_1 - 0.0938271604938264*G0_0_1_10_1_0 - 0.1326278659612*G0_0_1_10_1_1 - 0.153086419753086*G0_0_1_11_1_0 - 0.114285714285712*G0_0_1_11_1_1 + 0.0606701940035279*G0_1_0_0_0_0 + 0.0606701940035279*G0_1_0_0_0_1 + 0.0310405643738977*G0_1_0_1_0_0 + 0.071957671957672*G0_1_0_2_0_1 + 0.114285714285714*G0_1_0_3_0_0 + 0.0733686067019394*G0_1_0_3_0_1 - 0.114285714285714*G0_1_0_4_0_0 - 0.1326278659612*G0_1_0_4_0_1 - 0.0917107583774256*G0_1_0_5_0_0 - 0.0733686067019394*G0_1_0_5_0_1 + 0.0606701940035279*G0_1_0_6_1_0 + 0.0606701940035279*G0_1_0_6_1_1 + 0.0310405643738977*G0_1_0_7_1_0 + 0.071957671957672*G0_1_0_8_1_1 + 0.114285714285714*G0_1_0_9_1_0 + 0.0733686067019394*G0_1_0_9_1_1 - 0.114285714285714*G0_1_0_10_1_0 - 0.1326278659612*G0_1_0_10_1_1 - 0.0917107583774256*G0_1_0_11_1_0 - 0.0733686067019394*G0_1_0_11_1_1 + 0.1326278659612*G0_1_1_0_0_0 + 0.1326278659612*G0_1_1_0_0_1 + 0.132627865961199*G0_1_1_2_0_1 + 0.132627865961198*G0_1_1_3_0_0 - 0.132627865961198*G0_1_1_4_0_0 - 0.265255731922399*G0_1_1_4_0_1 - 0.132627865961199*G0_1_1_5_0_0 + 0.1326278659612*G0_1_1_6_1_0 + 0.1326278659612*G0_1_1_6_1_1 + 0.132627865961199*G0_1_1_8_1_1 + 0.132627865961198*G0_1_1_9_1_0 - 0.132627865961198*G0_1_1_10_1_0 - 0.265255731922399*G0_1_1_10_1_1 - 0.132627865961199*G0_1_1_11_1_0; + A[585] = A[469] - 0.0204585537918863*G0_0_1_1_0_0 + 0.0204585537918862*G0_0_1_2_0_1 + 0.0204585537918862*G0_0_1_3_0_0 - 0.0204585537918863*G0_0_1_3_0_1 - 0.0204585537918862*G0_0_1_4_0_0 - 0.0204585537918862*G0_0_1_4_0_1 + 0.0204585537918863*G0_0_1_5_0_0 + 0.0204585537918863*G0_0_1_5_0_1 - 0.0204585537918863*G0_0_1_7_1_0 + 0.0204585537918862*G0_0_1_8_1_1 + 0.0204585537918862*G0_0_1_9_1_0 - 0.0204585537918863*G0_0_1_9_1_1 - 0.0204585537918862*G0_0_1_10_1_0 - 0.0204585537918862*G0_0_1_10_1_1 + 0.0204585537918863*G0_0_1_11_1_0 + 0.0204585537918863*G0_0_1_11_1_1 + 0.0204585537918862*G0_1_0_1_0_0 - 0.0204585537918862*G0_1_0_2_0_1 - 0.0204585537918862*G0_1_0_3_0_0 + 0.0204585537918863*G0_1_0_3_0_1 + 0.0204585537918862*G0_1_0_4_0_0 + 0.0204585537918862*G0_1_0_4_0_1 - 0.0204585537918862*G0_1_0_5_0_0 - 0.0204585537918863*G0_1_0_5_0_1 + 0.0204585537918862*G0_1_0_7_1_0 - 0.0204585537918862*G0_1_0_8_1_1 - 0.0204585537918862*G0_1_0_9_1_0 + 0.0204585537918863*G0_1_0_9_1_1 + 0.0204585537918862*G0_1_0_10_1_0 + 0.0204585537918862*G0_1_0_10_1_1 - 0.0204585537918862*G0_1_0_11_1_0 - 0.0204585537918863*G0_1_0_11_1_1; + A[165] = 0.0; + A[872] = 0.0; + A[109] = 0.0; + A[140] = 0.0; + A[514] = 0.0; + A[543] = 0.0; + A[665] = 0.0; + A[690] = 0.0; + A[267] = 0.0; + A[296] = 0.0; + A[437] = 0.0; + A[361] = A[421] + 0.27089947089947*G0_0_0_0_0_0 + 0.27089947089947*G0_0_0_0_0_1 + 0.27089947089947*G0_0_0_2_0_1 + 0.27089947089947*G0_0_0_3_0_0 - 0.27089947089947*G0_0_0_4_0_0 - 0.541798941798939*G0_0_0_4_0_1 - 0.27089947089947*G0_0_0_5_0_0 + 0.27089947089947*G0_0_0_6_1_0 + 0.27089947089947*G0_0_0_6_1_1 + 0.27089947089947*G0_0_0_8_1_1 + 0.27089947089947*G0_0_0_9_1_0 - 0.27089947089947*G0_0_0_10_1_0 - 0.541798941798939*G0_0_0_10_1_1 - 0.27089947089947*G0_0_0_11_1_0; + A[317] = 0.0; + A[470] = A[5]; + A[358] = 0.0; + A[7] = A[765] + 1.04338624338624*G0_0_0_0_0_0 + 1.04338624338624*G0_0_0_0_0_1 + 0.0444444444444449*G0_0_0_1_0_0 + 0.573544973544974*G0_0_0_2_0_1 + 0.148148148148149*G0_0_0_3_0_0 - 0.380952380952381*G0_0_0_3_0_1 - 0.148148148148149*G0_0_0_4_0_0 - 1.61693121693122*G0_0_0_4_0_1 - 1.08783068783069*G0_0_0_5_0_0 + 0.380952380952381*G0_0_0_5_0_1 + 1.04338624338624*G0_0_0_6_1_0 + 1.04338624338624*G0_0_0_6_1_1 + 0.0444444444444449*G0_0_0_7_1_0 + 0.573544973544974*G0_0_0_8_1_1 + 0.148148148148149*G0_0_0_9_1_0 - 0.380952380952381*G0_0_0_9_1_1 - 0.148148148148149*G0_0_0_10_1_0 - 1.61693121693122*G0_0_0_10_1_1 - 1.08783068783069*G0_0_0_11_1_0 + 0.380952380952381*G0_0_0_11_1_1 - 0.250440917107583*G0_0_1_1_0_0 + 0.250440917107584*G0_0_1_2_0_1 + 0.250440917107584*G0_0_1_3_0_0 - 0.250440917107583*G0_0_1_3_0_1 - 0.250440917107584*G0_0_1_4_0_0 - 0.250440917107587*G0_0_1_4_0_1 + 0.250440917107581*G0_0_1_5_0_0 + 0.250440917107583*G0_0_1_5_0_1 - 0.250440917107583*G0_0_1_7_1_0 + 0.250440917107584*G0_0_1_8_1_1 + 0.250440917107584*G0_0_1_9_1_0 - 0.250440917107583*G0_0_1_9_1_1 - 0.250440917107584*G0_0_1_10_1_0 - 0.250440917107587*G0_0_1_10_1_1 + 0.250440917107581*G0_0_1_11_1_0 + 0.250440917107583*G0_0_1_11_1_1 - 0.278659611992945*G0_1_0_1_0_0 + 0.278659611992947*G0_1_0_2_0_1 + 0.278659611992946*G0_1_0_3_0_0 - 0.278659611992945*G0_1_0_3_0_1 - 0.278659611992946*G0_1_0_4_0_0 - 0.278659611992949*G0_1_0_4_0_1 + 0.278659611992942*G0_1_0_5_0_0 + 0.278659611992945*G0_1_0_5_0_1 - 0.278659611992945*G0_1_0_7_1_0 + 0.278659611992947*G0_1_0_8_1_1 + 0.278659611992946*G0_1_0_9_1_0 - 0.278659611992945*G0_1_0_9_1_1 - 0.278659611992946*G0_1_0_10_1_0 - 0.278659611992949*G0_1_0_10_1_1 + 0.278659611992942*G0_1_0_11_1_0 + 0.278659611992945*G0_1_0_11_1_1 - 1.04338624338624*G0_1_1_0_0_0 - 1.04338624338624*G0_1_1_0_0_1 - 0.573544973544972*G0_1_1_1_0_0 - 0.0444444444444432*G0_1_1_2_0_1 + 0.380952380952381*G0_1_1_3_0_0 - 0.148148148148147*G0_1_1_3_0_1 - 0.380952380952381*G0_1_1_4_0_0 + 1.08783068783068*G0_1_1_4_0_1 + 1.61693121693121*G0_1_1_5_0_0 + 0.148148148148147*G0_1_1_5_0_1 - 1.04338624338624*G0_1_1_6_1_0 - 1.04338624338624*G0_1_1_6_1_1 - 0.573544973544972*G0_1_1_7_1_0 - 0.0444444444444432*G0_1_1_8_1_1 + 0.380952380952381*G0_1_1_9_1_0 - 0.148148148148147*G0_1_1_9_1_1 - 0.380952380952381*G0_1_1_10_1_0 + 1.08783068783068*G0_1_1_10_1_1 + 1.61693121693121*G0_1_1_11_1_0 + 0.148148148148147*G0_1_1_11_1_1; + A[724] = 0.0; + A[827] = A[887] + 0.812698412698414*G0_1_1_0_0_0 + 0.812698412698414*G0_1_1_0_0_1 - 0.541798941798942*G0_1_1_1_0_0 + 1.35449735449736*G0_1_1_2_0_1 + 1.35449735449736*G0_1_1_3_0_0 - 0.54179894179894*G0_1_1_3_0_1 - 1.35449735449736*G0_1_1_4_0_0 - 2.16719576719577*G0_1_1_4_0_1 - 0.270899470899472*G0_1_1_5_0_0 + 0.54179894179894*G0_1_1_5_0_1 + 0.812698412698414*G0_1_1_6_1_0 + 0.812698412698414*G0_1_1_6_1_1 - 0.541798941798942*G0_1_1_7_1_0 + 1.35449735449736*G0_1_1_8_1_1 + 1.35449735449736*G0_1_1_9_1_0 - 0.54179894179894*G0_1_1_9_1_1 - 1.35449735449736*G0_1_1_10_1_0 - 2.16719576719577*G0_1_1_10_1_1 - 0.270899470899472*G0_1_1_11_1_0 + 0.54179894179894*G0_1_1_11_1_1; + A[72] = A[827] + 0.0282186948853606*G0_0_1_0_0_0 + 0.0282186948853606*G0_0_1_0_0_1 + 0.0282186948853616*G0_0_1_1_0_0 + 0.0282186948853607*G0_0_1_3_0_1 - 0.0282186948853586*G0_0_1_4_0_1 - 0.0564373897707222*G0_0_1_5_0_0 - 0.0282186948853607*G0_0_1_5_0_1 + 0.0282186948853606*G0_0_1_6_1_0 + 0.0282186948853606*G0_0_1_6_1_1 + 0.0282186948853616*G0_0_1_7_1_0 + 0.0282186948853607*G0_0_1_9_1_1 - 0.0282186948853586*G0_0_1_10_1_1 - 0.0564373897707222*G0_0_1_11_1_0 - 0.0282186948853607*G0_0_1_11_1_1 - 0.0282186948853607*G0_1_0_0_0_0 - 0.0282186948853606*G0_1_0_0_0_1 - 0.0282186948853616*G0_1_0_1_0_0 - 0.0282186948853606*G0_1_0_3_0_1 + 0.0282186948853586*G0_1_0_4_0_1 + 0.0564373897707223*G0_1_0_5_0_0 + 0.0282186948853607*G0_1_0_5_0_1 - 0.0282186948853607*G0_1_0_6_1_0 - 0.0282186948853606*G0_1_0_6_1_1 - 0.0282186948853616*G0_1_0_7_1_0 - 0.0282186948853606*G0_1_0_9_1_1 + 0.0282186948853586*G0_1_0_10_1_1 + 0.0564373897707223*G0_1_0_11_1_0 + 0.0282186948853607*G0_1_0_11_1_1; + A[36] = A[181] + 0.0310405643738986*G0_0_1_0_0_0 + 0.0310405643738986*G0_0_1_0_0_1 + 0.0310405643738977*G0_0_1_2_0_1 + 0.0310405643738978*G0_0_1_3_0_0 - 0.0310405643738978*G0_0_1_4_0_0 - 0.0620811287477962*G0_0_1_4_0_1 - 0.0310405643738996*G0_0_1_5_0_0 + 0.0310405643738986*G0_0_1_6_1_0 + 0.0310405643738986*G0_0_1_6_1_1 + 0.0310405643738977*G0_0_1_8_1_1 + 0.0310405643738978*G0_0_1_9_1_0 - 0.0310405643738978*G0_0_1_10_1_0 - 0.0620811287477962*G0_0_1_10_1_1 - 0.0310405643738996*G0_0_1_11_1_0 - 0.0310405643738986*G0_1_0_0_0_0 - 0.0310405643738986*G0_1_0_0_0_1 - 0.0310405643738977*G0_1_0_2_0_1 - 0.0310405643738978*G0_1_0_3_0_0 + 0.0310405643738978*G0_1_0_4_0_0 + 0.0620811287477962*G0_1_0_4_0_1 + 0.0310405643738996*G0_1_0_5_0_0 - 0.0310405643738986*G0_1_0_6_1_0 - 0.0310405643738986*G0_1_0_6_1_1 - 0.0310405643738977*G0_1_0_8_1_1 - 0.0310405643738978*G0_1_0_9_1_0 + 0.0310405643738978*G0_1_0_10_1_0 + 0.0620811287477962*G0_1_0_10_1_1 + 0.0310405643738996*G0_1_0_11_1_0; + A[751] = 0.0; + A[65] = A[530]; + A[786] = 0.0; + A[114] = 0.0; + A[139] = 0.0; + A[168] = 0.0; + A[502] = -0.0514991181657851*G0_0_0_0_0_0 - 0.0514991181657851*G0_0_0_0_0_1 - 0.0811287477954157*G0_0_0_1_0_0 + 0.0719576719576722*G0_0_0_2_0_1 + 0.114285714285714*G0_0_0_3_0_0 - 0.038800705467374*G0_0_0_3_0_1 - 0.114285714285714*G0_0_0_4_0_0 - 0.020458553791887*G0_0_0_4_0_1 + 0.132627865961201*G0_0_0_5_0_0 + 0.038800705467374*G0_0_0_5_0_1 - 0.0514991181657851*G0_0_0_6_1_0 - 0.0514991181657851*G0_0_0_6_1_1 - 0.0811287477954157*G0_0_0_7_1_0 + 0.0719576719576722*G0_0_0_8_1_1 + 0.114285714285714*G0_0_0_9_1_0 - 0.038800705467374*G0_0_0_9_1_1 - 0.114285714285714*G0_0_0_10_1_0 - 0.020458553791887*G0_0_0_10_1_1 + 0.132627865961201*G0_0_0_11_1_0 + 0.038800705467374*G0_0_0_11_1_1 + 0.020458553791886*G0_0_1_0_0_0 + 0.020458553791886*G0_0_1_0_0_1 + 0.0204585537918875*G0_0_1_2_0_1 + 0.0204585537918871*G0_0_1_3_0_0 - 0.0204585537918871*G0_0_1_4_0_0 - 0.0409171075837735*G0_0_1_4_0_1 - 0.0204585537918841*G0_0_1_5_0_0 + 0.020458553791886*G0_0_1_6_1_0 + 0.020458553791886*G0_0_1_6_1_1 + 0.0204585537918875*G0_0_1_8_1_1 + 0.0204585537918871*G0_0_1_9_1_0 - 0.0204585537918871*G0_0_1_10_1_0 - 0.0409171075837735*G0_0_1_10_1_1 - 0.0204585537918841*G0_0_1_11_1_0; + A[205] = 0.0; + A[573] = 0.0; + A[533] = -A[530] - 0.0451499118165791*G0_1_1_0_0_0 - 0.0451499118165791*G0_1_1_0_0_1 + 0.0451499118165782*G0_1_1_1_0_0 - 0.615167548500882*G0_1_1_2_0_1 - 1.14003527336861*G0_1_1_3_0_0 - 0.479717813051146*G0_1_1_3_0_1 + 1.14003527336861*G0_1_1_4_0_0 + 0.660317460317461*G0_1_1_4_0_1 + 0.479717813051146*G0_1_1_5_0_1 - 0.0451499118165791*G0_1_1_6_1_0 - 0.0451499118165791*G0_1_1_6_1_1 + 0.0451499118165782*G0_1_1_7_1_0 - 0.615167548500882*G0_1_1_8_1_1 - 1.14003527336861*G0_1_1_9_1_0 - 0.479717813051146*G0_1_1_9_1_1 + 1.14003527336861*G0_1_1_10_1_0 + 0.660317460317461*G0_1_1_10_1_1 + 0.479717813051146*G0_1_1_11_1_1; + A[238] = 0.0; + A[604] = 0.0; + A[715] = -A[625] - 0.12416225749559*G0_1_0_0_0_0 - 0.12416225749559*G0_1_0_0_0_1 - 0.124162257495589*G0_1_0_1_0_0 - 0.124162257495588*G0_1_0_3_0_1 + 0.124162257495589*G0_1_0_4_0_1 + 0.248324514991179*G0_1_0_5_0_0 + 0.124162257495588*G0_1_0_5_0_1 - 0.12416225749559*G0_1_0_6_1_0 - 0.12416225749559*G0_1_0_6_1_1 - 0.124162257495589*G0_1_0_7_1_0 - 0.124162257495588*G0_1_0_9_1_1 + 0.124162257495589*G0_1_0_10_1_1 + 0.248324514991179*G0_1_0_11_1_0 + 0.124162257495588*G0_1_0_11_1_1 + 0.2652557319224*G0_1_1_0_0_0 + 0.2652557319224*G0_1_1_0_0_1 - 0.389417989417987*G0_1_1_1_0_0 + 0.434567901234568*G0_1_1_2_0_1 + 0.21446208112875*G0_1_1_3_0_0 - 0.609523809523806*G0_1_1_3_0_1 - 0.21446208112875*G0_1_1_4_0_0 - 0.699823633156968*G0_1_1_4_0_1 + 0.124162257495587*G0_1_1_5_0_0 + 0.609523809523806*G0_1_1_5_0_1 + 0.2652557319224*G0_1_1_6_1_0 + 0.2652557319224*G0_1_1_6_1_1 - 0.389417989417987*G0_1_1_7_1_0 + 0.434567901234568*G0_1_1_8_1_1 + 0.21446208112875*G0_1_1_9_1_0 - 0.609523809523806*G0_1_1_9_1_1 - 0.21446208112875*G0_1_1_10_1_0 - 0.699823633156968*G0_1_1_10_1_1 + 0.124162257495587*G0_1_1_11_1_0 + 0.609523809523806*G0_1_1_11_1_1; + A[242] = A[533] - 0.595414462081129*G0_0_1_0_0_0 - 0.595414462081129*G0_0_1_0_0_1 + 0.595414462081129*G0_0_1_1_0_0 - 1.96966490299823*G0_0_1_2_0_1 - 2.74850088183421*G0_0_1_3_0_0 - 0.183421516754849*G0_0_1_3_0_1 + 2.74850088183421*G0_0_1_4_0_0 + 2.56507936507936*G0_0_1_4_0_1 + 0.183421516754849*G0_0_1_5_0_1 - 0.595414462081129*G0_0_1_6_1_0 - 0.595414462081129*G0_0_1_6_1_1 + 0.595414462081129*G0_0_1_7_1_0 - 1.96966490299823*G0_0_1_8_1_1 - 2.74850088183421*G0_0_1_9_1_0 - 0.183421516754849*G0_0_1_9_1_1 + 2.74850088183421*G0_0_1_10_1_0 + 2.56507936507936*G0_0_1_10_1_1 + 0.183421516754849*G0_0_1_11_1_1 + 0.595414462081129*G0_1_0_0_0_0 + 0.595414462081129*G0_1_0_0_0_1 - 0.595414462081129*G0_1_0_1_0_0 + 1.96966490299824*G0_1_0_2_0_1 + 2.74850088183421*G0_1_0_3_0_0 + 0.183421516754849*G0_1_0_3_0_1 - 2.74850088183421*G0_1_0_4_0_0 - 2.56507936507936*G0_1_0_4_0_1 - 0.183421516754849*G0_1_0_5_0_1 + 0.595414462081129*G0_1_0_6_1_0 + 0.595414462081129*G0_1_0_6_1_1 - 0.595414462081129*G0_1_0_7_1_0 + 1.96966490299824*G0_1_0_8_1_1 + 2.74850088183421*G0_1_0_9_1_0 + 0.183421516754849*G0_1_0_9_1_1 - 2.74850088183421*G0_1_0_10_1_0 - 2.56507936507936*G0_1_0_10_1_1 - 0.183421516754849*G0_1_0_11_1_1; + A[444] = 0.0; + A[324] = 0.0; + A[479] = A[14]; + A[351] = 0.0; + A[731] = 0.0; + A[422] = A[887]; + A[382] = 0.0; + A[760] = 0.0; + A[413] = 0.0; + A[857] = A[827] - 0.270899470899472*G0_1_1_0_0_0 - 0.270899470899472*G0_1_1_0_0_1 - 0.270899470899471*G0_1_1_1_0_0 - 0.270899470899473*G0_1_1_3_0_1 + 0.270899470899475*G0_1_1_4_0_1 + 0.541798941798942*G0_1_1_5_0_0 + 0.270899470899473*G0_1_1_5_0_1 - 0.270899470899472*G0_1_1_6_1_0 - 0.270899470899472*G0_1_1_6_1_1 - 0.270899470899471*G0_1_1_7_1_0 - 0.270899470899473*G0_1_1_9_1_1 + 0.270899470899475*G0_1_1_10_1_1 + 0.541798941798942*G0_1_1_11_1_0 + 0.270899470899473*G0_1_1_11_1_1; + A[88] = 0.0; + A[781] = 0.0; + A[91] = -A[331] - 0.0451499118165792*G0_0_0_0_0_0 - 0.0451499118165794*G0_0_0_0_0_1 - 0.615167548500884*G0_0_0_1_0_0 + 0.0451499118165795*G0_0_0_2_0_1 - 0.479717813051145*G0_0_0_3_0_0 - 1.14003527336861*G0_0_0_3_0_1 + 0.479717813051145*G0_0_0_4_0_0 + 0.660317460317463*G0_0_0_5_0_0 + 1.14003527336861*G0_0_0_5_0_1 - 0.0451499118165792*G0_0_0_6_1_0 - 0.0451499118165794*G0_0_0_6_1_1 - 0.615167548500884*G0_0_0_7_1_0 + 0.0451499118165795*G0_0_0_8_1_1 - 0.479717813051145*G0_0_0_9_1_0 - 1.14003527336861*G0_0_0_9_1_1 + 0.479717813051145*G0_0_0_10_1_0 + 0.660317460317463*G0_0_0_11_1_0 + 1.14003527336861*G0_0_0_11_1_1; + A[822] = 0.0; + A[146] = 0.0; + A[855] = A[14] - 0.270899470899469*G0_0_0_1_0_0 + 0.270899470899471*G0_0_0_2_0_1 + 0.270899470899471*G0_0_0_3_0_0 - 0.270899470899469*G0_0_0_3_0_1 - 0.270899470899471*G0_0_0_4_0_0 - 0.270899470899473*G0_0_0_4_0_1 + 0.270899470899467*G0_0_0_5_0_0 + 0.270899470899469*G0_0_0_5_0_1 - 0.270899470899469*G0_0_0_7_1_0 + 0.270899470899471*G0_0_0_8_1_1 + 0.270899470899471*G0_0_0_9_1_0 - 0.270899470899469*G0_0_0_9_1_1 - 0.270899470899471*G0_0_0_10_1_0 - 0.270899470899473*G0_0_0_10_1_1 + 0.270899470899467*G0_0_0_11_1_0 + 0.270899470899469*G0_0_0_11_1_1 - 0.242680776014107*G0_0_1_1_0_0 + 0.24268077601411*G0_0_1_2_0_1 + 0.242680776014109*G0_0_1_3_0_0 - 0.242680776014107*G0_0_1_3_0_1 - 0.242680776014109*G0_0_1_4_0_0 - 0.242680776014113*G0_0_1_4_0_1 + 0.242680776014104*G0_0_1_5_0_0 + 0.242680776014107*G0_0_1_5_0_1 - 0.242680776014107*G0_0_1_7_1_0 + 0.24268077601411*G0_0_1_8_1_1 + 0.242680776014109*G0_0_1_9_1_0 - 0.242680776014107*G0_0_1_9_1_1 - 0.242680776014109*G0_0_1_10_1_0 - 0.242680776014113*G0_0_1_10_1_1 + 0.242680776014104*G0_0_1_11_1_0 + 0.242680776014107*G0_0_1_11_1_1 - 0.29911816578483*G0_1_0_1_0_0 + 0.299118165784834*G0_1_0_2_0_1 + 0.299118165784833*G0_1_0_3_0_0 - 0.299118165784831*G0_1_0_3_0_1 - 0.299118165784833*G0_1_0_4_0_0 - 0.299118165784837*G0_1_0_4_0_1 + 0.299118165784826*G0_1_0_5_0_0 + 0.299118165784831*G0_1_0_5_0_1 - 0.29911816578483*G0_1_0_7_1_0 + 0.299118165784834*G0_1_0_8_1_1 + 0.299118165784833*G0_1_0_9_1_0 - 0.299118165784831*G0_1_0_9_1_1 - 0.299118165784833*G0_1_0_10_1_0 - 0.299118165784837*G0_1_0_10_1_1 + 0.299118165784826*G0_1_0_11_1_0 + 0.299118165784831*G0_1_0_11_1_1 - 0.270899470899468*G0_1_1_1_0_0 + 0.270899470899472*G0_1_1_2_0_1 + 0.270899470899472*G0_1_1_3_0_0 - 0.270899470899469*G0_1_1_3_0_1 - 0.270899470899472*G0_1_1_4_0_0 - 0.270899470899478*G0_1_1_4_0_1 + 0.270899470899463*G0_1_1_5_0_0 + 0.270899470899469*G0_1_1_5_0_1 - 0.270899470899468*G0_1_1_7_1_0 + 0.270899470899472*G0_1_1_8_1_1 + 0.270899470899472*G0_1_1_9_1_0 - 0.270899470899469*G0_1_1_9_1_1 - 0.270899470899472*G0_1_1_10_1_0 - 0.270899470899478*G0_1_1_10_1_1 + 0.270899470899463*G0_1_1_11_1_0 + 0.270899470899469*G0_1_1_11_1_1; + A[177] = 0.0; + A[884] = 0.0; + A[493] = 0.0; + A[196] = 0.0; + A[578] = 0.0; + A[518] = 0.0; + A[231] = 0.0; + A[603] = 0.0; + A[555] = A[5] + 0.146737213403879*G0_0_0_1_0_0 - 0.14673721340388*G0_0_0_2_0_1 - 0.146737213403881*G0_0_0_3_0_0 + 0.146737213403879*G0_0_0_3_0_1 + 0.146737213403881*G0_0_0_4_0_0 + 0.14673721340388*G0_0_0_4_0_1 - 0.146737213403879*G0_0_0_5_0_0 - 0.146737213403879*G0_0_0_5_0_1 + 0.146737213403879*G0_0_0_7_1_0 - 0.14673721340388*G0_0_0_8_1_1 - 0.146737213403881*G0_0_0_9_1_0 + 0.146737213403879*G0_0_0_9_1_1 + 0.146737213403881*G0_0_0_10_1_0 + 0.14673721340388*G0_0_0_10_1_1 - 0.146737213403879*G0_0_0_11_1_0 - 0.146737213403879*G0_0_0_11_1_1 + 0.115696649029981*G0_0_1_1_0_0 - 0.115696649029982*G0_0_1_2_0_1 - 0.115696649029982*G0_0_1_3_0_0 + 0.115696649029981*G0_0_1_3_0_1 + 0.115696649029982*G0_0_1_4_0_0 + 0.115696649029982*G0_0_1_4_0_1 - 0.115696649029981*G0_0_1_5_0_0 - 0.115696649029981*G0_0_1_5_0_1 + 0.115696649029981*G0_0_1_7_1_0 - 0.115696649029982*G0_0_1_8_1_1 - 0.115696649029982*G0_0_1_9_1_0 + 0.115696649029981*G0_0_1_9_1_1 + 0.115696649029982*G0_0_1_10_1_0 + 0.115696649029982*G0_0_1_10_1_1 - 0.115696649029981*G0_0_1_11_1_0 - 0.115696649029981*G0_0_1_11_1_1 + 0.177777777777778*G0_1_0_1_0_0 - 0.177777777777779*G0_1_0_2_0_1 - 0.17777777777778*G0_1_0_3_0_0 + 0.177777777777777*G0_1_0_3_0_1 + 0.17777777777778*G0_1_0_4_0_0 + 0.177777777777779*G0_1_0_4_0_1 - 0.177777777777778*G0_1_0_5_0_0 - 0.177777777777777*G0_1_0_5_0_1 + 0.177777777777778*G0_1_0_7_1_0 - 0.177777777777779*G0_1_0_8_1_1 - 0.17777777777778*G0_1_0_9_1_0 + 0.177777777777777*G0_1_0_9_1_1 + 0.17777777777778*G0_1_0_10_1_0 + 0.177777777777779*G0_1_0_10_1_1 - 0.177777777777778*G0_1_0_11_1_0 - 0.177777777777777*G0_1_0_11_1_1 + 0.14673721340388*G0_1_1_1_0_0 - 0.14673721340388*G0_1_1_2_0_1 - 0.14673721340388*G0_1_1_3_0_0 + 0.146737213403879*G0_1_1_3_0_1 + 0.14673721340388*G0_1_1_4_0_0 + 0.146737213403879*G0_1_1_4_0_1 - 0.14673721340388*G0_1_1_5_0_0 - 0.146737213403879*G0_1_1_5_0_1 + 0.14673721340388*G0_1_1_7_1_0 - 0.14673721340388*G0_1_1_8_1_1 - 0.14673721340388*G0_1_1_9_1_0 + 0.146737213403879*G0_1_1_9_1_1 + 0.14673721340388*G0_1_1_10_1_0 + 0.146737213403879*G0_1_1_10_1_1 - 0.14673721340388*G0_1_1_11_1_0 - 0.146737213403879*G0_1_1_11_1_1; + A[632] = 0.0; + A[669] = 0.0; + A[274] = A[625] - 0.203174603174602*G0_0_0_0_0_0 - 0.203174603174602*G0_0_0_0_0_1 - 0.0677248677248682*G0_0_0_1_0_0 - 0.203174603174601*G0_0_0_2_0_1 - 0.270899470899468*G0_0_0_3_0_0 - 0.135449735449735*G0_0_0_3_0_1 + 0.270899470899468*G0_0_0_4_0_0 + 0.406349206349204*G0_0_0_4_0_1 + 0.270899470899471*G0_0_0_5_0_0 + 0.135449735449735*G0_0_0_5_0_1 - 0.203174603174602*G0_0_0_6_1_0 - 0.203174603174602*G0_0_0_6_1_1 - 0.0677248677248682*G0_0_0_7_1_0 - 0.203174603174601*G0_0_0_8_1_1 - 0.270899470899468*G0_0_0_9_1_0 - 0.135449735449735*G0_0_0_9_1_1 + 0.270899470899468*G0_0_0_10_1_0 + 0.406349206349204*G0_0_0_10_1_1 + 0.270899470899471*G0_0_0_11_1_0 + 0.135449735449735*G0_0_0_11_1_1 - 0.237037037037036*G0_0_1_0_0_0 - 0.237037037037037*G0_0_1_0_0_1 - 0.135449735449734*G0_0_1_1_0_0 - 0.16931216931217*G0_0_1_2_0_1 - 0.237037037037038*G0_0_1_3_0_0 - 0.203174603174601*G0_0_1_3_0_1 + 0.237037037037038*G0_0_1_4_0_0 + 0.406349206349207*G0_0_1_4_0_1 + 0.37248677248677*G0_0_1_5_0_0 + 0.203174603174601*G0_0_1_5_0_1 - 0.237037037037036*G0_0_1_6_1_0 - 0.237037037037037*G0_0_1_6_1_1 - 0.135449735449734*G0_0_1_7_1_0 - 0.16931216931217*G0_0_1_8_1_1 - 0.237037037037038*G0_0_1_9_1_0 - 0.203174603174601*G0_0_1_9_1_1 + 0.237037037037038*G0_0_1_10_1_0 + 0.406349206349207*G0_0_1_10_1_1 + 0.37248677248677*G0_0_1_11_1_0 + 0.203174603174601*G0_0_1_11_1_1 - 0.169312169312168*G0_1_0_0_0_0 - 0.169312169312168*G0_1_0_0_0_1 - 0.237037037037036*G0_1_0_2_0_1 - 0.304761904761905*G0_1_0_3_0_0 - 0.0677248677248709*G0_1_0_3_0_1 + 0.304761904761905*G0_1_0_4_0_0 + 0.406349206349204*G0_1_0_4_0_1 + 0.16931216931217*G0_1_0_5_0_0 + 0.0677248677248709*G0_1_0_5_0_1 - 0.169312169312168*G0_1_0_6_1_0 - 0.169312169312168*G0_1_0_6_1_1 - 0.237037037037036*G0_1_0_8_1_1 - 0.304761904761905*G0_1_0_9_1_0 - 0.0677248677248709*G0_1_0_9_1_1 + 0.304761904761905*G0_1_0_10_1_0 + 0.406349206349204*G0_1_0_10_1_1 + 0.16931216931217*G0_1_0_11_1_0 + 0.0677248677248709*G0_1_0_11_1_1 - 0.406349206349206*G0_1_1_0_0_0 - 0.406349206349206*G0_1_1_0_0_1 - 0.406349206349206*G0_1_1_2_0_1 - 0.406349206349208*G0_1_1_3_0_0 + 0.406349206349208*G0_1_1_4_0_0 + 0.812698412698412*G0_1_1_4_0_1 + 0.406349206349208*G0_1_1_5_0_0 - 0.406349206349206*G0_1_1_6_1_0 - 0.406349206349206*G0_1_1_6_1_1 - 0.406349206349206*G0_1_1_8_1_1 - 0.406349206349208*G0_1_1_9_1_0 + 0.406349206349208*G0_1_1_10_1_0 + 0.812698412698412*G0_1_1_10_1_1 + 0.406349206349208*G0_1_1_11_1_0; + A[125] = A[274] - 0.186243386243385*G0_0_0_0_0_0 - 0.186243386243385*G0_0_0_0_0_1 + 0.93121693121693*G0_0_0_1_0_0 - 1.81164021164021*G0_0_0_2_0_1 - 2.50582010582009*G0_0_0_3_0_0 + 0.23703703703704*G0_0_0_3_0_1 + 2.50582010582009*G0_0_0_4_0_0 + 1.99788359788359*G0_0_0_4_0_1 - 0.744973544973545*G0_0_0_5_0_0 - 0.237037037037039*G0_0_0_5_0_1 - 0.186243386243385*G0_0_0_6_1_0 - 0.186243386243385*G0_0_0_6_1_1 + 0.93121693121693*G0_0_0_7_1_0 - 1.81164021164021*G0_0_0_8_1_1 - 2.50582010582009*G0_0_0_9_1_0 + 0.23703703703704*G0_0_0_9_1_1 + 2.50582010582009*G0_0_0_10_1_0 + 1.99788359788359*G0_0_0_10_1_1 - 0.744973544973545*G0_0_0_11_1_0 - 0.237037037037039*G0_0_0_11_1_1 + 0.874779541446208*G0_0_1_0_0_0 + 0.874779541446208*G0_0_1_0_0_1 + 0.49100529100529*G0_0_1_1_0_0 + 1.31499118165785*G0_0_1_2_0_1 + 2.24620811287478*G0_0_1_3_0_0 + 1.42222222222222*G0_0_1_3_0_1 - 2.24620811287478*G0_0_1_4_0_0 - 2.18977072310406*G0_0_1_4_0_1 - 1.3657848324515*G0_0_1_5_0_0 - 1.42222222222222*G0_0_1_5_0_1 + 0.874779541446208*G0_0_1_6_1_0 + 0.874779541446208*G0_0_1_6_1_1 + 0.49100529100529*G0_0_1_7_1_0 + 1.31499118165785*G0_0_1_8_1_1 + 2.24620811287478*G0_0_1_9_1_0 + 1.42222222222222*G0_0_1_9_1_1 - 2.24620811287478*G0_0_1_10_1_0 - 2.18977072310406*G0_0_1_10_1_1 - 1.3657848324515*G0_0_1_11_1_0 - 1.42222222222222*G0_0_1_11_1_1 + 0.0395061728395061*G0_1_0_0_0_0 + 0.0395061728395063*G0_1_0_0_0_1 + 0.186243386243387*G0_1_0_1_0_0 - 0.332980599647264*G0_1_0_2_0_1 - 0.519223985890646*G0_1_0_3_0_0 + 0.519223985890646*G0_1_0_4_0_0 + 0.293474426807757*G0_1_0_4_0_1 - 0.225749559082893*G0_1_0_5_0_0 + 0.0395061728395061*G0_1_0_6_1_0 + 0.0395061728395063*G0_1_0_6_1_1 + 0.186243386243387*G0_1_0_7_1_0 - 0.332980599647264*G0_1_0_8_1_1 - 0.519223985890646*G0_1_0_9_1_0 + 0.519223985890646*G0_1_0_10_1_0 + 0.293474426807757*G0_1_0_10_1_1 - 0.225749559082893*G0_1_0_11_1_0 + 0.0338624338624336*G0_1_1_0_0_0 + 0.0338624338624334*G0_1_1_0_0_1 - 0.982010582010582*G0_1_1_1_0_0 + 0.50793650793651*G0_1_1_2_0_1 - 1.48994708994709*G0_1_1_3_0_1 - 0.541798941798944*G0_1_1_4_0_1 + 0.948148148148149*G0_1_1_5_0_0 + 1.48994708994709*G0_1_1_5_0_1 + 0.0338624338624336*G0_1_1_6_1_0 + 0.0338624338624334*G0_1_1_6_1_1 - 0.982010582010582*G0_1_1_7_1_0 + 0.50793650793651*G0_1_1_8_1_1 - 1.48994708994709*G0_1_1_9_1_1 - 0.541798941798944*G0_1_1_10_1_1 + 0.948148148148149*G0_1_1_11_1_0 + 1.48994708994709*G0_1_1_11_1_1; + A[559] = A[125] + 0.214462081128746*G0_0_0_0_0_0 + 0.214462081128746*G0_0_0_0_0_1 - 0.530511463844798*G0_0_0_1_0_0 + 0.846560846560842*G0_0_0_2_0_1 + 0.948148148148139*G0_0_0_3_0_0 - 0.428924162257499*G0_0_0_3_0_1 - 0.948148148148139*G0_0_0_4_0_0 - 1.06102292768959*G0_0_0_4_0_1 + 0.316049382716052*G0_0_0_5_0_0 + 0.428924162257499*G0_0_0_5_0_1 + 0.214462081128746*G0_0_0_6_1_0 + 0.214462081128746*G0_0_0_6_1_1 - 0.530511463844798*G0_0_0_7_1_0 + 0.846560846560842*G0_0_0_8_1_1 + 0.948148148148139*G0_0_0_9_1_0 - 0.428924162257499*G0_0_0_9_1_1 - 0.948148148148139*G0_0_0_10_1_0 - 1.06102292768959*G0_0_0_10_1_1 + 0.316049382716052*G0_0_0_11_1_0 + 0.428924162257499*G0_0_0_11_1_1 + 0.81269841269841*G0_0_1_1_0_0 - 0.812698412698415*G0_0_1_2_0_1 - 0.812698412698417*G0_0_1_3_0_0 + 0.812698412698409*G0_0_1_3_0_1 + 0.812698412698417*G0_0_1_4_0_0 + 0.812698412698417*G0_0_1_4_0_1 - 0.812698412698409*G0_0_1_5_0_0 - 0.812698412698408*G0_0_1_5_0_1 + 0.81269841269841*G0_0_1_7_1_0 - 0.812698412698415*G0_0_1_8_1_1 - 0.812698412698417*G0_0_1_9_1_0 + 0.812698412698409*G0_0_1_9_1_1 + 0.812698412698417*G0_0_1_10_1_0 + 0.812698412698417*G0_0_1_10_1_1 - 0.812698412698409*G0_0_1_11_1_0 - 0.812698412698408*G0_0_1_11_1_1 - 0.654673721340387*G0_1_0_1_0_0 + 0.654673721340385*G0_1_0_2_0_1 + 0.654673721340383*G0_1_0_3_0_0 - 0.654673721340388*G0_1_0_3_0_1 - 0.654673721340383*G0_1_0_4_0_0 - 0.654673721340384*G0_1_0_4_0_1 + 0.654673721340387*G0_1_0_5_0_0 + 0.654673721340388*G0_1_0_5_0_1 - 0.654673721340387*G0_1_0_7_1_0 + 0.654673721340385*G0_1_0_8_1_1 + 0.654673721340383*G0_1_0_9_1_0 - 0.654673721340388*G0_1_0_9_1_1 - 0.654673721340383*G0_1_0_10_1_0 - 0.654673721340384*G0_1_0_10_1_1 + 0.654673721340387*G0_1_0_11_1_0 + 0.654673721340388*G0_1_0_11_1_1 - 0.214462081128749*G0_1_1_0_0_0 - 0.214462081128749*G0_1_1_0_0_1 - 0.846560846560849*G0_1_1_1_0_0 + 0.530511463844795*G0_1_1_2_0_1 + 0.428924162257492*G0_1_1_3_0_0 - 0.948148148148151*G0_1_1_3_0_1 - 0.428924162257492*G0_1_1_4_0_0 - 0.316049382716046*G0_1_1_4_0_1 + 1.0610229276896*G0_1_1_5_0_0 + 0.948148148148152*G0_1_1_5_0_1 - 0.214462081128749*G0_1_1_6_1_0 - 0.214462081128749*G0_1_1_6_1_1 - 0.846560846560849*G0_1_1_7_1_0 + 0.530511463844795*G0_1_1_8_1_1 + 0.428924162257492*G0_1_1_9_1_0 - 0.948148148148151*G0_1_1_9_1_1 - 0.428924162257492*G0_1_1_10_1_0 - 0.316049382716046*G0_1_1_10_1_1 + 1.0610229276896*G0_1_1_11_1_0 + 0.948148148148152*G0_1_1_11_1_1; + A[588] = A[559] - 0.823985890652556*G0_0_1_0_0_0 - 0.823985890652556*G0_0_1_0_0_1 - 1.70440917107583*G0_0_1_1_0_0 - 0.237037037037037*G0_0_1_2_0_1 - 1.35449735449735*G0_0_1_3_0_0 - 2.82186948853615*G0_0_1_3_0_1 + 1.35449735449735*G0_0_1_4_0_0 + 1.06102292768959*G0_0_1_4_0_1 + 2.52839506172839*G0_0_1_5_0_0 + 2.82186948853615*G0_0_1_5_0_1 - 0.823985890652556*G0_0_1_6_1_0 - 0.823985890652556*G0_0_1_6_1_1 - 1.70440917107583*G0_0_1_7_1_0 - 0.237037037037037*G0_0_1_8_1_1 - 1.35449735449735*G0_0_1_9_1_0 - 2.82186948853615*G0_0_1_9_1_1 + 1.35449735449735*G0_0_1_10_1_0 + 1.06102292768959*G0_0_1_10_1_1 + 2.52839506172839*G0_0_1_11_1_0 + 2.82186948853615*G0_0_1_11_1_1 + 0.823985890652556*G0_1_0_0_0_0 + 0.823985890652556*G0_1_0_0_0_1 + 1.70440917107583*G0_1_0_1_0_0 + 0.237037037037037*G0_1_0_2_0_1 + 1.35449735449735*G0_1_0_3_0_0 + 2.82186948853615*G0_1_0_3_0_1 - 1.35449735449735*G0_1_0_4_0_0 - 1.06102292768959*G0_1_0_4_0_1 - 2.52839506172839*G0_1_0_5_0_0 - 2.82186948853615*G0_1_0_5_0_1 + 0.823985890652556*G0_1_0_6_1_0 + 0.823985890652556*G0_1_0_6_1_1 + 1.70440917107583*G0_1_0_7_1_0 + 0.237037037037037*G0_1_0_8_1_1 + 1.35449735449735*G0_1_0_9_1_0 + 2.82186948853615*G0_1_0_9_1_1 - 1.35449735449735*G0_1_0_10_1_0 - 1.06102292768959*G0_1_0_10_1_1 - 2.52839506172839*G0_1_0_11_1_0 - 2.82186948853615*G0_1_0_11_1_1; + A[309] = A[125] + 2.67513227513227*G0_0_0_0_0_0 + 2.67513227513227*G0_0_0_0_0_1 - 1.59153439153439*G0_0_0_1_0_0 + 3.08148148148147*G0_0_0_2_0_1 + 1.89629629629629*G0_0_0_3_0_0 - 2.77671957671958*G0_0_0_3_0_1 - 1.89629629629629*G0_0_0_4_0_0 - 5.75661375661375*G0_0_0_4_0_1 - 1.08359788359788*G0_0_0_5_0_0 + 2.77671957671958*G0_0_0_5_0_1 + 2.67513227513227*G0_0_0_6_1_0 + 2.67513227513227*G0_0_0_6_1_1 - 1.59153439153439*G0_0_0_7_1_0 + 3.08148148148147*G0_0_0_8_1_1 + 1.89629629629629*G0_0_0_9_1_0 - 2.77671957671958*G0_0_0_9_1_1 - 1.89629629629629*G0_0_0_10_1_0 - 5.75661375661375*G0_0_0_10_1_1 - 1.08359788359788*G0_0_0_11_1_0 + 2.77671957671958*G0_0_0_11_1_1 + 0.169312169312168*G0_0_1_0_0_0 + 0.169312169312168*G0_0_1_0_0_1 - 1.82857142857143*G0_0_1_1_0_0 - 0.304761904761907*G0_0_1_2_0_1 - 2.60740740740741*G0_0_1_3_0_0 - 4.13121693121693*G0_0_1_3_0_1 + 2.60740740740741*G0_0_1_4_0_0 + 0.135449735449739*G0_0_1_4_0_1 + 1.65925925925926*G0_0_1_5_0_0 + 4.13121693121693*G0_0_1_5_0_1 + 0.169312169312168*G0_0_1_6_1_0 + 0.169312169312168*G0_0_1_6_1_1 - 1.82857142857143*G0_0_1_7_1_0 - 0.304761904761907*G0_0_1_8_1_1 - 2.60740740740741*G0_0_1_9_1_0 - 4.13121693121693*G0_0_1_9_1_1 + 2.60740740740741*G0_0_1_10_1_0 + 0.135449735449739*G0_0_1_10_1_1 + 1.65925925925926*G0_0_1_11_1_0 + 4.13121693121693*G0_0_1_11_1_1 - 0.71111111111111*G0_1_0_0_0_0 - 0.71111111111111*G0_1_0_0_0_1 - 1.35449735449735*G0_1_0_1_0_0 + 0.575661375661374*G0_1_0_2_0_1 + 0.507936507936503*G0_1_0_3_0_0 - 1.42222222222222*G0_1_0_3_0_1 - 0.507936507936503*G0_1_0_4_0_0 + 0.135449735449736*G0_1_0_4_0_1 + 2.06560846560846*G0_1_0_5_0_0 + 1.42222222222222*G0_1_0_5_0_1 - 0.71111111111111*G0_1_0_6_1_0 - 0.71111111111111*G0_1_0_6_1_1 - 1.35449735449735*G0_1_0_7_1_0 + 0.575661375661374*G0_1_0_8_1_1 + 0.507936507936503*G0_1_0_9_1_0 - 1.42222222222222*G0_1_0_9_1_1 - 0.507936507936503*G0_1_0_10_1_0 + 0.135449735449736*G0_1_0_10_1_1 + 2.06560846560846*G0_1_0_11_1_0 + 1.42222222222222*G0_1_0_11_1_1 - 0.135449735449736*G0_1_1_0_0_0 - 0.135449735449736*G0_1_1_0_0_1 - 0.135449735449739*G0_1_1_2_0_1 - 0.135449735449738*G0_1_1_3_0_0 + 0.135449735449738*G0_1_1_4_0_0 + 0.270899470899475*G0_1_1_4_0_1 + 0.135449735449734*G0_1_1_5_0_0 - 0.135449735449736*G0_1_1_6_1_0 - 0.135449735449736*G0_1_1_6_1_1 - 0.135449735449739*G0_1_1_8_1_1 - 0.135449735449738*G0_1_1_9_1_0 + 0.135449735449738*G0_1_1_10_1_0 + 0.270899470899475*G0_1_1_10_1_1 + 0.135449735449734*G0_1_1_11_1_0; + A[334] = -A[559] - 0.0395061728395073*G0_0_0_0_0_0 - 0.0395061728395069*G0_0_0_0_0_1 + 0.603880070546735*G0_0_0_1_0_0 - 1.37142857142857*G0_0_0_2_0_1 - 2.09947089947089*G0_0_0_3_0_0 - 0.124162257495592*G0_0_0_3_0_1 + 2.09947089947089*G0_0_0_4_0_0 + 1.41093474426807*G0_0_0_4_0_1 - 0.564373897707228*G0_0_0_5_0_0 + 0.124162257495592*G0_0_0_5_0_1 - 0.0395061728395073*G0_0_0_6_1_0 - 0.0395061728395069*G0_0_0_6_1_1 + 0.603880070546735*G0_0_0_7_1_0 - 1.37142857142857*G0_0_0_8_1_1 - 2.09947089947089*G0_0_0_9_1_0 - 0.124162257495592*G0_0_0_9_1_1 + 2.09947089947089*G0_0_0_10_1_0 + 1.41093474426807*G0_0_0_10_1_1 - 0.564373897707228*G0_0_0_11_1_0 + 0.124162257495592*G0_0_0_11_1_1 + 1.06102292768959*G0_0_1_0_0_0 + 1.0610229276896*G0_0_1_0_0_1 + 2.06560846560847*G0_0_1_1_0_0 + 0.112874779541445*G0_0_1_2_0_1 + 1.23033509700176*G0_0_1_3_0_0 + 3.18306878306878*G0_0_1_3_0_1 - 1.23033509700176*G0_0_1_4_0_0 - 1.17389770723104*G0_0_1_4_0_1 - 3.12663139329806*G0_0_1_5_0_0 - 3.18306878306878*G0_0_1_5_0_1 + 1.06102292768959*G0_0_1_6_1_0 + 1.0610229276896*G0_0_1_6_1_1 + 2.06560846560847*G0_0_1_7_1_0 + 0.112874779541445*G0_0_1_8_1_1 + 1.23033509700176*G0_0_1_9_1_0 + 3.18306878306878*G0_0_1_9_1_1 - 1.23033509700176*G0_0_1_10_1_0 - 1.17389770723104*G0_0_1_10_1_1 - 3.12663139329806*G0_0_1_11_1_0 - 3.18306878306878*G0_0_1_11_1_1; + A[131] = -A[588] - 0.0395061728395073*G0_0_0_0_0_0 - 0.0395061728395069*G0_0_0_0_0_1 + 0.603880070546734*G0_0_0_1_0_0 - 1.37142857142857*G0_0_0_2_0_1 - 2.09947089947089*G0_0_0_3_0_0 - 0.124162257495592*G0_0_0_3_0_1 + 2.09947089947089*G0_0_0_4_0_0 + 1.41093474426807*G0_0_0_4_0_1 - 0.564373897707227*G0_0_0_5_0_0 + 0.124162257495593*G0_0_0_5_0_1 - 0.0395061728395073*G0_0_0_6_1_0 - 0.0395061728395069*G0_0_0_6_1_1 + 0.603880070546734*G0_0_0_7_1_0 - 1.37142857142857*G0_0_0_8_1_1 - 2.09947089947089*G0_0_0_9_1_0 - 0.124162257495592*G0_0_0_9_1_1 + 2.09947089947089*G0_0_0_10_1_0 + 1.41093474426807*G0_0_0_10_1_1 - 0.564373897707227*G0_0_0_11_1_0 + 0.124162257495593*G0_0_0_11_1_1 + 1.06102292768959*G0_1_0_0_0_0 + 1.0610229276896*G0_1_0_0_0_1 + 2.06560846560847*G0_1_0_1_0_0 + 0.112874779541445*G0_1_0_2_0_1 + 1.23033509700176*G0_1_0_3_0_0 + 3.18306878306879*G0_1_0_3_0_1 - 1.23033509700176*G0_1_0_4_0_0 - 1.17389770723104*G0_1_0_4_0_1 - 3.12663139329806*G0_1_0_5_0_0 - 3.18306878306879*G0_1_0_5_0_1 + 1.06102292768959*G0_1_0_6_1_0 + 1.0610229276896*G0_1_0_6_1_1 + 2.06560846560847*G0_1_0_7_1_0 + 0.112874779541445*G0_1_0_8_1_1 + 1.23033509700176*G0_1_0_9_1_0 + 3.18306878306879*G0_1_0_9_1_1 - 1.23033509700176*G0_1_0_10_1_0 - 1.17389770723104*G0_1_0_10_1_1 - 3.12663139329806*G0_1_0_11_1_0 - 3.18306878306879*G0_1_0_11_1_1; + A[805] = A[559] + 0.92557319223986*G0_0_0_0_0_0 + 0.925573192239859*G0_0_0_0_0_1 - 2.59611992945326*G0_0_0_1_0_0 + 2.23492063492063*G0_0_0_2_0_1 + 0.948148148148149*G0_0_0_3_0_0 - 3.88289241622575*G0_0_0_3_0_1 - 0.948148148148149*G0_0_0_4_0_0 - 3.16049382716049*G0_0_0_4_0_1 + 1.6705467372134*G0_0_0_5_0_0 + 3.88289241622575*G0_0_0_5_0_1 + 0.92557319223986*G0_0_0_6_1_0 + 0.925573192239859*G0_0_0_6_1_1 - 2.59611992945326*G0_0_0_7_1_0 + 2.23492063492063*G0_0_0_8_1_1 + 0.948148148148149*G0_0_0_9_1_0 - 3.88289241622575*G0_0_0_9_1_1 - 0.948148148148149*G0_0_0_10_1_0 - 3.16049382716049*G0_0_0_10_1_1 + 1.6705467372134*G0_0_0_11_1_0 + 3.88289241622575*G0_0_0_11_1_1 - 1.17389770723104*G0_0_1_0_0_0 - 1.17389770723104*G0_0_1_0_0_1 - 4.3005291005291*G0_0_1_1_0_0 + 0.722398589065256*G0_0_1_2_0_1 - 1.68183421516754*G0_0_1_3_0_0 - 6.7047619047619*G0_0_1_3_0_1 + 1.68183421516754*G0_0_1_4_0_0 + 0.45149911816578*G0_0_1_4_0_1 + 5.47442680776014*G0_0_1_5_0_0 + 6.7047619047619*G0_0_1_5_0_1 - 1.17389770723104*G0_0_1_6_1_0 - 1.17389770723104*G0_0_1_6_1_1 - 4.3005291005291*G0_0_1_7_1_0 + 0.722398589065256*G0_0_1_8_1_1 - 1.68183421516754*G0_0_1_9_1_0 - 6.7047619047619*G0_0_1_9_1_1 + 1.68183421516754*G0_0_1_10_1_0 + 0.45149911816578*G0_0_1_10_1_1 + 5.47442680776014*G0_0_1_11_1_0 + 6.7047619047619*G0_0_1_11_1_1 - 0.586948853615521*G0_1_0_0_0_0 - 0.586948853615521*G0_1_0_0_0_1 - 0.891710758377426*G0_1_0_1_0_0 + 0.135449735449736*G0_1_0_2_0_1 - 0.0338624338624338*G0_1_0_3_0_0 - 1.0610229276896*G0_1_0_3_0_1 + 0.0338624338624338*G0_1_0_4_0_0 + 0.451499118165785*G0_1_0_4_0_1 + 1.47865961199295*G0_1_0_5_0_0 + 1.0610229276896*G0_1_0_5_0_1 - 0.586948853615521*G0_1_0_6_1_0 - 0.586948853615521*G0_1_0_6_1_1 - 0.891710758377426*G0_1_0_7_1_0 + 0.135449735449736*G0_1_0_8_1_1 - 0.0338624338624338*G0_1_0_9_1_0 - 1.0610229276896*G0_1_0_9_1_1 + 0.0338624338624338*G0_1_0_10_1_0 + 0.451499118165785*G0_1_0_10_1_1 + 1.47865961199295*G0_1_0_11_1_0 + 1.0610229276896*G0_1_0_11_1_1 - 0.451499118165782*G0_1_1_0_0_0 - 0.451499118165782*G0_1_1_0_0_1 - 0.451499118165786*G0_1_1_2_0_1 - 0.451499118165784*G0_1_1_3_0_0 + 0.451499118165784*G0_1_1_4_0_0 + 0.902998236331568*G0_1_1_4_0_1 + 0.451499118165774*G0_1_1_5_0_0 - 0.451499118165782*G0_1_1_6_1_0 - 0.451499118165782*G0_1_1_6_1_1 - 0.451499118165786*G0_1_1_8_1_1 - 0.451499118165784*G0_1_1_9_1_0 + 0.451499118165784*G0_1_1_10_1_0 + 0.902998236331568*G0_1_1_10_1_1 + 0.451499118165774*G0_1_1_11_1_0; + A[94] = A[559]; + A[590] = A[125]; + A[652] = A[309] - 2.59611992945326*G0_0_0_0_0_0 - 2.59611992945326*G0_0_0_0_0_1 + 0.925573192239858*G0_0_0_1_0_0 - 2.23492063492063*G0_0_0_2_0_1 - 0.94814814814815*G0_0_0_3_0_0 + 2.21234567901234*G0_0_0_3_0_1 + 0.94814814814815*G0_0_0_4_0_0 + 4.8310405643739*G0_0_0_4_0_1 + 1.6705467372134*G0_0_0_5_0_0 - 2.21234567901234*G0_0_0_5_0_1 - 2.59611992945326*G0_0_0_6_1_0 - 2.59611992945326*G0_0_0_6_1_1 + 0.925573192239858*G0_0_0_7_1_0 - 2.23492063492063*G0_0_0_8_1_1 - 0.94814814814815*G0_0_0_9_1_0 + 2.21234567901234*G0_0_0_9_1_1 + 0.94814814814815*G0_0_0_10_1_0 + 4.8310405643739*G0_0_0_10_1_1 + 1.6705467372134*G0_0_0_11_1_0 - 2.21234567901234*G0_0_0_11_1_1 + 2.33650793650794*G0_0_1_1_0_0 - 2.33650793650793*G0_0_1_2_0_1 - 2.33650793650794*G0_0_1_3_0_0 + 2.33650793650793*G0_0_1_3_0_1 + 2.33650793650794*G0_0_1_4_0_0 + 2.33650793650793*G0_0_1_4_0_1 - 2.33650793650794*G0_0_1_5_0_0 - 2.33650793650793*G0_0_1_5_0_1 + 2.33650793650794*G0_0_1_7_1_0 - 2.33650793650793*G0_0_1_8_1_1 - 2.33650793650794*G0_0_1_9_1_0 + 2.33650793650793*G0_0_1_9_1_1 + 2.33650793650794*G0_0_1_10_1_0 + 2.33650793650793*G0_0_1_10_1_1 - 2.33650793650794*G0_0_1_11_1_0 - 2.33650793650793*G0_0_1_11_1_1 + 1.27548500881834*G0_1_0_1_0_0 - 1.27548500881834*G0_1_0_2_0_1 - 1.27548500881834*G0_1_0_3_0_0 + 1.27548500881834*G0_1_0_3_0_1 + 1.27548500881834*G0_1_0_4_0_0 + 1.27548500881835*G0_1_0_4_0_1 - 1.27548500881834*G0_1_0_5_0_0 - 1.27548500881834*G0_1_0_5_0_1 + 1.27548500881834*G0_1_0_7_1_0 - 1.27548500881834*G0_1_0_8_1_1 - 1.27548500881834*G0_1_0_9_1_0 + 1.27548500881834*G0_1_0_9_1_1 + 1.27548500881834*G0_1_0_10_1_0 + 1.27548500881835*G0_1_0_10_1_1 - 1.27548500881834*G0_1_0_11_1_0 - 1.27548500881834*G0_1_0_11_1_1 + 2.59611992945326*G0_1_1_0_0_0 + 2.59611992945326*G0_1_1_0_0_1 + 2.23492063492063*G0_1_1_1_0_0 - 0.925573192239859*G0_1_1_2_0_1 - 2.21234567901235*G0_1_1_3_0_0 + 0.948148148148145*G0_1_1_3_0_1 + 2.21234567901235*G0_1_1_4_0_0 - 1.6705467372134*G0_1_1_4_0_1 - 4.83104056437389*G0_1_1_5_0_0 - 0.948148148148145*G0_1_1_5_0_1 + 2.59611992945326*G0_1_1_6_1_0 + 2.59611992945326*G0_1_1_6_1_1 + 2.23492063492063*G0_1_1_7_1_0 - 0.925573192239859*G0_1_1_8_1_1 - 2.21234567901235*G0_1_1_9_1_0 + 0.948148148148145*G0_1_1_9_1_1 + 2.21234567901235*G0_1_1_10_1_0 - 1.6705467372134*G0_1_1_10_1_1 - 4.83104056437389*G0_1_1_11_1_0 - 0.948148148148145*G0_1_1_11_1_1; + A[187] = A[652]; + A[216] = A[652] - 1.70440917107584*G0_0_1_0_0_0 - 1.70440917107584*G0_0_1_0_0_1 - 0.823985890652558*G0_0_1_1_0_0 + 0.237037037037035*G0_0_1_2_0_1 + 1.35449735449735*G0_0_1_3_0_0 + 0.29347442680776*G0_0_1_3_0_1 - 1.35449735449735*G0_0_1_4_0_0 + 1.46737213403881*G0_0_1_4_0_1 + 2.5283950617284*G0_0_1_5_0_0 - 0.29347442680776*G0_0_1_5_0_1 - 1.70440917107584*G0_0_1_6_1_0 - 1.70440917107584*G0_0_1_6_1_1 - 0.823985890652558*G0_0_1_7_1_0 + 0.237037037037035*G0_0_1_8_1_1 + 1.35449735449735*G0_0_1_9_1_0 + 0.29347442680776*G0_0_1_9_1_1 - 1.35449735449735*G0_0_1_10_1_0 + 1.46737213403881*G0_0_1_10_1_1 + 2.5283950617284*G0_0_1_11_1_0 - 0.29347442680776*G0_0_1_11_1_1 + 1.70440917107584*G0_1_0_0_0_0 + 1.70440917107584*G0_1_0_0_0_1 + 0.823985890652558*G0_1_0_1_0_0 - 0.237037037037034*G0_1_0_2_0_1 - 1.35449735449735*G0_1_0_3_0_0 - 0.29347442680776*G0_1_0_3_0_1 + 1.35449735449735*G0_1_0_4_0_0 - 1.46737213403881*G0_1_0_4_0_1 - 2.5283950617284*G0_1_0_5_0_0 + 0.29347442680776*G0_1_0_5_0_1 + 1.70440917107584*G0_1_0_6_1_0 + 1.70440917107584*G0_1_0_6_1_1 + 0.823985890652558*G0_1_0_7_1_0 - 0.237037037037034*G0_1_0_8_1_1 - 1.35449735449735*G0_1_0_9_1_0 - 0.29347442680776*G0_1_0_9_1_1 + 1.35449735449735*G0_1_0_10_1_0 - 1.46737213403881*G0_1_0_10_1_1 - 2.5283950617284*G0_1_0_11_1_0 + 0.29347442680776*G0_1_0_11_1_1; + A[702] = 0.0; + A[340] = A[805]; + A[21] = 0.0; + A[46] = 0.0; + A[450] = 0.0; + A[406] = 0.0; + A[83] = 0.0; + A[788] = 0.0; + A[815] = 0.0; + A[40] = 0.00564373897707236*G0_0_0_0_0_0 + 0.00564373897707261*G0_0_0_0_0_1 + 0.729453262786596*G0_0_0_1_0_0 - 0.256084656084656*G0_0_0_2_0_1 + 0.211640211640211*G0_0_0_3_0_0 + 1.19717813051146*G0_0_0_3_0_1 - 0.211640211640211*G0_0_0_4_0_0 + 0.250440917107584*G0_0_0_4_0_1 - 0.735097001763669*G0_0_0_5_0_0 - 1.19717813051146*G0_0_0_5_0_1 + 0.00564373897707236*G0_0_0_6_1_0 + 0.00564373897707261*G0_0_0_6_1_1 + 0.729453262786596*G0_0_0_7_1_0 - 0.256084656084656*G0_0_0_8_1_1 + 0.211640211640211*G0_0_0_9_1_0 + 1.19717813051146*G0_0_0_9_1_1 - 0.211640211640211*G0_0_0_10_1_0 + 0.250440917107584*G0_0_0_10_1_1 - 0.735097001763669*G0_0_0_11_1_0 - 1.19717813051146*G0_0_0_11_1_1 + 0.323104056437389*G0_0_1_0_0_0 + 0.323104056437389*G0_0_1_0_0_1 + 1.04338624338624*G0_0_1_1_0_0 - 0.294885361552028*G0_0_1_2_0_1 + 0.130511463844796*G0_0_1_3_0_0 + 1.46878306878307*G0_0_1_3_0_1 - 0.130511463844796*G0_0_1_4_0_0 - 0.0282186948853607*G0_0_1_4_0_1 - 1.36649029982363*G0_0_1_5_0_0 - 1.46878306878307*G0_0_1_5_0_1 + 0.323104056437389*G0_0_1_6_1_0 + 0.323104056437389*G0_0_1_6_1_1 + 1.04338624338624*G0_0_1_7_1_0 - 0.294885361552028*G0_0_1_8_1_1 + 0.130511463844796*G0_0_1_9_1_0 + 1.46878306878307*G0_0_1_9_1_1 - 0.130511463844796*G0_0_1_10_1_0 - 0.0282186948853607*G0_0_1_10_1_1 - 1.36649029982363*G0_0_1_11_1_0 - 1.46878306878307*G0_0_1_11_1_1; + A[121] = -A[766] - 0.0331569664902994*G0_0_0_0_0_0 - 0.0331569664902993*G0_0_0_0_0_1 + 0.415520282186951*G0_0_0_1_0_0 + 0.06137566137566*G0_0_0_2_0_1 + 0.571428571428569*G0_0_0_3_0_0 + 0.92557319223986*G0_0_0_3_0_1 - 0.571428571428569*G0_0_0_4_0_0 - 0.0282186948853603*G0_0_0_4_0_1 - 0.382363315696651*G0_0_0_5_0_0 - 0.925573192239861*G0_0_0_5_0_1 - 0.0331569664902994*G0_0_0_6_1_0 - 0.0331569664902993*G0_0_0_6_1_1 + 0.415520282186951*G0_0_0_7_1_0 + 0.06137566137566*G0_0_0_8_1_1 + 0.571428571428569*G0_0_0_9_1_0 + 0.92557319223986*G0_0_0_9_1_1 - 0.571428571428569*G0_0_0_10_1_0 - 0.0282186948853603*G0_0_0_10_1_1 - 0.382363315696651*G0_0_0_11_1_0 - 0.925573192239861*G0_0_0_11_1_1 + 0.0282186948853608*G0_1_0_0_0_0 + 0.0282186948853608*G0_1_0_0_0_1 + 0.0282186948853617*G0_1_0_2_0_1 + 0.0282186948853611*G0_1_0_3_0_0 - 0.0282186948853611*G0_1_0_4_0_0 - 0.0564373897707226*G0_1_0_4_0_1 - 0.0282186948853593*G0_1_0_5_0_0 + 0.0282186948853608*G0_1_0_6_1_0 + 0.0282186948853608*G0_1_0_6_1_1 + 0.0282186948853617*G0_1_0_8_1_1 + 0.0282186948853611*G0_1_0_9_1_0 - 0.0282186948853611*G0_1_0_10_1_0 - 0.0564373897707226*G0_1_0_10_1_1 - 0.0282186948853593*G0_1_0_11_1_0; + A[846] = 0.0; + A[154] = A[125] - 0.823985890652557*G0_0_1_0_0_0 - 0.823985890652557*G0_0_1_0_0_1 - 0.237037037037037*G0_0_1_1_0_0 - 1.70440917107584*G0_0_1_2_0_1 - 2.82186948853615*G0_0_1_3_0_0 - 1.35449735449735*G0_0_1_3_0_1 + 2.82186948853615*G0_0_1_4_0_0 + 2.52839506172839*G0_0_1_4_0_1 + 1.06102292768959*G0_0_1_5_0_0 + 1.35449735449735*G0_0_1_5_0_1 - 0.823985890652557*G0_0_1_6_1_0 - 0.823985890652557*G0_0_1_6_1_1 - 0.237037037037037*G0_0_1_7_1_0 - 1.70440917107584*G0_0_1_8_1_1 - 2.82186948853615*G0_0_1_9_1_0 - 1.35449735449735*G0_0_1_9_1_1 + 2.82186948853615*G0_0_1_10_1_0 + 2.52839506172839*G0_0_1_10_1_1 + 1.06102292768959*G0_0_1_11_1_0 + 1.35449735449735*G0_0_1_11_1_1 + 0.823985890652557*G0_1_0_0_0_0 + 0.823985890652557*G0_1_0_0_0_1 + 0.237037037037037*G0_1_0_1_0_0 + 1.70440917107584*G0_1_0_2_0_1 + 2.82186948853615*G0_1_0_3_0_0 + 1.35449735449735*G0_1_0_3_0_1 - 2.82186948853615*G0_1_0_4_0_0 - 2.52839506172839*G0_1_0_4_0_1 - 1.06102292768959*G0_1_0_5_0_0 - 1.35449735449735*G0_1_0_5_0_1 + 0.823985890652557*G0_1_0_6_1_0 + 0.823985890652557*G0_1_0_6_1_1 + 0.237037037037037*G0_1_0_7_1_0 + 1.70440917107584*G0_1_0_8_1_1 + 2.82186948853615*G0_1_0_9_1_0 + 1.35449735449735*G0_1_0_9_1_1 - 2.82186948853615*G0_1_0_10_1_0 - 2.52839506172839*G0_1_0_10_1_1 - 1.06102292768959*G0_1_0_11_1_0 - 1.35449735449735*G0_1_0_11_1_1; + A[709] = -A[154] + 1.06102292768959*G0_1_0_0_0_0 + 1.06102292768959*G0_1_0_0_0_1 + 0.112874779541448*G0_1_0_1_0_0 + 2.06560846560846*G0_1_0_2_0_1 + 3.18306878306878*G0_1_0_3_0_0 + 1.23033509700176*G0_1_0_3_0_1 - 3.18306878306878*G0_1_0_4_0_0 - 3.12663139329805*G0_1_0_4_0_1 - 1.17389770723104*G0_1_0_5_0_0 - 1.23033509700176*G0_1_0_5_0_1 + 1.06102292768959*G0_1_0_6_1_0 + 1.06102292768959*G0_1_0_6_1_1 + 0.112874779541448*G0_1_0_7_1_0 + 2.06560846560846*G0_1_0_8_1_1 + 3.18306878306878*G0_1_0_9_1_0 + 1.23033509700176*G0_1_0_9_1_1 - 3.18306878306878*G0_1_0_10_1_0 - 3.12663139329805*G0_1_0_10_1_1 - 1.17389770723104*G0_1_0_11_1_0 - 1.23033509700176*G0_1_0_11_1_1 - 0.0395061728395083*G0_1_1_0_0_0 - 0.0395061728395086*G0_1_1_0_0_1 - 1.37142857142857*G0_1_1_1_0_0 + 0.603880070546737*G0_1_1_2_0_1 - 0.124162257495591*G0_1_1_3_0_0 - 2.0994708994709*G0_1_1_3_0_1 + 0.124162257495591*G0_1_1_4_0_0 - 0.564373897707229*G0_1_1_4_0_1 + 1.41093474426808*G0_1_1_5_0_0 + 2.0994708994709*G0_1_1_5_0_1 - 0.0395061728395083*G0_1_1_6_1_0 - 0.0395061728395086*G0_1_1_6_1_1 - 1.37142857142857*G0_1_1_7_1_0 + 0.603880070546737*G0_1_1_8_1_1 - 0.124162257495591*G0_1_1_9_1_0 - 2.0994708994709*G0_1_1_9_1_1 + 0.124162257495591*G0_1_1_10_1_0 - 0.564373897707229*G0_1_1_10_1_1 + 1.41093474426808*G0_1_1_11_1_0 + 2.0994708994709*G0_1_1_11_1_1; + A[877] = 0.0; + A[484] = 0.0; + A[191] = A[656]; + A[587] = -A[677] + 0.0282186948853626*G0_0_1_0_0_0 + 0.0282186948853627*G0_0_1_0_0_1 + 0.0282186948853613*G0_0_1_1_0_0 + 0.0282186948853625*G0_0_1_3_0_1 - 0.0282186948853653*G0_0_1_4_0_1 - 0.0564373897707239*G0_0_1_5_0_0 - 0.0282186948853625*G0_0_1_5_0_1 + 0.0282186948853626*G0_0_1_6_1_0 + 0.0282186948853627*G0_0_1_6_1_1 + 0.0282186948853613*G0_0_1_7_1_0 + 0.0282186948853625*G0_0_1_9_1_1 - 0.0282186948853653*G0_0_1_10_1_1 - 0.0564373897707239*G0_0_1_11_1_0 - 0.0282186948853625*G0_0_1_11_1_1 - 0.033156966490298*G0_1_1_0_0_0 - 0.0331569664902979*G0_1_1_0_0_1 + 0.0613756613756621*G0_1_1_1_0_0 + 0.41552028218695*G0_1_1_2_0_1 + 0.92557319223986*G0_1_1_3_0_0 + 0.571428571428572*G0_1_1_3_0_1 - 0.92557319223986*G0_1_1_4_0_0 - 0.382363315696652*G0_1_1_4_0_1 - 0.028218694885364*G0_1_1_5_0_0 - 0.571428571428573*G0_1_1_5_0_1 - 0.033156966490298*G0_1_1_6_1_0 - 0.0331569664902979*G0_1_1_6_1_1 + 0.0613756613756621*G0_1_1_7_1_0 + 0.41552028218695*G0_1_1_8_1_1 + 0.92557319223986*G0_1_1_9_1_0 + 0.571428571428572*G0_1_1_9_1_1 - 0.92557319223986*G0_1_1_10_1_0 - 0.382363315696652*G0_1_1_10_1_1 - 0.028218694885364*G0_1_1_11_1_0 - 0.571428571428573*G0_1_1_11_1_1; + A[511] = 0.0; + A[228] = 0.0; + A[610] = 0.0; + A[546] = 0.0; + A[506] = A[331] - 0.595414462081127*G0_0_1_0_0_0 - 0.595414462081128*G0_0_1_0_0_1 - 1.96966490299823*G0_0_1_1_0_0 + 0.595414462081128*G0_0_1_2_0_1 - 0.183421516754848*G0_0_1_3_0_0 - 2.74850088183421*G0_0_1_3_0_1 + 0.183421516754848*G0_0_1_4_0_0 + 2.56507936507936*G0_0_1_5_0_0 + 2.74850088183421*G0_0_1_5_0_1 - 0.595414462081127*G0_0_1_6_1_0 - 0.595414462081128*G0_0_1_6_1_1 - 1.96966490299823*G0_0_1_7_1_0 + 0.595414462081128*G0_0_1_8_1_1 - 0.183421516754848*G0_0_1_9_1_0 - 2.74850088183421*G0_0_1_9_1_1 + 0.183421516754848*G0_0_1_10_1_0 + 2.56507936507936*G0_0_1_11_1_0 + 2.74850088183421*G0_0_1_11_1_1 + 0.595414462081127*G0_1_0_0_0_0 + 0.595414462081128*G0_1_0_0_0_1 + 1.96966490299823*G0_1_0_1_0_0 - 0.595414462081128*G0_1_0_2_0_1 + 0.183421516754848*G0_1_0_3_0_0 + 2.74850088183421*G0_1_0_3_0_1 - 0.183421516754848*G0_1_0_4_0_0 - 2.56507936507936*G0_1_0_5_0_0 - 2.74850088183421*G0_1_0_5_0_1 + 0.595414462081127*G0_1_0_6_1_0 + 0.595414462081128*G0_1_0_6_1_1 + 1.96966490299823*G0_1_0_7_1_0 - 0.595414462081128*G0_1_0_8_1_1 + 0.183421516754848*G0_1_0_9_1_0 + 2.74850088183421*G0_1_0_9_1_1 - 0.183421516754848*G0_1_0_10_1_0 - 2.56507936507936*G0_1_0_11_1_0 - 2.74850088183421*G0_1_0_11_1_1; + A[641] = 0.0; + A[537] = A[72]; + A[660] = 0.0; + A[695] = 0.0; + A[262] = 0.0; + A[293] = 0.0; + A[745] = A[309] - 1.70440917107583*G0_0_1_0_0_0 - 1.70440917107583*G0_0_1_0_0_1 + 0.237037037037038*G0_0_1_1_0_0 - 0.823985890652556*G0_0_1_2_0_1 + 0.293474426807759*G0_0_1_3_0_0 + 1.35449735449735*G0_0_1_3_0_1 - 0.293474426807759*G0_0_1_4_0_0 + 2.52839506172839*G0_0_1_4_0_1 + 1.4673721340388*G0_0_1_5_0_0 - 1.35449735449735*G0_0_1_5_0_1 - 1.70440917107583*G0_0_1_6_1_0 - 1.70440917107583*G0_0_1_6_1_1 + 0.237037037037038*G0_0_1_7_1_0 - 0.823985890652556*G0_0_1_8_1_1 + 0.293474426807759*G0_0_1_9_1_0 + 1.35449735449735*G0_0_1_9_1_1 - 0.293474426807759*G0_0_1_10_1_0 + 2.52839506172839*G0_0_1_10_1_1 + 1.4673721340388*G0_0_1_11_1_0 - 1.35449735449735*G0_0_1_11_1_1 + 1.70440917107583*G0_1_0_0_0_0 + 1.70440917107583*G0_1_0_0_0_1 - 0.237037037037038*G0_1_0_1_0_0 + 0.823985890652556*G0_1_0_2_0_1 - 0.293474426807759*G0_1_0_3_0_0 - 1.35449735449735*G0_1_0_3_0_1 + 0.293474426807759*G0_1_0_4_0_0 - 2.52839506172839*G0_1_0_4_0_1 - 1.4673721340388*G0_1_0_5_0_0 + 1.35449735449735*G0_1_0_5_0_1 + 1.70440917107583*G0_1_0_6_1_0 + 1.70440917107583*G0_1_0_6_1_1 - 0.237037037037038*G0_1_0_7_1_0 + 0.823985890652556*G0_1_0_8_1_1 - 0.293474426807759*G0_1_0_9_1_0 - 1.35449735449735*G0_1_0_9_1_1 + 0.293474426807759*G0_1_0_10_1_0 - 2.52839506172839*G0_1_0_10_1_1 - 1.4673721340388*G0_1_0_11_1_0 + 1.35449735449735*G0_1_0_11_1_1; + A[320] = 0.0; + A[770] = A[305]; + A[459] = 0.0; + A[355] = 0.0; + A[799] = A[334]; + A[105] = 0.0; + A[33] = -A[506] - 0.0451499118165792*G0_0_0_0_0_0 - 0.0451499118165793*G0_0_0_0_0_1 - 0.615167548500884*G0_0_0_1_0_0 + 0.0451499118165794*G0_0_0_2_0_1 - 0.479717813051145*G0_0_0_3_0_0 - 1.14003527336861*G0_0_0_3_0_1 + 0.479717813051145*G0_0_0_4_0_0 + 0.660317460317463*G0_0_0_5_0_0 + 1.14003527336861*G0_0_0_5_0_1 - 0.0451499118165792*G0_0_0_6_1_0 - 0.0451499118165793*G0_0_0_6_1_1 - 0.615167548500884*G0_0_0_7_1_0 + 0.0451499118165794*G0_0_0_8_1_1 - 0.479717813051145*G0_0_0_9_1_0 - 1.14003527336861*G0_0_0_9_1_1 + 0.479717813051145*G0_0_0_10_1_0 + 0.660317460317463*G0_0_0_11_1_0 + 1.14003527336861*G0_0_0_11_1_1; + A[128] = -A[125] + 1.06102292768959*G0_0_1_0_0_0 + 1.06102292768959*G0_0_1_0_0_1 + 0.112874779541448*G0_0_1_1_0_0 + 2.06560846560846*G0_0_1_2_0_1 + 3.18306878306878*G0_0_1_3_0_0 + 1.23033509700176*G0_0_1_3_0_1 - 3.18306878306878*G0_0_1_4_0_0 - 3.12663139329806*G0_0_1_4_0_1 - 1.17389770723104*G0_0_1_5_0_0 - 1.23033509700176*G0_0_1_5_0_1 + 1.06102292768959*G0_0_1_6_1_0 + 1.06102292768959*G0_0_1_6_1_1 + 0.112874779541448*G0_0_1_7_1_0 + 2.06560846560846*G0_0_1_8_1_1 + 3.18306878306878*G0_0_1_9_1_0 + 1.23033509700176*G0_0_1_9_1_1 - 3.18306878306878*G0_0_1_10_1_0 - 3.12663139329806*G0_0_1_10_1_1 - 1.17389770723104*G0_0_1_11_1_0 - 1.23033509700176*G0_0_1_11_1_1 - 0.0395061728395082*G0_1_1_0_0_0 - 0.0395061728395085*G0_1_1_0_0_1 - 1.37142857142857*G0_1_1_1_0_0 + 0.603880070546737*G0_1_1_2_0_1 - 0.124162257495591*G0_1_1_3_0_0 - 2.0994708994709*G0_1_1_3_0_1 + 0.124162257495591*G0_1_1_4_0_0 - 0.56437389770723*G0_1_1_4_0_1 + 1.41093474426808*G0_1_1_5_0_0 + 2.0994708994709*G0_1_1_5_0_1 - 0.0395061728395082*G0_1_1_6_1_0 - 0.0395061728395085*G0_1_1_6_1_1 - 1.37142857142857*G0_1_1_7_1_0 + 0.603880070546737*G0_1_1_8_1_1 - 0.124162257495591*G0_1_1_9_1_0 - 2.0994708994709*G0_1_1_9_1_1 + 0.124162257495591*G0_1_1_10_1_0 - 0.56437389770723*G0_1_1_10_1_1 + 1.41093474426808*G0_1_1_11_1_0 + 2.0994708994709*G0_1_1_11_1_1; + A[68] = A[533]; + A[870] = 0.0; + A[111] = 0.0; + A[142] = 0.0; + A[221] = -A[213] + 0.265255731922398*G0_0_0_0_0_0 + 0.265255731922398*G0_0_0_0_0_1 + 0.434567901234569*G0_0_0_1_0_0 - 0.389417989417988*G0_0_0_2_0_1 - 0.609523809523805*G0_0_0_3_0_0 + 0.214462081128751*G0_0_0_3_0_1 + 0.609523809523805*G0_0_0_4_0_0 + 0.12416225749559*G0_0_0_4_0_1 - 0.699823633156967*G0_0_0_5_0_0 - 0.214462081128751*G0_0_0_5_0_1 + 0.265255731922398*G0_0_0_6_1_0 + 0.265255731922398*G0_0_0_6_1_1 + 0.434567901234569*G0_0_0_7_1_0 - 0.389417989417988*G0_0_0_8_1_1 - 0.609523809523805*G0_0_0_9_1_0 + 0.214462081128751*G0_0_0_9_1_1 + 0.609523809523805*G0_0_0_10_1_0 + 0.12416225749559*G0_0_0_10_1_1 - 0.699823633156967*G0_0_0_11_1_0 - 0.214462081128751*G0_0_0_11_1_1 - 0.124162257495588*G0_1_0_0_0_0 - 0.124162257495588*G0_1_0_0_0_1 - 0.12416225749559*G0_1_0_2_0_1 - 0.12416225749559*G0_1_0_3_0_0 + 0.12416225749559*G0_1_0_4_0_0 + 0.248324514991177*G0_1_0_4_0_1 + 0.124162257495586*G0_1_0_5_0_0 - 0.124162257495588*G0_1_0_6_1_0 - 0.124162257495588*G0_1_0_6_1_1 - 0.12416225749559*G0_1_0_8_1_1 - 0.12416225749559*G0_1_0_9_1_0 + 0.12416225749559*G0_1_0_10_1_0 + 0.248324514991177*G0_1_0_10_1_1 + 0.124162257495586*G0_1_0_11_1_0; + A[219] = A[221] - 0.361199294532629*G0_0_0_0_0_0 - 0.361199294532629*G0_0_0_0_0_1 - 0.361199294532629*G0_0_0_1_0_0 - 0.36119929453263*G0_0_0_3_0_1 + 0.361199294532629*G0_0_0_4_0_1 + 0.722398589065258*G0_0_0_5_0_0 + 0.36119929453263*G0_0_0_5_0_1 - 0.361199294532629*G0_0_0_6_1_0 - 0.361199294532629*G0_0_0_6_1_1 - 0.361199294532629*G0_0_0_7_1_0 - 0.36119929453263*G0_0_0_9_1_1 + 0.361199294532629*G0_0_0_10_1_1 + 0.722398589065258*G0_0_0_11_1_0 + 0.36119929453263*G0_0_0_11_1_1 + 0.293474426807759*G0_0_1_0_0_0 + 0.293474426807759*G0_0_1_0_0_1 + 0.0225749559082863*G0_0_1_1_0_0 - 0.135449735449735*G0_0_1_2_0_1 - 0.541798941798942*G0_0_1_3_0_0 - 0.383774250440921*G0_0_1_3_0_1 + 0.541798941798942*G0_0_1_4_0_0 - 0.158024691358025*G0_0_1_4_0_1 - 0.316049382716046*G0_0_1_5_0_0 + 0.383774250440921*G0_0_1_5_0_1 + 0.293474426807759*G0_0_1_6_1_0 + 0.293474426807759*G0_0_1_6_1_1 + 0.0225749559082863*G0_0_1_7_1_0 - 0.135449735449735*G0_0_1_8_1_1 - 0.541798941798942*G0_0_1_9_1_0 - 0.383774250440921*G0_0_1_9_1_1 + 0.541798941798942*G0_0_1_10_1_0 - 0.158024691358025*G0_0_1_10_1_1 - 0.316049382716046*G0_0_1_11_1_0 + 0.383774250440921*G0_0_1_11_1_1 + 0.722398589065252*G0_1_0_0_0_0 + 0.722398589065252*G0_1_0_0_0_1 + 0.270899470899468*G0_1_0_1_0_0 + 0.0451499118165782*G0_1_0_2_0_1 - 0.361199294532627*G0_1_0_3_0_0 - 0.135449735449738*G0_1_0_3_0_1 + 0.361199294532627*G0_1_0_4_0_0 - 0.76754850088183*G0_1_0_4_0_1 - 0.99329805996472*G0_1_0_5_0_0 + 0.135449735449738*G0_1_0_5_0_1 + 0.722398589065252*G0_1_0_6_1_0 + 0.722398589065252*G0_1_0_6_1_1 + 0.270899470899468*G0_1_0_7_1_0 + 0.0451499118165782*G0_1_0_8_1_1 - 0.361199294532627*G0_1_0_9_1_0 - 0.135449735449738*G0_1_0_9_1_1 + 0.361199294532627*G0_1_0_10_1_0 - 0.76754850088183*G0_1_0_10_1_1 - 0.99329805996472*G0_1_0_11_1_0 + 0.135449735449738*G0_1_0_11_1_1 - 0.823985890652555*G0_1_1_0_0_0 - 0.823985890652555*G0_1_1_0_0_1 + 0.0338624338624307*G0_1_1_1_0_0 - 0.756261022927687*G0_1_1_2_0_1 - 0.65467372134039*G0_1_1_3_0_0 + 0.135449735449729*G0_1_1_3_0_1 + 0.65467372134039*G0_1_1_4_0_0 + 1.58024691358024*G0_1_1_4_0_1 + 0.790123456790124*G0_1_1_5_0_0 - 0.135449735449729*G0_1_1_5_0_1 - 0.823985890652555*G0_1_1_6_1_0 - 0.823985890652555*G0_1_1_6_1_1 + 0.0338624338624307*G0_1_1_7_1_0 - 0.756261022927687*G0_1_1_8_1_1 - 0.65467372134039*G0_1_1_9_1_0 + 0.135449735449729*G0_1_1_9_1_1 + 0.65467372134039*G0_1_1_10_1_0 + 1.58024691358024*G0_1_1_10_1_1 + 0.790123456790124*G0_1_1_11_1_0 - 0.135449735449729*G0_1_1_11_1_1; + A[173] = 0.0; + A[617] = -A[242] - 0.0451499118165792*G0_1_1_0_0_0 - 0.0451499118165791*G0_1_1_0_0_1 + 0.0451499118165782*G0_1_1_1_0_0 - 0.615167548500882*G0_1_1_2_0_1 - 1.14003527336861*G0_1_1_3_0_0 - 0.479717813051146*G0_1_1_3_0_1 + 1.14003527336861*G0_1_1_4_0_0 + 0.660317460317461*G0_1_1_4_0_1 + 0.479717813051147*G0_1_1_5_0_1 - 0.0451499118165792*G0_1_1_6_1_0 - 0.0451499118165791*G0_1_1_6_1_1 + 0.0451499118165782*G0_1_1_7_1_0 - 0.615167548500882*G0_1_1_8_1_1 - 1.14003527336861*G0_1_1_9_1_0 - 0.479717813051146*G0_1_1_9_1_1 + 1.14003527336861*G0_1_1_10_1_0 + 0.660317460317461*G0_1_1_10_1_1 + 0.479717813051147*G0_1_1_11_1_1; + A[541] = 0.0; + A[497] = -0.0361552028218697*G0_0_1_0_0_0 - 0.0361552028218697*G0_0_1_0_0_1 - 0.0463844797178135*G0_0_1_1_0_0 - 0.0463844797178129*G0_0_1_2_0_1 - 0.102998236331569*G0_0_1_3_0_0 - 0.10299823633157*G0_0_1_3_0_1 + 0.102998236331569*G0_0_1_4_0_0 + 0.0825396825396824*G0_0_1_4_0_1 + 0.0825396825396832*G0_0_1_5_0_0 + 0.10299823633157*G0_0_1_5_0_1 - 0.0361552028218697*G0_0_1_6_1_0 - 0.0361552028218697*G0_0_1_6_1_1 - 0.0463844797178135*G0_0_1_7_1_0 - 0.0463844797178129*G0_0_1_8_1_1 - 0.102998236331569*G0_0_1_9_1_0 - 0.10299823633157*G0_0_1_9_1_1 + 0.102998236331569*G0_0_1_10_1_0 + 0.0825396825396824*G0_0_1_10_1_1 + 0.0825396825396832*G0_0_1_11_1_0 + 0.10299823633157*G0_0_1_11_1_1; + A[30] = -A[497] - 0.0463844797178132*G0_0_0_0_0_0 - 0.0463844797178131*G0_0_0_0_0_1 + 0.0463844797178131*G0_0_0_1_0_0 - 0.0361552028218696*G0_0_0_2_0_1 + 0.020458553791887*G0_0_0_3_0_0 + 0.10299823633157*G0_0_0_3_0_1 - 0.020458553791887*G0_0_0_4_0_0 + 0.0825396825396828*G0_0_0_4_0_1 - 0.10299823633157*G0_0_0_5_0_1 - 0.0463844797178132*G0_0_0_6_1_0 - 0.0463844797178131*G0_0_0_6_1_1 + 0.0463844797178131*G0_0_0_7_1_0 - 0.0361552028218696*G0_0_0_8_1_1 + 0.020458553791887*G0_0_0_9_1_0 + 0.10299823633157*G0_0_0_9_1_1 - 0.020458553791887*G0_0_0_10_1_0 + 0.0825396825396828*G0_0_0_10_1_1 - 0.10299823633157*G0_0_0_11_1_1 - 0.0825396825396829*G0_0_1_0_0_0 - 0.0825396825396829*G0_0_1_0_0_1 - 0.0825396825396824*G0_0_1_2_0_1 - 0.0825396825396826*G0_0_1_3_0_0 + 0.0825396825396826*G0_0_1_4_0_0 + 0.165079365079365*G0_0_1_4_0_1 + 0.0825396825396835*G0_0_1_5_0_0 - 0.0825396825396829*G0_0_1_6_1_0 - 0.0825396825396829*G0_0_1_6_1_1 - 0.0825396825396824*G0_0_1_8_1_1 - 0.0825396825396826*G0_0_1_9_1_0 + 0.0825396825396826*G0_0_1_10_1_0 + 0.165079365079365*G0_0_1_10_1_1 + 0.0825396825396835*G0_0_1_11_1_0; + A[2] = -A[497] - 0.0825396825396826*G0_0_1_0_0_0 - 0.0825396825396826*G0_0_1_0_0_1 - 0.0825396825396831*G0_0_1_1_0_0 - 0.0825396825396831*G0_0_1_3_0_1 + 0.0825396825396822*G0_0_1_4_0_1 + 0.165079365079366*G0_0_1_5_0_0 + 0.0825396825396831*G0_0_1_5_0_1 - 0.0825396825396826*G0_0_1_6_1_0 - 0.0825396825396826*G0_0_1_6_1_1 - 0.0825396825396831*G0_0_1_7_1_0 - 0.0825396825396831*G0_0_1_9_1_1 + 0.0825396825396822*G0_0_1_10_1_1 + 0.165079365079366*G0_0_1_11_1_0 + 0.0825396825396831*G0_0_1_11_1_1 - 0.0463844797178128*G0_1_1_0_0_0 - 0.0463844797178128*G0_1_1_0_0_1 - 0.0361552028218697*G0_1_1_1_0_0 + 0.0463844797178138*G0_1_1_2_0_1 + 0.102998236331571*G0_1_1_3_0_0 + 0.0204585537918871*G0_1_1_3_0_1 - 0.102998236331571*G0_1_1_4_0_0 + 0.0825396825396825*G0_1_1_5_0_0 - 0.0204585537918871*G0_1_1_5_0_1 - 0.0463844797178128*G0_1_1_6_1_0 - 0.0463844797178128*G0_1_1_6_1_1 - 0.0361552028218697*G0_1_1_7_1_0 + 0.0463844797178138*G0_1_1_8_1_1 + 0.102998236331571*G0_1_1_9_1_0 + 0.0204585537918871*G0_1_1_9_1_1 - 0.102998236331571*G0_1_1_10_1_0 + 0.0825396825396825*G0_1_1_11_1_0 - 0.0204585537918871*G0_1_1_11_1_1; + A[538] = A[72] - 0.270899470899472*G0_1_1_0_0_0 - 0.270899470899472*G0_1_1_0_0_1 - 0.270899470899471*G0_1_1_1_0_0 - 0.270899470899473*G0_1_1_3_0_1 + 0.270899470899475*G0_1_1_4_0_1 + 0.541798941798942*G0_1_1_5_0_0 + 0.270899470899473*G0_1_1_5_0_1 - 0.270899470899472*G0_1_1_6_1_0 - 0.270899470899472*G0_1_1_6_1_1 - 0.270899470899471*G0_1_1_7_1_0 - 0.270899470899473*G0_1_1_9_1_1 + 0.270899470899475*G0_1_1_10_1_1 + 0.541798941798942*G0_1_1_11_1_0 + 0.270899470899473*G0_1_1_11_1_1; + A[692] = 0.0; + A[269] = 0.0; + A[294] = 0.0; + A[443] = 0.0; + A[472] = A[7]; + A[392] = A[857]; + A[25] = 0.0; + A[726] = 0.0; + A[385] = 0.0; + A[34] = -A[40] - 0.0331569664902995*G0_0_0_0_0_0 - 0.0331569664902994*G0_0_0_0_0_1 + 0.41552028218695*G0_0_0_1_0_0 + 0.06137566137566*G0_0_0_2_0_1 + 0.571428571428569*G0_0_0_3_0_0 + 0.92557319223986*G0_0_0_3_0_1 - 0.571428571428569*G0_0_0_4_0_0 - 0.0282186948853603*G0_0_0_4_0_1 - 0.382363315696651*G0_0_0_5_0_0 - 0.92557319223986*G0_0_0_5_0_1 - 0.0331569664902995*G0_0_0_6_1_0 - 0.0331569664902994*G0_0_0_6_1_1 + 0.41552028218695*G0_0_0_7_1_0 + 0.06137566137566*G0_0_0_8_1_1 + 0.571428571428569*G0_0_0_9_1_0 + 0.92557319223986*G0_0_0_9_1_1 - 0.571428571428569*G0_0_0_10_1_0 - 0.0282186948853603*G0_0_0_10_1_1 - 0.382363315696651*G0_0_0_11_1_0 - 0.92557319223986*G0_0_0_11_1_1 + 0.0282186948853608*G0_0_1_0_0_0 + 0.0282186948853607*G0_0_1_0_0_1 + 0.0282186948853618*G0_0_1_2_0_1 + 0.0282186948853611*G0_0_1_3_0_0 - 0.0282186948853611*G0_0_1_4_0_0 - 0.0564373897707226*G0_0_1_4_0_1 - 0.0282186948853591*G0_0_1_5_0_0 + 0.0282186948853608*G0_0_1_6_1_0 + 0.0282186948853607*G0_0_1_6_1_1 + 0.0282186948853618*G0_0_1_8_1_1 + 0.0282186948853611*G0_0_1_9_1_0 - 0.0282186948853611*G0_0_1_10_1_0 - 0.0564373897707226*G0_0_1_10_1_1 - 0.0282186948853591*G0_0_1_11_1_0; + A[757] = 0.0; + A[418] = 0.0; + A[784] = 0.0; + A[116] = 0.0; + A[819] = 0.0; + A[149] = 0.0; + A[210] = A[7] + 1.04338624338624*G0_0_1_0_0_0 + 1.04338624338624*G0_0_1_0_0_1 + 0.294885361552028*G0_0_1_1_0_0 + 0.32310405643739*G0_0_1_2_0_1 - 0.102292768959434*G0_0_1_3_0_0 - 0.130511463844797*G0_0_1_3_0_1 + 0.102292768959434*G0_0_1_4_0_0 - 1.36649029982363*G0_0_1_4_0_1 - 1.33827160493827*G0_0_1_5_0_0 + 0.130511463844797*G0_0_1_5_0_1 + 1.04338624338624*G0_0_1_6_1_0 + 1.04338624338624*G0_0_1_6_1_1 + 0.294885361552028*G0_0_1_7_1_0 + 0.32310405643739*G0_0_1_8_1_1 - 0.102292768959434*G0_0_1_9_1_0 - 0.130511463844797*G0_0_1_9_1_1 + 0.102292768959434*G0_0_1_10_1_0 - 1.36649029982363*G0_0_1_10_1_1 - 1.33827160493827*G0_0_1_11_1_0 + 0.130511463844797*G0_0_1_11_1_1 - 1.04338624338624*G0_1_0_0_0_0 - 1.04338624338624*G0_1_0_0_0_1 - 0.294885361552028*G0_1_0_1_0_0 - 0.32310405643739*G0_1_0_2_0_1 + 0.102292768959434*G0_1_0_3_0_0 + 0.130511463844797*G0_1_0_3_0_1 - 0.102292768959434*G0_1_0_4_0_0 + 1.36649029982363*G0_1_0_4_0_1 + 1.33827160493827*G0_1_0_5_0_0 - 0.130511463844797*G0_1_0_5_0_1 - 1.04338624338624*G0_1_0_6_1_0 - 1.04338624338624*G0_1_0_6_1_1 - 0.294885361552028*G0_1_0_7_1_0 - 0.32310405643739*G0_1_0_8_1_1 + 0.102292768959434*G0_1_0_9_1_0 + 0.130511463844797*G0_1_0_9_1_1 - 0.102292768959434*G0_1_0_10_1_0 + 1.36649029982363*G0_1_0_10_1_1 + 1.33827160493827*G0_1_0_11_1_0 - 0.130511463844797*G0_1_0_11_1_1; + A[679] = A[210] - 0.343562610229276*G0_0_0_0_0_0 - 0.343562610229276*G0_0_0_0_0_1 - 0.00917107583774325*G0_0_0_1_0_0 + 0.0169312169312204*G0_0_0_2_0_1 + 0.368253968253974*G0_0_0_3_0_0 + 0.34215167548501*G0_0_0_3_0_1 - 0.368253968253974*G0_0_0_4_0_0 + 0.326631393298056*G0_0_0_4_0_1 + 0.35273368606702*G0_0_0_5_0_0 - 0.34215167548501*G0_0_0_5_0_1 - 0.343562610229276*G0_0_0_6_1_0 - 0.343562610229276*G0_0_0_6_1_1 - 0.00917107583774325*G0_0_0_7_1_0 + 0.0169312169312204*G0_0_0_8_1_1 + 0.368253968253974*G0_0_0_9_1_0 + 0.34215167548501*G0_0_0_9_1_1 - 0.368253968253974*G0_0_0_10_1_0 + 0.326631393298056*G0_0_0_10_1_1 + 0.35273368606702*G0_0_0_11_1_0 - 0.34215167548501*G0_0_0_11_1_1 - 0.328747795414462*G0_0_1_0_0_0 - 0.328747795414462*G0_0_1_0_0_1 + 0.0183421516754872*G0_0_1_1_0_0 - 0.192592592592591*G0_0_1_2_0_1 - 0.0380952380952324*G0_0_1_3_0_0 + 0.172839506172846*G0_0_1_3_0_1 + 0.0380952380952324*G0_0_1_4_0_0 + 0.521340388007053*G0_0_1_4_0_1 + 0.310405643738975*G0_0_1_5_0_0 - 0.172839506172845*G0_0_1_5_0_1 - 0.328747795414462*G0_0_1_6_1_0 - 0.328747795414462*G0_0_1_6_1_1 + 0.0183421516754872*G0_0_1_7_1_0 - 0.192592592592591*G0_0_1_8_1_1 - 0.0380952380952324*G0_0_1_9_1_0 + 0.172839506172846*G0_0_1_9_1_1 + 0.0380952380952324*G0_0_1_10_1_0 + 0.521340388007053*G0_0_1_10_1_1 + 0.310405643738975*G0_0_1_11_1_0 - 0.172839506172845*G0_0_1_11_1_1 + 0.756966490299824*G0_1_0_0_0_0 + 0.756966490299824*G0_1_0_0_0_1 + 0.27089947089947*G0_1_0_1_0_0 + 0.215167548500883*G0_1_0_2_0_1 - 0.055731922398586*G0_1_0_3_0_0 + 0.055731922398586*G0_1_0_4_0_0 - 0.972134038800708*G0_1_0_4_0_1 - 1.02786596119929*G0_1_0_5_0_0 + 0.756966490299824*G0_1_0_6_1_0 + 0.756966490299824*G0_1_0_6_1_1 + 0.27089947089947*G0_1_0_7_1_0 + 0.215167548500883*G0_1_0_8_1_1 - 0.055731922398586*G0_1_0_9_1_0 + 0.055731922398586*G0_1_0_10_1_0 - 0.972134038800708*G0_1_0_10_1_1 - 1.02786596119929*G0_1_0_11_1_0 + 0.754850088183424*G0_1_1_0_0_0 + 0.754850088183424*G0_1_1_0_0_1 + 0.273015873015876*G0_1_1_1_0_0 + 0.0649029982363319*G0_1_1_2_0_1 - 0.352028218694884*G0_1_1_3_0_0 - 0.14391534391534*G0_1_1_3_0_1 + 0.352028218694884*G0_1_1_4_0_0 - 0.819753086419756*G0_1_1_4_0_1 - 1.0278659611993*G0_1_1_5_0_0 + 0.14391534391534*G0_1_1_5_0_1 + 0.754850088183424*G0_1_1_6_1_0 + 0.754850088183424*G0_1_1_6_1_1 + 0.273015873015876*G0_1_1_7_1_0 + 0.0649029982363319*G0_1_1_8_1_1 - 0.352028218694884*G0_1_1_9_1_0 - 0.14391534391534*G0_1_1_9_1_1 + 0.352028218694884*G0_1_1_10_1_0 - 0.819753086419756*G0_1_1_10_1_1 - 1.0278659611993*G0_1_1_11_1_0 + 0.14391534391534*G0_1_1_11_1_1; + A[307] = A[679] - 0.0296296296296306*G0_0_0_0_0_0 - 0.0296296296296305*G0_0_0_0_0_1 - 0.0550264550264536*G0_0_0_1_0_0 - 0.317460317460323*G0_0_0_2_0_1 - 0.660317460317468*G0_0_0_3_0_0 - 0.397883597883599*G0_0_0_3_0_1 + 0.660317460317468*G0_0_0_4_0_0 + 0.347089947089953*G0_0_0_4_0_1 + 0.0846560846560841*G0_0_0_5_0_0 + 0.397883597883599*G0_0_0_5_0_1 - 0.0296296296296306*G0_0_0_6_1_0 - 0.0296296296296305*G0_0_0_6_1_1 - 0.0550264550264536*G0_0_0_7_1_0 - 0.317460317460323*G0_0_0_8_1_1 - 0.660317460317468*G0_0_0_9_1_0 - 0.397883597883599*G0_0_0_9_1_1 + 0.660317460317468*G0_0_0_10_1_0 + 0.347089947089953*G0_0_0_10_1_1 + 0.0846560846560841*G0_0_0_11_1_0 + 0.397883597883599*G0_0_0_11_1_1 + 0.165079365079363*G0_0_1_0_0_0 + 0.165079365079363*G0_0_1_0_0_1 - 0.0550264550264573*G0_0_1_1_0_0 - 0.122751322751326*G0_0_1_2_0_1 - 0.465608465608473*G0_0_1_3_0_0 - 0.397883597883604*G0_0_1_3_0_1 + 0.465608465608473*G0_0_1_4_0_0 - 0.0423280423280361*G0_0_1_4_0_1 - 0.110052910052905*G0_0_1_5_0_0 + 0.397883597883604*G0_0_1_5_0_1 + 0.165079365079363*G0_0_1_6_1_0 + 0.165079365079363*G0_0_1_6_1_1 - 0.0550264550264573*G0_0_1_7_1_0 - 0.122751322751326*G0_0_1_8_1_1 - 0.465608465608473*G0_0_1_9_1_0 - 0.397883597883604*G0_0_1_9_1_1 + 0.465608465608473*G0_0_1_10_1_0 - 0.0423280423280361*G0_0_1_10_1_1 - 0.110052910052905*G0_0_1_11_1_0 + 0.397883597883604*G0_0_1_11_1_1 + 0.0380952380952366*G0_1_0_0_0_0 + 0.0380952380952367*G0_1_0_0_0_1 - 0.0550264550264544*G0_1_0_1_0_0 - 0.249735449735453*G0_1_0_2_0_1 - 0.592592592592596*G0_1_0_3_0_0 - 0.397883597883598*G0_1_0_3_0_1 + 0.592592592592596*G0_1_0_4_0_0 + 0.211640211640216*G0_1_0_4_0_1 + 0.0169312169312176*G0_1_0_5_0_0 + 0.397883597883598*G0_1_0_5_0_1 + 0.0380952380952366*G0_1_0_6_1_0 + 0.0380952380952367*G0_1_0_6_1_1 - 0.0550264550264544*G0_1_0_7_1_0 - 0.249735449735453*G0_1_0_8_1_1 - 0.592592592592596*G0_1_0_9_1_0 - 0.397883597883598*G0_1_0_9_1_1 + 0.592592592592596*G0_1_0_10_1_0 + 0.211640211640216*G0_1_0_10_1_1 + 0.0169312169312176*G0_1_0_11_1_0 + 0.397883597883598*G0_1_0_11_1_1 - 0.084656084656091*G0_1_1_0_0_0 - 0.0846560846560909*G0_1_1_0_0_1 - 0.0846560846560869*G0_1_1_2_0_1 - 0.0846560846560869*G0_1_1_3_0_0 + 0.0846560846560869*G0_1_1_4_0_0 + 0.169312169312178*G0_1_1_4_0_1 + 0.0846560846560948*G0_1_1_5_0_0 - 0.084656084656091*G0_1_1_6_1_0 - 0.0846560846560909*G0_1_1_6_1_1 - 0.0846560846560869*G0_1_1_8_1_1 - 0.0846560846560869*G0_1_1_9_1_0 + 0.0846560846560869*G0_1_1_10_1_0 + 0.169312169312178*G0_1_1_10_1_1 + 0.0846560846560948*G0_1_1_11_1_0; + A[214] = A[679]; + A[127] = A[679] + 0.0423280423280433*G0_0_1_0_0_0 + 0.0423280423280433*G0_0_1_0_0_1 - 0.0423280423280446*G0_0_1_1_0_0 + 0.0846560846560842*G0_0_1_2_0_1 + 0.0846560846560807*G0_0_1_3_0_0 - 0.0423280423280483*G0_0_1_3_0_1 - 0.0846560846560807*G0_0_1_4_0_0 - 0.126984126984128*G0_0_1_4_0_1 + 0.0423280423280481*G0_0_1_5_0_1 + 0.0423280423280433*G0_0_1_6_1_0 + 0.0423280423280433*G0_0_1_6_1_1 - 0.0423280423280446*G0_0_1_7_1_0 + 0.0846560846560842*G0_0_1_8_1_1 + 0.0846560846560807*G0_0_1_9_1_0 - 0.0423280423280483*G0_0_1_9_1_1 - 0.0846560846560807*G0_0_1_10_1_0 - 0.126984126984128*G0_0_1_10_1_1 + 0.0423280423280481*G0_0_1_11_1_1 - 0.0423280423280433*G0_1_0_0_0_0 - 0.0423280423280433*G0_1_0_0_0_1 + 0.0423280423280446*G0_1_0_1_0_0 - 0.0846560846560842*G0_1_0_2_0_1 - 0.0846560846560807*G0_1_0_3_0_0 + 0.0423280423280482*G0_1_0_3_0_1 + 0.0846560846560807*G0_1_0_4_0_0 + 0.126984126984128*G0_1_0_4_0_1 - 0.0423280423280481*G0_1_0_5_0_1 - 0.0423280423280433*G0_1_0_6_1_0 - 0.0423280423280433*G0_1_0_6_1_1 + 0.0423280423280446*G0_1_0_7_1_0 - 0.0846560846560842*G0_1_0_8_1_1 - 0.0846560846560807*G0_1_0_9_1_0 + 0.0423280423280482*G0_1_0_9_1_1 + 0.0846560846560807*G0_1_0_10_1_0 + 0.126984126984128*G0_1_0_10_1_1 - 0.0423280423280481*G0_1_0_11_1_1; + A[772] = A[307]; + A[769] = A[127] + 0.055026455026453*G0_0_0_0_0_0 + 0.0550264550264531*G0_0_0_0_0_1 + 0.0296296296296296*G0_0_0_1_0_0 - 0.317460317460321*G0_0_0_2_0_1 - 0.660317460317466*G0_0_0_3_0_0 - 0.313227513227515*G0_0_0_3_0_1 + 0.660317460317466*G0_0_0_4_0_0 + 0.262433862433868*G0_0_0_4_0_1 - 0.0846560846560827*G0_0_0_5_0_0 + 0.313227513227515*G0_0_0_5_0_1 + 0.055026455026453*G0_0_0_6_1_0 + 0.0550264550264531*G0_0_0_6_1_1 + 0.0296296296296296*G0_0_0_7_1_0 - 0.317460317460321*G0_0_0_8_1_1 - 0.660317460317466*G0_0_0_9_1_0 - 0.313227513227515*G0_0_0_9_1_1 + 0.660317460317466*G0_0_0_10_1_0 + 0.262433862433868*G0_0_0_10_1_1 - 0.0846560846560827*G0_0_0_11_1_0 + 0.313227513227515*G0_0_0_11_1_1 + 0.194708994708991*G0_0_1_1_0_0 - 0.194708994708996*G0_0_1_2_0_1 - 0.194708994708998*G0_0_1_3_0_0 + 0.194708994708989*G0_0_1_3_0_1 + 0.194708994708998*G0_0_1_4_0_0 + 0.194708994709001*G0_0_1_4_0_1 - 0.194708994708987*G0_0_1_5_0_0 - 0.194708994708989*G0_0_1_5_0_1 + 0.194708994708991*G0_0_1_7_1_0 - 0.194708994708996*G0_0_1_8_1_1 - 0.194708994708998*G0_0_1_9_1_0 + 0.194708994708989*G0_0_1_9_1_1 + 0.194708994708998*G0_0_1_10_1_0 + 0.194708994709001*G0_0_1_10_1_1 - 0.194708994708987*G0_0_1_11_1_0 - 0.194708994708989*G0_0_1_11_1_1 + 0.0677248677248653*G0_1_0_1_0_0 - 0.0677248677248712*G0_1_0_2_0_1 - 0.0677248677248763*G0_1_0_3_0_0 + 0.0677248677248601*G0_1_0_3_0_1 + 0.0677248677248763*G0_1_0_4_0_0 + 0.0677248677248723*G0_1_0_4_0_1 - 0.0677248677248642*G0_1_0_5_0_0 - 0.0677248677248604*G0_1_0_5_0_1 + 0.0677248677248653*G0_1_0_7_1_0 - 0.0677248677248712*G0_1_0_8_1_1 - 0.0677248677248763*G0_1_0_9_1_0 + 0.0677248677248601*G0_1_0_9_1_1 + 0.0677248677248763*G0_1_0_10_1_0 + 0.0677248677248723*G0_1_0_10_1_1 - 0.0677248677248642*G0_1_0_11_1_0 - 0.0677248677248604*G0_1_0_11_1_1 - 0.0550264550264598*G0_1_1_0_0_0 - 0.0550264550264598*G0_1_1_0_0_1 + 0.317460317460311*G0_1_1_1_0_0 - 0.029629629629631*G0_1_1_2_0_1 + 0.313227513227509*G0_1_1_3_0_0 + 0.660317460317451*G0_1_1_3_0_1 - 0.313227513227509*G0_1_1_4_0_0 + 0.0846560846560908*G0_1_1_4_0_1 - 0.262433862433851*G0_1_1_5_0_0 - 0.660317460317451*G0_1_1_5_0_1 - 0.0550264550264598*G0_1_1_6_1_0 - 0.0550264550264598*G0_1_1_6_1_1 + 0.317460317460311*G0_1_1_7_1_0 - 0.029629629629631*G0_1_1_8_1_1 + 0.313227513227509*G0_1_1_9_1_0 + 0.660317460317451*G0_1_1_9_1_1 - 0.313227513227509*G0_1_1_10_1_0 + 0.0846560846560908*G0_1_1_10_1_1 - 0.262433862433851*G0_1_1_11_1_0 - 0.660317460317451*G0_1_1_11_1_1; + A[775] = -A[769] - 2.26455026455026*G0_0_0_0_0_0 - 2.26455026455026*G0_0_0_0_0_1 + 2.34920634920635*G0_0_0_1_0_0 - 1.6042328042328*G0_0_0_2_0_1 + 1.405291005291*G0_0_0_3_0_0 + 5.35873015873015*G0_0_0_3_0_1 - 1.405291005291*G0_0_0_4_0_0 + 3.86878306878307*G0_0_0_4_0_1 - 0.0846560846560837*G0_0_0_5_0_0 - 5.35873015873016*G0_0_0_5_0_1 - 2.26455026455026*G0_0_0_6_1_0 - 2.26455026455026*G0_0_0_6_1_1 + 2.34920634920635*G0_0_0_7_1_0 - 1.6042328042328*G0_0_0_8_1_1 + 1.405291005291*G0_0_0_9_1_0 + 5.35873015873015*G0_0_0_9_1_1 - 1.405291005291*G0_0_0_10_1_0 + 3.86878306878307*G0_0_0_10_1_1 - 0.0846560846560837*G0_0_0_11_1_0 - 5.35873015873016*G0_0_0_11_1_1 + 0.795767195767192*G0_0_1_0_0_0 + 0.795767195767193*G0_0_1_0_0_1 + 3.26772486772486*G0_0_1_1_0_0 - 0.795767195767196*G0_0_1_2_0_1 + 0.880423280423276*G0_0_1_3_0_0 + 4.94391534391533*G0_0_1_3_0_1 - 0.880423280423276*G0_0_1_4_0_0 - 4.06349206349205*G0_0_1_5_0_0 - 4.94391534391534*G0_0_1_5_0_1 + 0.795767195767192*G0_0_1_6_1_0 + 0.795767195767193*G0_0_1_6_1_1 + 3.26772486772486*G0_0_1_7_1_0 - 0.795767195767196*G0_0_1_8_1_1 + 0.880423280423276*G0_0_1_9_1_0 + 4.94391534391533*G0_0_1_9_1_1 - 0.880423280423276*G0_0_1_10_1_0 - 4.06349206349205*G0_0_1_11_1_0 - 4.94391534391534*G0_0_1_11_1_1 + 0.753439153439152*G0_1_0_0_0_0 + 0.753439153439152*G0_1_0_0_0_1 + 3.18306878306878*G0_1_0_1_0_0 - 0.753439153439154*G0_1_0_2_0_1 + 0.922751322751317*G0_1_0_3_0_0 + 4.85925925925925*G0_1_0_3_0_1 - 0.922751322751317*G0_1_0_4_0_0 - 3.93650793650793*G0_1_0_5_0_0 - 4.85925925925925*G0_1_0_5_0_1 + 0.753439153439152*G0_1_0_6_1_0 + 0.753439153439152*G0_1_0_6_1_1 + 3.18306878306878*G0_1_0_7_1_0 - 0.753439153439154*G0_1_0_8_1_1 + 0.922751322751317*G0_1_0_9_1_0 + 4.85925925925925*G0_1_0_9_1_1 - 0.922751322751317*G0_1_0_10_1_0 - 3.93650793650793*G0_1_0_11_1_0 - 4.85925925925925*G0_1_0_11_1_1 - 0.06772486772487*G0_1_1_0_0_0 - 0.0677248677248694*G0_1_1_0_0_1 + 4.19894179894179*G0_1_1_1_0_0 - 1.42222222222222*G0_1_1_2_0_1 + 1.42222222222221*G0_1_1_3_0_0 + 7.04338624338623*G0_1_1_3_0_1 - 1.42222222222221*G0_1_1_4_0_0 + 1.48994708994709*G0_1_1_4_0_1 - 4.13121693121692*G0_1_1_5_0_0 - 7.04338624338623*G0_1_1_5_0_1 - 0.06772486772487*G0_1_1_6_1_0 - 0.0677248677248694*G0_1_1_6_1_1 + 4.19894179894179*G0_1_1_7_1_0 - 1.42222222222222*G0_1_1_8_1_1 + 1.42222222222221*G0_1_1_9_1_0 + 7.04338624338623*G0_1_1_9_1_1 - 1.42222222222221*G0_1_1_10_1_0 + 1.48994708994709*G0_1_1_10_1_1 - 4.13121693121692*G0_1_1_11_1_0 - 7.04338624338623*G0_1_1_11_1_1; + A[310] = A[775]; + A[592] = A[127]; + A[166] = 0.0; + A[488] = 0.0; + A[575] = 0.0; + A[678] = A[213]; + A[606] = 0.0; + A[637] = 0.0; + A[244] = A[709]; + A[353] = 0.0; + A[16] = 0.0; + A[733] = 0.0; + A[420] = A[14] + 0.0282186948853618*G0_0_1_1_0_0 - 0.0282186948853614*G0_0_1_2_0_1 - 0.0282186948853619*G0_0_1_3_0_0 + 0.0282186948853614*G0_0_1_3_0_1 + 0.0282186948853619*G0_0_1_4_0_0 + 0.0282186948853603*G0_0_1_4_0_1 - 0.0282186948853627*G0_0_1_5_0_0 - 0.0282186948853614*G0_0_1_5_0_1 + 0.0282186948853618*G0_0_1_7_1_0 - 0.0282186948853614*G0_0_1_8_1_1 - 0.0282186948853619*G0_0_1_9_1_0 + 0.0282186948853614*G0_0_1_9_1_1 + 0.0282186948853619*G0_0_1_10_1_0 + 0.0282186948853603*G0_0_1_10_1_1 - 0.0282186948853627*G0_0_1_11_1_0 - 0.0282186948853614*G0_0_1_11_1_1 - 0.0282186948853618*G0_1_0_1_0_0 + 0.0282186948853614*G0_1_0_2_0_1 + 0.0282186948853619*G0_1_0_3_0_0 - 0.0282186948853614*G0_1_0_3_0_1 - 0.0282186948853619*G0_1_0_4_0_0 - 0.0282186948853603*G0_1_0_4_0_1 + 0.0282186948853628*G0_1_0_5_0_0 + 0.0282186948853614*G0_1_0_5_0_1 - 0.0282186948853618*G0_1_0_7_1_0 + 0.0282186948853614*G0_1_0_8_1_1 + 0.0282186948853619*G0_1_0_9_1_0 - 0.0282186948853614*G0_1_0_9_1_1 - 0.0282186948853619*G0_1_0_10_1_0 - 0.0282186948853603*G0_1_0_10_1_1 + 0.0282186948853628*G0_1_0_11_1_0 + 0.0282186948853614*G0_1_0_11_1_1; + A[376] = 0.0; + A[59] = 0.0; + A[758] = 0.0; + A[455] = 0.0; + A[411] = 0.0; + A[86] = 0.0; + A[795] = -A[555] + 0.411992945326279*G0_0_0_0_0_0 + 0.411992945326279*G0_0_0_0_0_1 + 0.0451499118165776*G0_0_0_1_0_0 + 0.163668430335097*G0_0_0_2_0_1 - 0.0395061728395059*G0_0_0_3_0_0 - 0.158024691358026*G0_0_0_3_0_1 + 0.0395061728395059*G0_0_0_4_0_0 - 0.575661375661376*G0_0_0_4_0_1 - 0.457142857142856*G0_0_0_5_0_0 + 0.158024691358026*G0_0_0_5_0_1 + 0.411992945326279*G0_0_0_6_1_0 + 0.411992945326279*G0_0_0_6_1_1 + 0.0451499118165776*G0_0_0_7_1_0 + 0.163668430335097*G0_0_0_8_1_1 - 0.0395061728395059*G0_0_0_9_1_0 - 0.158024691358026*G0_0_0_9_1_1 + 0.0395061728395059*G0_0_0_10_1_0 - 0.575661375661376*G0_0_0_10_1_1 - 0.457142857142856*G0_0_0_11_1_0 + 0.158024691358026*G0_0_0_11_1_1 + 0.411992945326279*G0_0_1_0_0_0 + 0.411992945326279*G0_0_1_0_0_1 + 0.0451499118165778*G0_0_1_1_0_0 + 0.163668430335098*G0_0_1_2_0_1 - 0.0395061728395056*G0_0_1_3_0_0 - 0.158024691358025*G0_0_1_3_0_1 + 0.0395061728395056*G0_0_1_4_0_0 - 0.575661375661376*G0_0_1_4_0_1 - 0.457142857142857*G0_0_1_5_0_0 + 0.158024691358026*G0_0_1_5_0_1 + 0.411992945326279*G0_0_1_6_1_0 + 0.411992945326279*G0_0_1_6_1_1 + 0.0451499118165778*G0_0_1_7_1_0 + 0.163668430335098*G0_0_1_8_1_1 - 0.0395061728395056*G0_0_1_9_1_0 - 0.158024691358025*G0_0_1_9_1_1 + 0.0395061728395056*G0_0_1_10_1_0 - 0.575661375661376*G0_0_1_10_1_1 - 0.457142857142857*G0_0_1_11_1_0 + 0.158024691358026*G0_0_1_11_1_1; + A[824] = 0.0; + A[124] = A[775] + 3.74179894179894*G0_0_0_0_0_0 + 3.74179894179894*G0_0_0_0_0_1 - 2.25185185185185*G0_0_0_1_0_0 + 5.48571428571428*G0_0_0_2_0_1 + 4.97777777777777*G0_0_0_3_0_0 - 2.75978835978836*G0_0_0_3_0_1 - 4.97777777777777*G0_0_0_4_0_0 - 9.22751322751322*G0_0_0_4_0_1 - 1.48994708994709*G0_0_0_5_0_0 + 2.75978835978836*G0_0_0_5_0_1 + 3.74179894179894*G0_0_0_6_1_0 + 3.74179894179894*G0_0_0_6_1_1 - 2.25185185185185*G0_0_0_7_1_0 + 5.48571428571428*G0_0_0_8_1_1 + 4.97777777777777*G0_0_0_9_1_0 - 2.75978835978836*G0_0_0_9_1_1 - 4.97777777777777*G0_0_0_10_1_0 - 9.22751322751322*G0_0_0_10_1_1 - 1.48994708994709*G0_0_0_11_1_0 + 2.75978835978836*G0_0_0_11_1_1 - 0.126984126984127*G0_0_1_0_0_0 - 0.126984126984127*G0_0_1_0_0_1 - 2.25185185185185*G0_0_1_1_0_0 + 1.61693121693122*G0_0_1_2_0_1 + 1.10899470899471*G0_0_1_3_0_0 - 2.75978835978836*G0_0_1_3_0_1 - 1.10899470899471*G0_0_1_4_0_0 - 1.48994708994709*G0_0_1_4_0_1 + 2.37883597883598*G0_0_1_5_0_0 + 2.75978835978836*G0_0_1_5_0_1 - 0.126984126984127*G0_0_1_6_1_0 - 0.126984126984127*G0_0_1_6_1_1 - 2.25185185185185*G0_0_1_7_1_0 + 1.61693121693122*G0_0_1_8_1_1 + 1.10899470899471*G0_0_1_9_1_0 - 2.75978835978836*G0_0_1_9_1_1 - 1.10899470899471*G0_0_1_10_1_0 - 1.48994708994709*G0_0_1_10_1_1 + 2.37883597883598*G0_0_1_11_1_0 + 2.75978835978836*G0_0_1_11_1_1 - 0.126984126984127*G0_1_0_0_0_0 - 0.126984126984127*G0_1_0_0_0_1 - 2.25185185185185*G0_1_0_1_0_0 + 1.61693121693122*G0_1_0_2_0_1 + 1.10899470899471*G0_1_0_3_0_0 - 2.75978835978836*G0_1_0_3_0_1 - 1.10899470899471*G0_1_0_4_0_0 - 1.48994708994709*G0_1_0_4_0_1 + 2.37883597883598*G0_1_0_5_0_0 + 2.75978835978836*G0_1_0_5_0_1 - 0.126984126984127*G0_1_0_6_1_0 - 0.126984126984127*G0_1_0_6_1_1 - 2.25185185185185*G0_1_0_7_1_0 + 1.61693121693122*G0_1_0_8_1_1 + 1.10899470899471*G0_1_0_9_1_0 - 2.75978835978836*G0_1_0_9_1_1 - 1.10899470899471*G0_1_0_10_1_0 - 1.48994708994709*G0_1_0_10_1_1 + 2.37883597883598*G0_1_0_11_1_0 + 2.75978835978836*G0_1_0_11_1_1 + 1.48994708994709*G0_1_1_0_0_0 + 1.48994708994709*G0_1_1_0_0_1 + 1.48994708994709*G0_1_1_2_0_1 + 1.48994708994709*G0_1_1_3_0_0 - 1.48994708994709*G0_1_1_4_0_0 - 2.97989417989418*G0_1_1_4_0_1 - 1.48994708994709*G0_1_1_5_0_0 + 1.48994708994709*G0_1_1_6_1_0 + 1.48994708994709*G0_1_1_6_1_1 + 1.48994708994709*G0_1_1_8_1_1 + 1.48994708994709*G0_1_1_9_1_0 - 1.48994708994709*G0_1_1_10_1_0 - 2.97989417989418*G0_1_1_10_1_1 - 1.48994708994709*G0_1_1_11_1_0; + A[849] = 0.0; + A[175] = 0.0; + A[882] = 0.0; + A[495] = A[30]; + A[202] = 0.0; + A[580] = 0.0; + A[524] = 0.0; + A[233] = 0.0; + A[681] = A[216]; + A[613] = 0.0; + A[553] = 0.0; + A[706] = A[181] + 0.14673721340388*G0_0_0_0_0_0 + 0.146737213403879*G0_0_0_0_0_1 + 0.14673721340388*G0_0_0_2_0_1 + 0.14673721340388*G0_0_0_3_0_0 - 0.14673721340388*G0_0_0_4_0_0 - 0.293474426807759*G0_0_0_4_0_1 - 0.146737213403879*G0_0_0_5_0_0 + 0.14673721340388*G0_0_0_6_1_0 + 0.146737213403879*G0_0_0_6_1_1 + 0.14673721340388*G0_0_0_8_1_1 + 0.14673721340388*G0_0_0_9_1_0 - 0.14673721340388*G0_0_0_10_1_0 - 0.293474426807759*G0_0_0_10_1_1 - 0.146737213403879*G0_0_0_11_1_0; + A[151] = -A[706] + 0.163668430335098*G0_1_0_0_0_0 + 0.163668430335098*G0_1_0_0_0_1 + 0.411992945326281*G0_1_0_1_0_0 - 0.0451499118165795*G0_1_0_2_0_1 + 0.158024691358024*G0_1_0_3_0_0 + 0.615167548500885*G0_1_0_3_0_1 - 0.158024691358024*G0_1_0_4_0_0 - 0.118518518518518*G0_1_0_4_0_1 - 0.575661375661379*G0_1_0_5_0_0 - 0.615167548500885*G0_1_0_5_0_1 + 0.163668430335098*G0_1_0_6_1_0 + 0.163668430335098*G0_1_0_6_1_1 + 0.411992945326281*G0_1_0_7_1_0 - 0.0451499118165795*G0_1_0_8_1_1 + 0.158024691358024*G0_1_0_9_1_0 + 0.615167548500885*G0_1_0_9_1_1 - 0.158024691358024*G0_1_0_10_1_0 - 0.118518518518518*G0_1_0_10_1_1 - 0.575661375661379*G0_1_0_11_1_0 - 0.615167548500885*G0_1_0_11_1_1; + A[736] = -A[151] + 0.0790123456790123*G0_0_0_0_0_0 + 0.0790123456790123*G0_0_0_0_0_1 - 0.186243386243387*G0_0_0_1_0_0 - 0.0225749559082889*G0_0_0_2_0_1 - 0.310405643738976*G0_0_0_3_0_0 - 0.474074074074074*G0_0_0_3_0_1 + 0.310405643738976*G0_0_0_4_0_0 - 0.0564373897707236*G0_0_0_4_0_1 + 0.107231040564374*G0_0_0_5_0_0 + 0.474074074074075*G0_0_0_5_0_1 + 0.0790123456790123*G0_0_0_6_1_0 + 0.0790123456790123*G0_0_0_6_1_1 - 0.186243386243387*G0_0_0_7_1_0 - 0.0225749559082889*G0_0_0_8_1_1 - 0.310405643738976*G0_0_0_9_1_0 - 0.474074074074074*G0_0_0_9_1_1 + 0.310405643738976*G0_0_0_10_1_0 - 0.0564373897707236*G0_0_0_10_1_1 + 0.107231040564374*G0_0_0_11_1_0 + 0.474074074074075*G0_0_0_11_1_1 + 0.0564373897707236*G0_1_0_0_0_0 + 0.0564373897707237*G0_1_0_0_0_1 + 0.0564373897707222*G0_1_0_2_0_1 + 0.0564373897707227*G0_1_0_3_0_0 - 0.0564373897707227*G0_1_0_4_0_0 - 0.112874779541446*G0_1_0_4_0_1 - 0.0564373897707255*G0_1_0_5_0_0 + 0.0564373897707236*G0_1_0_6_1_0 + 0.0564373897707237*G0_1_0_6_1_1 + 0.0564373897707222*G0_1_0_8_1_1 + 0.0564373897707227*G0_1_0_9_1_0 - 0.0564373897707227*G0_1_0_10_1_0 - 0.112874779541446*G0_1_0_10_1_1 - 0.0564373897707255*G0_1_0_11_1_0; + A[271] = A[736]; + A[630] = 0.0; + A[251] = A[716]; + A[675] = A[210]; + A[280] = A[745]; + A[704] = 0.0; + A[301] = A[766]; + A[257] = 0.0; + A[23] = 0.0; + A[740] = -A[743] - 0.225749559082892*G0_0_1_0_0_0 - 0.225749559082892*G0_0_1_0_0_1 - 0.225749559082893*G0_0_1_1_0_0 - 0.225749559082892*G0_0_1_3_0_1 + 0.225749559082892*G0_0_1_4_0_1 + 0.451499118165785*G0_0_1_5_0_0 + 0.225749559082893*G0_0_1_5_0_1 - 0.225749559082892*G0_0_1_6_1_0 - 0.225749559082892*G0_0_1_6_1_1 - 0.225749559082893*G0_0_1_7_1_0 - 0.225749559082892*G0_0_1_9_1_1 + 0.225749559082892*G0_0_1_10_1_1 + 0.451499118165785*G0_0_1_11_1_0 + 0.225749559082893*G0_0_1_11_1_1 + 0.609523809523808*G0_1_1_0_0_0 + 0.609523809523808*G0_1_1_0_0_1 - 0.112874779541447*G0_1_1_1_0_0 + 0.383774250440917*G0_1_1_2_0_1 + 0.0451499118165795*G0_1_1_3_0_0 - 0.451499118165784*G0_1_1_3_0_1 - 0.0451499118165795*G0_1_1_4_0_0 - 0.993298059964726*G0_1_1_4_0_1 - 0.496649029982362*G0_1_1_5_0_0 + 0.451499118165785*G0_1_1_5_0_1 + 0.609523809523808*G0_1_1_6_1_0 + 0.609523809523808*G0_1_1_6_1_1 - 0.112874779541447*G0_1_1_7_1_0 + 0.383774250440917*G0_1_1_8_1_1 + 0.0451499118165795*G0_1_1_9_1_0 - 0.451499118165784*G0_1_1_9_1_1 - 0.0451499118165795*G0_1_1_10_1_0 - 0.993298059964726*G0_1_1_10_1_1 - 0.496649029982362*G0_1_1_11_1_0 + 0.451499118165785*G0_1_1_11_1_1; + A[252] = A[740] - 0.0451499118165807*G0_0_0_0_0_0 - 0.0451499118165807*G0_0_0_0_0_1 - 0.0451499118165775*G0_0_0_1_0_0 - 0.0451499118165806*G0_0_0_3_0_1 + 0.0451499118165872*G0_0_0_4_0_1 + 0.0902998236331582*G0_0_0_5_0_0 + 0.0451499118165806*G0_0_0_5_0_1 - 0.0451499118165807*G0_0_0_6_1_0 - 0.0451499118165807*G0_0_0_6_1_1 - 0.0451499118165775*G0_0_0_7_1_0 - 0.0451499118165806*G0_0_0_9_1_1 + 0.0451499118165872*G0_0_0_10_1_1 + 0.0902998236331582*G0_0_0_11_1_0 + 0.0451499118165806*G0_0_0_11_1_1 - 0.146737213403882*G0_0_1_0_0_0 - 0.146737213403882*G0_0_1_0_0_1 + 0.146737213403881*G0_0_1_1_0_0 - 0.530511463844802*G0_0_1_2_0_1 - 0.76754850088184*G0_0_1_3_0_0 - 0.0902998236331577*G0_0_1_3_0_1 + 0.76754850088184*G0_0_1_4_0_0 + 0.677248677248684*G0_0_1_4_0_1 + 0.0902998236331579*G0_0_1_5_0_1 - 0.146737213403882*G0_0_1_6_1_0 - 0.146737213403882*G0_0_1_6_1_1 + 0.146737213403881*G0_0_1_7_1_0 - 0.530511463844802*G0_0_1_8_1_1 - 0.76754850088184*G0_0_1_9_1_0 - 0.0902998236331577*G0_0_1_9_1_1 + 0.76754850088184*G0_0_1_10_1_0 + 0.677248677248684*G0_0_1_10_1_1 + 0.0902998236331579*G0_0_1_11_1_1 + 0.0790123456790122*G0_1_0_0_0_0 + 0.0790123456790119*G0_1_0_0_0_1 + 0.237037037037037*G0_1_0_1_0_0 - 0.395061728395064*G0_1_0_2_0_1 - 0.632098765432104*G0_1_0_3_0_0 + 0.632098765432104*G0_1_0_4_0_0 + 0.316049382716053*G0_1_0_4_0_1 - 0.316049382716049*G0_1_0_5_0_0 + 0.0790123456790122*G0_1_0_6_1_0 + 0.0790123456790119*G0_1_0_6_1_1 + 0.237037037037037*G0_1_0_7_1_0 - 0.395061728395064*G0_1_0_8_1_1 - 0.632098765432104*G0_1_0_9_1_0 + 0.632098765432104*G0_1_0_10_1_0 + 0.316049382716053*G0_1_0_10_1_1 - 0.316049382716049*G0_1_0_11_1_0 - 1.37707231040564*G0_1_1_0_0_0 - 1.37707231040564*G0_1_1_0_0_1 + 0.474074074074074*G0_1_1_1_0_0 - 1.51252204585538*G0_1_1_2_0_1 - 1.17389770723105*G0_1_1_3_0_0 + 0.81269841269841*G0_1_1_3_0_1 + 1.17389770723105*G0_1_1_4_0_0 + 2.88959435626103*G0_1_1_4_0_1 + 0.90299823633157*G0_1_1_5_0_0 - 0.81269841269841*G0_1_1_5_0_1 - 1.37707231040564*G0_1_1_6_1_0 - 1.37707231040564*G0_1_1_6_1_1 + 0.474074074074074*G0_1_1_7_1_0 - 1.51252204585538*G0_1_1_8_1_1 - 1.17389770723105*G0_1_1_9_1_0 + 0.81269841269841*G0_1_1_9_1_1 + 1.17389770723105*G0_1_1_10_1_0 + 2.88959435626103*G0_1_1_10_1_1 + 0.90299823633157*G0_1_1_11_1_0 - 0.81269841269841*G0_1_1_11_1_1; + A[428] = -A[252] + 0.361199294532629*G0_0_0_0_0_0 + 0.361199294532629*G0_0_0_0_0_1 + 0.361199294532626*G0_0_0_1_0_0 + 0.361199294532629*G0_0_0_3_0_1 - 0.361199294532637*G0_0_0_4_0_1 - 0.722398589065255*G0_0_0_5_0_0 - 0.361199294532629*G0_0_0_5_0_1 + 0.361199294532629*G0_0_0_6_1_0 + 0.361199294532629*G0_0_0_6_1_1 + 0.361199294532626*G0_0_0_7_1_0 + 0.361199294532629*G0_0_0_9_1_1 - 0.361199294532637*G0_0_0_10_1_1 - 0.722398589065255*G0_0_0_11_1_0 - 0.361199294532629*G0_0_0_11_1_1 - 0.0451499118165753*G0_0_1_0_0_0 - 0.0451499118165758*G0_0_1_0_0_1 - 0.767548500881836*G0_0_1_1_0_0 + 1.67054673721341*G0_0_1_2_0_1 + 2.61869488536156*G0_0_1_3_0_0 + 0.180599647266314*G0_0_1_3_0_1 - 2.61869488536156*G0_0_1_4_0_0 - 1.62539682539683*G0_0_1_4_0_1 + 0.812698412698411*G0_0_1_5_0_0 - 0.180599647266314*G0_0_1_5_0_1 - 0.0451499118165753*G0_0_1_6_1_0 - 0.0451499118165758*G0_0_1_6_1_1 - 0.767548500881836*G0_0_1_7_1_0 + 1.67054673721341*G0_0_1_8_1_1 + 2.61869488536156*G0_0_1_9_1_0 + 0.180599647266314*G0_0_1_9_1_1 - 2.61869488536156*G0_0_1_10_1_0 - 1.62539682539683*G0_0_1_10_1_1 + 0.812698412698411*G0_0_1_11_1_0 - 0.180599647266314*G0_0_1_11_1_1 + 1.03844797178131*G0_1_0_0_0_0 + 1.03844797178131*G0_1_0_0_0_1 - 0.225749559082893*G0_1_0_1_0_0 + 2.21234567901235*G0_1_0_2_0_1 + 3.16049382716049*G0_1_0_3_0_0 + 0.722398589065252*G0_1_0_3_0_1 - 3.16049382716049*G0_1_0_4_0_0 - 3.25079365079365*G0_1_0_4_0_1 - 0.812698412698412*G0_1_0_5_0_0 - 0.722398589065253*G0_1_0_5_0_1 + 1.03844797178131*G0_1_0_6_1_0 + 1.03844797178131*G0_1_0_6_1_1 - 0.225749559082893*G0_1_0_7_1_0 + 2.21234567901235*G0_1_0_8_1_1 + 3.16049382716049*G0_1_0_9_1_0 + 0.722398589065252*G0_1_0_9_1_1 - 3.16049382716049*G0_1_0_10_1_0 - 3.25079365079365*G0_1_0_10_1_1 - 0.812698412698412*G0_1_0_11_1_0 - 0.722398589065253*G0_1_0_11_1_1 + 0.0902998236331589*G0_1_1_0_0_0 + 0.0902998236331591*G0_1_1_0_0_1 - 0.270899470899471*G0_1_1_1_0_0 + 0.632098765432099*G0_1_1_2_0_1 + 0.902998236331567*G0_1_1_3_0_0 - 0.902998236331567*G0_1_1_4_0_0 - 0.722398589065257*G0_1_1_4_0_1 + 0.180599647266312*G0_1_1_5_0_0 + 0.0902998236331589*G0_1_1_6_1_0 + 0.0902998236331591*G0_1_1_6_1_1 - 0.270899470899471*G0_1_1_7_1_0 + 0.632098765432099*G0_1_1_8_1_1 + 0.902998236331567*G0_1_1_9_1_0 - 0.902998236331567*G0_1_1_10_1_0 - 0.722398589065257*G0_1_1_10_1_1 + 0.180599647266312*G0_1_1_11_1_0; + A[368] = A[252] + 0.270899470899472*G0_0_1_0_0_0 + 0.270899470899472*G0_0_1_0_0_1 + 0.180599647266313*G0_0_1_1_0_0 + 0.0902998236331579*G0_0_1_2_0_1 + 0.0902998236331568*G0_0_1_3_0_0 + 0.180599647266312*G0_0_1_3_0_1 - 0.0902998236331568*G0_0_1_4_0_0 - 0.361199294532629*G0_0_1_4_0_1 - 0.451499118165785*G0_0_1_5_0_0 - 0.180599647266313*G0_0_1_5_0_1 + 0.270899470899472*G0_0_1_6_1_0 + 0.270899470899472*G0_0_1_6_1_1 + 0.180599647266313*G0_0_1_7_1_0 + 0.0902998236331579*G0_0_1_8_1_1 + 0.0902998236331568*G0_0_1_9_1_0 + 0.180599647266312*G0_0_1_9_1_1 - 0.0902998236331568*G0_0_1_10_1_0 - 0.361199294532629*G0_0_1_10_1_1 - 0.451499118165785*G0_0_1_11_1_0 - 0.180599647266313*G0_0_1_11_1_1 - 0.270899470899472*G0_1_0_0_0_0 - 0.270899470899472*G0_1_0_0_0_1 - 0.180599647266313*G0_1_0_1_0_0 - 0.0902998236331579*G0_1_0_2_0_1 - 0.0902998236331567*G0_1_0_3_0_0 - 0.180599647266312*G0_1_0_3_0_1 + 0.0902998236331567*G0_1_0_4_0_0 + 0.361199294532629*G0_1_0_4_0_1 + 0.451499118165785*G0_1_0_5_0_0 + 0.180599647266313*G0_1_0_5_0_1 - 0.270899470899472*G0_1_0_6_1_0 - 0.270899470899472*G0_1_0_6_1_1 - 0.180599647266313*G0_1_0_7_1_0 - 0.0902998236331579*G0_1_0_8_1_1 - 0.0902998236331567*G0_1_0_9_1_0 - 0.180599647266312*G0_1_0_9_1_1 + 0.0902998236331567*G0_1_0_10_1_0 + 0.361199294532629*G0_1_0_10_1_1 + 0.451499118165785*G0_1_0_11_1_0 + 0.180599647266313*G0_1_0_11_1_1; + A[628] = -A[252] + 0.451499118165783*G0_1_0_0_0_0 + 0.451499118165783*G0_1_0_0_0_1 + 0.451499118165784*G0_1_0_1_0_0 + 0.45149911816578*G0_1_0_3_0_1 - 0.451499118165777*G0_1_0_4_0_1 - 0.902998236331566*G0_1_0_5_0_0 - 0.45149911816578*G0_1_0_5_0_1 + 0.451499118165783*G0_1_0_6_1_0 + 0.451499118165783*G0_1_0_6_1_1 + 0.451499118165784*G0_1_0_7_1_0 + 0.45149911816578*G0_1_0_9_1_1 - 0.451499118165777*G0_1_0_10_1_1 - 0.902998236331566*G0_1_0_11_1_0 - 0.45149911816578*G0_1_0_11_1_1 - 1.30934744268078*G0_1_1_0_0_0 - 1.30934744268078*G0_1_1_0_0_1 + 1.76084656084656*G0_1_1_1_0_0 - 2.12204585537919*G0_1_1_2_0_1 - 1.17389770723105*G0_1_1_3_0_0 + 2.7089947089947*G0_1_1_3_0_1 + 1.17389770723105*G0_1_1_4_0_0 + 3.43139329805997*G0_1_1_4_0_1 - 0.45149911816578*G0_1_1_5_0_0 - 2.7089947089947*G0_1_1_5_0_1 - 1.30934744268078*G0_1_1_6_1_0 - 1.30934744268078*G0_1_1_6_1_1 + 1.76084656084656*G0_1_1_7_1_0 - 2.12204585537919*G0_1_1_8_1_1 - 1.17389770723105*G0_1_1_9_1_0 + 2.7089947089947*G0_1_1_9_1_1 + 1.17389770723105*G0_1_1_10_1_0 + 3.43139329805997*G0_1_1_10_1_1 - 0.45149911816578*G0_1_1_11_1_0 - 2.7089947089947*G0_1_1_11_1_1; + A[830] = -A[368] + 0.451499118165784*G0_0_1_0_0_0 + 0.451499118165784*G0_0_1_0_0_1 + 0.451499118165784*G0_0_1_1_0_0 + 0.451499118165783*G0_0_1_3_0_1 - 0.451499118165784*G0_0_1_4_0_1 - 0.902998236331569*G0_0_1_5_0_0 - 0.451499118165784*G0_0_1_5_0_1 + 0.451499118165784*G0_0_1_6_1_0 + 0.451499118165784*G0_0_1_6_1_1 + 0.451499118165784*G0_0_1_7_1_0 + 0.451499118165783*G0_0_1_9_1_1 - 0.451499118165784*G0_0_1_10_1_1 - 0.902998236331569*G0_0_1_11_1_0 - 0.451499118165784*G0_0_1_11_1_1 - 1.30934744268077*G0_1_1_0_0_0 - 1.30934744268077*G0_1_1_0_0_1 + 0.677248677248677*G0_1_1_1_0_0 - 1.03844797178131*G0_1_1_2_0_1 - 0.0902998236331605*G0_1_1_3_0_0 + 1.62539682539682*G0_1_1_3_0_1 + 0.0902998236331605*G0_1_1_4_0_0 + 2.34779541446208*G0_1_1_4_0_1 + 0.632098765432097*G0_1_1_5_0_0 - 1.62539682539682*G0_1_1_5_0_1 - 1.30934744268077*G0_1_1_6_1_0 - 1.30934744268077*G0_1_1_6_1_1 + 0.677248677248677*G0_1_1_7_1_0 - 1.03844797178131*G0_1_1_8_1_1 - 0.0902998236331605*G0_1_1_9_1_0 + 1.62539682539682*G0_1_1_9_1_1 + 0.0902998236331605*G0_1_1_10_1_0 + 2.34779541446208*G0_1_1_10_1_1 + 0.632098765432097*G0_1_1_11_1_0 - 1.62539682539682*G0_1_1_11_1_1; + A[863] = A[368] + 1.08359788359789*G0_1_1_0_0_0 + 1.08359788359789*G0_1_1_0_0_1 + 1.08359788359789*G0_1_1_2_0_1 + 1.08359788359789*G0_1_1_3_0_0 - 1.08359788359789*G0_1_1_4_0_0 - 2.16719576719577*G0_1_1_4_0_1 - 1.08359788359789*G0_1_1_5_0_0 + 1.08359788359789*G0_1_1_6_1_0 + 1.08359788359789*G0_1_1_6_1_1 + 1.08359788359789*G0_1_1_8_1_1 + 1.08359788359789*G0_1_1_9_1_0 - 1.08359788359789*G0_1_1_10_1_0 - 2.16719576719577*G0_1_1_10_1_1 - 1.08359788359789*G0_1_1_11_1_0; + A[627] = A[628] - 1.08359788359788*G0_1_1_1_0_0 + 1.08359788359789*G0_1_1_2_0_1 + 1.08359788359789*G0_1_1_3_0_0 - 1.08359788359788*G0_1_1_3_0_1 - 1.08359788359789*G0_1_1_4_0_0 - 1.08359788359789*G0_1_1_4_0_1 + 1.08359788359788*G0_1_1_5_0_0 + 1.08359788359788*G0_1_1_5_0_1 - 1.08359788359788*G0_1_1_7_1_0 + 1.08359788359789*G0_1_1_8_1_1 + 1.08359788359789*G0_1_1_9_1_0 - 1.08359788359788*G0_1_1_9_1_1 - 1.08359788359789*G0_1_1_10_1_0 - 1.08359788359789*G0_1_1_10_1_1 + 1.08359788359788*G0_1_1_11_1_0 + 1.08359788359788*G0_1_1_11_1_1; + A[254] = A[428] + 0.812698412698409*G0_0_1_0_0_0 + 0.812698412698409*G0_0_1_0_0_1 + 0.361199294532629*G0_0_1_1_0_0 + 0.451499118165778*G0_0_1_2_0_1 + 0.451499118165774*G0_0_1_3_0_0 + 0.361199294532625*G0_0_1_3_0_1 - 0.451499118165774*G0_0_1_4_0_0 - 1.26419753086419*G0_0_1_4_0_1 - 1.17389770723104*G0_0_1_5_0_0 - 0.361199294532626*G0_0_1_5_0_1 + 0.812698412698409*G0_0_1_6_1_0 + 0.812698412698409*G0_0_1_6_1_1 + 0.361199294532629*G0_0_1_7_1_0 + 0.451499118165778*G0_0_1_8_1_1 + 0.451499118165774*G0_0_1_9_1_0 + 0.361199294532625*G0_0_1_9_1_1 - 0.451499118165774*G0_0_1_10_1_0 - 1.26419753086419*G0_0_1_10_1_1 - 1.17389770723104*G0_0_1_11_1_0 - 0.361199294532626*G0_0_1_11_1_1 - 0.812698412698409*G0_1_0_0_0_0 - 0.812698412698409*G0_1_0_0_0_1 - 0.361199294532629*G0_1_0_1_0_0 - 0.451499118165778*G0_1_0_2_0_1 - 0.451499118165774*G0_1_0_3_0_0 - 0.361199294532625*G0_1_0_3_0_1 + 0.451499118165774*G0_1_0_4_0_0 + 1.26419753086419*G0_1_0_4_0_1 + 1.17389770723104*G0_1_0_5_0_0 + 0.361199294532626*G0_1_0_5_0_1 - 0.812698412698409*G0_1_0_6_1_0 - 0.812698412698409*G0_1_0_6_1_1 - 0.361199294532629*G0_1_0_7_1_0 - 0.451499118165778*G0_1_0_8_1_1 - 0.451499118165774*G0_1_0_9_1_0 - 0.361199294532625*G0_1_0_9_1_1 + 0.451499118165774*G0_1_0_10_1_0 + 1.26419753086419*G0_1_0_10_1_1 + 1.17389770723104*G0_1_0_11_1_0 + 0.361199294532626*G0_1_0_11_1_1; + A[890] = -A[428] - 1.17389770723104*G0_0_1_0_0_0 - 1.17389770723104*G0_0_1_0_0_1 - 1.17389770723104*G0_0_1_1_0_0 - 1.17389770723104*G0_0_1_3_0_1 + 1.17389770723103*G0_0_1_4_0_1 + 2.34779541446208*G0_0_1_5_0_0 + 1.17389770723104*G0_0_1_5_0_1 - 1.17389770723104*G0_0_1_6_1_0 - 1.17389770723104*G0_0_1_6_1_1 - 1.17389770723104*G0_0_1_7_1_0 - 1.17389770723104*G0_0_1_9_1_1 + 1.17389770723103*G0_0_1_10_1_1 + 2.34779541446208*G0_0_1_11_1_0 + 1.17389770723104*G0_0_1_11_1_1 + 0.31604938271605*G0_1_1_0_0_0 + 0.31604938271605*G0_1_1_0_0_1 - 1.48994708994709*G0_1_1_1_0_0 - 0.496649029982362*G0_1_1_2_0_1 - 2.79929453262786*G0_1_1_3_0_0 - 3.79259259259259*G0_1_1_3_0_1 + 2.79929453262786*G0_1_1_4_0_0 + 0.180599647266312*G0_1_1_4_0_1 + 1.17389770723104*G0_1_1_5_0_0 + 3.79259259259259*G0_1_1_5_0_1 + 0.31604938271605*G0_1_1_6_1_0 + 0.31604938271605*G0_1_1_6_1_1 - 1.48994708994709*G0_1_1_7_1_0 - 0.496649029982362*G0_1_1_8_1_1 - 2.79929453262786*G0_1_1_9_1_0 - 3.79259259259259*G0_1_1_9_1_1 + 2.79929453262786*G0_1_1_10_1_0 + 0.180599647266312*G0_1_1_10_1_1 + 1.17389770723104*G0_1_1_11_1_0 + 3.79259259259259*G0_1_1_11_1_1; + A[425] = A[890]; + A[163] = A[628]; + A[860] = A[830] + 1.08359788359788*G0_1_1_1_0_0 - 1.08359788359789*G0_1_1_2_0_1 - 1.08359788359789*G0_1_1_3_0_0 + 1.08359788359788*G0_1_1_3_0_1 + 1.08359788359789*G0_1_1_4_0_0 + 1.08359788359789*G0_1_1_4_0_1 - 1.08359788359788*G0_1_1_5_0_0 - 1.08359788359788*G0_1_1_5_0_1 + 1.08359788359788*G0_1_1_7_1_0 - 1.08359788359789*G0_1_1_8_1_1 - 1.08359788359789*G0_1_1_9_1_0 + 1.08359788359788*G0_1_1_9_1_1 + 1.08359788359789*G0_1_1_10_1_0 + 1.08359788359789*G0_1_1_10_1_1 - 1.08359788359788*G0_1_1_11_1_0 - 1.08359788359788*G0_1_1_11_1_1; + A[624] = A[740] + 0.0451499118165777*G0_0_1_0_0_0 + 0.0451499118165777*G0_0_1_0_0_1 + 0.0902998236331574*G0_0_1_1_0_0 - 0.0451499118165797*G0_0_1_2_0_1 - 0.0451499118165797*G0_0_1_3_0_0 + 0.0902998236331572*G0_0_1_3_0_1 + 0.0451499118165797*G0_0_1_4_0_0 - 0.135449735449735*G0_0_1_5_0_0 - 0.0902998236331573*G0_0_1_5_0_1 + 0.0451499118165777*G0_0_1_6_1_0 + 0.0451499118165777*G0_0_1_6_1_1 + 0.0902998236331574*G0_0_1_7_1_0 - 0.0451499118165797*G0_0_1_8_1_1 - 0.0451499118165797*G0_0_1_9_1_0 + 0.0902998236331572*G0_0_1_9_1_1 + 0.0451499118165797*G0_0_1_10_1_0 - 0.135449735449735*G0_0_1_11_1_0 - 0.0902998236331573*G0_0_1_11_1_1 - 0.0451499118165777*G0_1_0_0_0_0 - 0.0451499118165777*G0_1_0_0_0_1 - 0.0902998236331574*G0_1_0_1_0_0 + 0.0451499118165797*G0_1_0_2_0_1 + 0.0451499118165797*G0_1_0_3_0_0 - 0.0902998236331573*G0_1_0_3_0_1 - 0.0451499118165797*G0_1_0_4_0_0 + 0.135449735449735*G0_1_0_5_0_0 + 0.0902998236331573*G0_1_0_5_0_1 - 0.0451499118165777*G0_1_0_6_1_0 - 0.0451499118165777*G0_1_0_6_1_1 - 0.0902998236331574*G0_1_0_7_1_0 + 0.0451499118165797*G0_1_0_8_1_1 + 0.0451499118165797*G0_1_0_9_1_0 - 0.0902998236331573*G0_1_0_9_1_1 - 0.0451499118165797*G0_1_0_10_1_0 + 0.135449735449735*G0_1_0_11_1_0 + 0.0902998236331573*G0_1_0_11_1_1; + A[249] = -A[624] - 0.225749559082892*G0_1_0_0_0_0 - 0.225749559082892*G0_1_0_0_0_1 - 0.225749559082893*G0_1_0_1_0_0 - 0.225749559082892*G0_1_0_3_0_1 + 0.225749559082892*G0_1_0_4_0_1 + 0.451499118165785*G0_1_0_5_0_0 + 0.225749559082893*G0_1_0_5_0_1 - 0.225749559082892*G0_1_0_6_1_0 - 0.225749559082892*G0_1_0_6_1_1 - 0.225749559082893*G0_1_0_7_1_0 - 0.225749559082892*G0_1_0_9_1_1 + 0.225749559082892*G0_1_0_10_1_1 + 0.451499118165785*G0_1_0_11_1_0 + 0.225749559082893*G0_1_0_11_1_1 + 0.609523809523808*G0_1_1_0_0_0 + 0.609523809523808*G0_1_1_0_0_1 - 0.112874779541447*G0_1_1_1_0_0 + 0.383774250440917*G0_1_1_2_0_1 + 0.0451499118165795*G0_1_1_3_0_0 - 0.451499118165784*G0_1_1_3_0_1 - 0.0451499118165795*G0_1_1_4_0_0 - 0.993298059964725*G0_1_1_4_0_1 - 0.496649029982362*G0_1_1_5_0_0 + 0.451499118165785*G0_1_1_5_0_1 + 0.609523809523808*G0_1_1_6_1_0 + 0.609523809523808*G0_1_1_6_1_1 - 0.112874779541447*G0_1_1_7_1_0 + 0.383774250440917*G0_1_1_8_1_1 + 0.0451499118165795*G0_1_1_9_1_0 - 0.451499118165784*G0_1_1_9_1_1 - 0.0451499118165795*G0_1_1_10_1_0 - 0.993298059964725*G0_1_1_10_1_1 - 0.496649029982362*G0_1_1_11_1_0 + 0.451499118165785*G0_1_1_11_1_1; + A[717] = A[252]; + A[375] = 0.0; + A[52] = 0.0; + A[767] = A[70] + 0.0204585537918868*G0_0_1_0_0_0 + 0.0204585537918868*G0_0_1_0_0_1 + 0.0204585537918871*G0_0_1_1_0_0 + 0.0204585537918867*G0_0_1_3_0_1 - 0.020458553791886*G0_0_1_4_0_1 - 0.0409171075837739*G0_0_1_5_0_0 - 0.0204585537918867*G0_0_1_5_0_1 + 0.0204585537918868*G0_0_1_6_1_0 + 0.0204585537918868*G0_0_1_6_1_1 + 0.0204585537918871*G0_0_1_7_1_0 + 0.0204585537918867*G0_0_1_9_1_1 - 0.020458553791886*G0_0_1_10_1_1 - 0.0409171075837739*G0_0_1_11_1_0 - 0.0204585537918867*G0_0_1_11_1_1 - 0.0204585537918868*G0_1_0_0_0_0 - 0.0204585537918867*G0_1_0_0_0_1 - 0.0204585537918871*G0_1_0_1_0_0 - 0.0204585537918868*G0_1_0_3_0_1 + 0.020458553791886*G0_1_0_4_0_1 + 0.0409171075837739*G0_1_0_5_0_0 + 0.0204585537918867*G0_1_0_5_0_1 - 0.0204585537918868*G0_1_0_6_1_0 - 0.0204585537918867*G0_1_0_6_1_1 - 0.0204585537918871*G0_1_0_7_1_0 - 0.0204585537918868*G0_1_0_9_1_1 + 0.020458553791886*G0_1_0_10_1_1 + 0.0409171075837739*G0_1_0_11_1_0 + 0.0204585537918867*G0_1_0_11_1_1; + A[452] = 0.0; + A[81] = 0.0; + A[802] = -A[562] + 0.265255731922398*G0_0_0_0_0_0 + 0.265255731922398*G0_0_0_0_0_1 + 0.434567901234569*G0_0_0_1_0_0 - 0.389417989417988*G0_0_0_2_0_1 - 0.609523809523805*G0_0_0_3_0_0 + 0.214462081128751*G0_0_0_3_0_1 + 0.609523809523805*G0_0_0_4_0_0 + 0.12416225749559*G0_0_0_4_0_1 - 0.699823633156967*G0_0_0_5_0_0 - 0.214462081128751*G0_0_0_5_0_1 + 0.265255731922398*G0_0_0_6_1_0 + 0.265255731922398*G0_0_0_6_1_1 + 0.434567901234569*G0_0_0_7_1_0 - 0.389417989417988*G0_0_0_8_1_1 - 0.609523809523805*G0_0_0_9_1_0 + 0.214462081128751*G0_0_0_9_1_1 + 0.609523809523805*G0_0_0_10_1_0 + 0.12416225749559*G0_0_0_10_1_1 - 0.699823633156967*G0_0_0_11_1_0 - 0.214462081128751*G0_0_0_11_1_1 - 0.124162257495588*G0_0_1_0_0_0 - 0.124162257495588*G0_0_1_0_0_1 - 0.12416225749559*G0_0_1_2_0_1 - 0.12416225749559*G0_0_1_3_0_0 + 0.12416225749559*G0_0_1_4_0_0 + 0.248324514991178*G0_0_1_4_0_1 + 0.124162257495586*G0_0_1_5_0_0 - 0.124162257495588*G0_0_1_6_1_0 - 0.124162257495588*G0_0_1_6_1_1 - 0.12416225749559*G0_0_1_8_1_1 - 0.12416225749559*G0_0_1_9_1_0 + 0.12416225749559*G0_0_1_10_1_0 + 0.248324514991178*G0_0_1_10_1_1 + 0.124162257495586*G0_0_1_11_1_0; + A[13] = A[855] - 0.0282186948853618*G0_0_1_1_0_0 + 0.0282186948853625*G0_0_1_2_0_1 + 0.0282186948853616*G0_0_1_3_0_0 - 0.0282186948853627*G0_0_1_3_0_1 - 0.0282186948853616*G0_0_1_4_0_0 - 0.0282186948853642*G0_0_1_4_0_1 + 0.0282186948853599*G0_0_1_5_0_0 + 0.0282186948853627*G0_0_1_5_0_1 - 0.0282186948853618*G0_0_1_7_1_0 + 0.0282186948853625*G0_0_1_8_1_1 + 0.0282186948853616*G0_0_1_9_1_0 - 0.0282186948853627*G0_0_1_9_1_1 - 0.0282186948853616*G0_0_1_10_1_0 - 0.0282186948853642*G0_0_1_10_1_1 + 0.0282186948853599*G0_0_1_11_1_0 + 0.0282186948853627*G0_0_1_11_1_1 + 0.0282186948853618*G0_1_0_1_0_0 - 0.0282186948853625*G0_1_0_2_0_1 - 0.0282186948853616*G0_1_0_3_0_0 + 0.0282186948853628*G0_1_0_3_0_1 + 0.0282186948853616*G0_1_0_4_0_0 + 0.0282186948853642*G0_1_0_4_0_1 - 0.0282186948853599*G0_1_0_5_0_0 - 0.0282186948853627*G0_1_0_5_0_1 + 0.0282186948853618*G0_1_0_7_1_0 - 0.0282186948853625*G0_1_0_8_1_1 - 0.0282186948853616*G0_1_0_9_1_0 + 0.0282186948853628*G0_1_0_9_1_1 + 0.0282186948853616*G0_1_0_10_1_0 + 0.0282186948853642*G0_1_0_10_1_1 - 0.0282186948853599*G0_1_0_11_1_0 - 0.0282186948853627*G0_1_0_11_1_1; + A[98] = -A[803] - 0.112874779541446*G0_0_0_0_0_0 - 0.112874779541446*G0_0_0_0_0_1 + 0.383774250440916*G0_0_0_1_0_0 - 0.835273368606699*G0_0_0_2_0_1 - 1.17389770723104*G0_0_0_3_0_0 + 0.0451499118165793*G0_0_0_3_0_1 + 1.17389770723104*G0_0_0_4_0_0 + 0.948148148148145*G0_0_0_4_0_1 - 0.27089947089947*G0_0_0_5_0_0 - 0.045149911816579*G0_0_0_5_0_1 - 0.112874779541446*G0_0_0_6_1_0 - 0.112874779541446*G0_0_0_6_1_1 + 0.383774250440916*G0_0_0_7_1_0 - 0.835273368606699*G0_0_0_8_1_1 - 1.17389770723104*G0_0_0_9_1_0 + 0.0451499118165793*G0_0_0_9_1_1 + 1.17389770723104*G0_0_0_10_1_0 + 0.948148148148145*G0_0_0_10_1_1 - 0.27089947089947*G0_0_0_11_1_0 - 0.045149911816579*G0_0_0_11_1_1 - 0.225749559082894*G0_0_1_0_0_0 - 0.225749559082894*G0_0_1_0_0_1 - 0.225749559082892*G0_0_1_2_0_1 - 0.225749559082893*G0_0_1_3_0_0 + 0.225749559082893*G0_0_1_4_0_0 + 0.451499118165786*G0_0_1_4_0_1 + 0.225749559082895*G0_0_1_5_0_0 - 0.225749559082894*G0_0_1_6_1_0 - 0.225749559082894*G0_0_1_6_1_1 - 0.225749559082892*G0_0_1_8_1_1 - 0.225749559082893*G0_0_1_9_1_0 + 0.225749559082893*G0_0_1_10_1_0 + 0.451499118165786*G0_0_1_10_1_1 + 0.225749559082895*G0_0_1_11_1_0; + A[621] = A[98] - 0.180599647266315*G0_0_0_0_0_0 - 0.180599647266315*G0_0_0_0_0_1 - 0.180599647266315*G0_0_0_1_0_0 - 0.180599647266314*G0_0_0_3_0_1 + 0.180599647266315*G0_0_0_4_0_1 + 0.361199294532629*G0_0_0_5_0_0 + 0.180599647266314*G0_0_0_5_0_1 - 0.180599647266315*G0_0_0_6_1_0 - 0.180599647266315*G0_0_0_6_1_1 - 0.180599647266315*G0_0_0_7_1_0 - 0.180599647266314*G0_0_0_9_1_1 + 0.180599647266315*G0_0_0_10_1_1 + 0.361199294532629*G0_0_0_11_1_0 + 0.180599647266314*G0_0_0_11_1_1 - 0.225749559082893*G0_0_1_0_0_0 - 0.225749559082893*G0_0_1_0_0_1 + 0.135449735449735*G0_0_1_1_0_0 - 0.496649029982364*G0_0_1_2_0_1 - 0.6320987654321*G0_0_1_3_0_0 + 0.6320987654321*G0_0_1_4_0_0 + 0.722398589065257*G0_0_1_4_0_1 + 0.0902998236331577*G0_0_1_5_0_0 - 0.225749559082893*G0_0_1_6_1_0 - 0.225749559082893*G0_0_1_6_1_1 + 0.135449735449735*G0_0_1_7_1_0 - 0.496649029982364*G0_0_1_8_1_1 - 0.6320987654321*G0_0_1_9_1_0 + 0.6320987654321*G0_0_1_10_1_0 + 0.722398589065257*G0_0_1_10_1_1 + 0.0902998236331577*G0_0_1_11_1_0 - 0.31604938271605*G0_1_0_0_0_0 - 0.31604938271605*G0_1_0_0_0_1 + 0.0451499118165782*G0_1_0_1_0_0 - 0.496649029982364*G0_1_0_2_0_1 - 0.6320987654321*G0_1_0_3_0_0 - 0.0902998236331578*G0_1_0_3_0_1 + 0.6320987654321*G0_1_0_4_0_0 + 0.812698412698414*G0_1_0_4_0_1 + 0.270899470899471*G0_1_0_5_0_0 + 0.0902998236331579*G0_1_0_5_0_1 - 0.31604938271605*G0_1_0_6_1_0 - 0.31604938271605*G0_1_0_6_1_1 + 0.0451499118165782*G0_1_0_7_1_0 - 0.496649029982364*G0_1_0_8_1_1 - 0.6320987654321*G0_1_0_9_1_0 - 0.0902998236331578*G0_1_0_9_1_1 + 0.6320987654321*G0_1_0_10_1_0 + 0.812698412698414*G0_1_0_10_1_1 + 0.270899470899471*G0_1_0_11_1_0 + 0.0902998236331579*G0_1_0_11_1_1 - 0.406349206349207*G0_1_1_0_0_0 - 0.406349206349207*G0_1_1_0_0_1 - 0.0451499118165806*G0_1_1_1_0_0 - 0.496649029982363*G0_1_1_2_0_1 - 0.6320987654321*G0_1_1_3_0_0 - 0.180599647266317*G0_1_1_3_0_1 + 0.6320987654321*G0_1_1_4_0_0 + 0.90299823633157*G0_1_1_4_0_1 + 0.451499118165787*G0_1_1_5_0_0 + 0.180599647266318*G0_1_1_5_0_1 - 0.406349206349207*G0_1_1_6_1_0 - 0.406349206349207*G0_1_1_6_1_1 - 0.0451499118165806*G0_1_1_7_1_0 - 0.496649029982363*G0_1_1_8_1_1 - 0.6320987654321*G0_1_1_9_1_0 - 0.180599647266317*G0_1_1_9_1_1 + 0.6320987654321*G0_1_1_10_1_0 + 0.90299823633157*G0_1_1_10_1_1 + 0.451499118165787*G0_1_1_11_1_0 + 0.180599647266318*G0_1_1_11_1_1; + A[156] = A[621]; + A[560] = -A[98] - 0.496649029982363*G0_0_1_0_0_0 - 0.496649029982363*G0_0_1_0_0_1 - 0.406349206349206*G0_0_1_1_0_0 - 0.632098765432099*G0_0_1_2_0_1 - 1.17389770723104*G0_0_1_3_0_0 - 0.948148148148148*G0_0_1_3_0_1 + 1.17389770723104*G0_0_1_4_0_0 + 1.12874779541446*G0_0_1_4_0_1 + 0.902998236331569*G0_0_1_5_0_0 + 0.948148148148148*G0_0_1_5_0_1 - 0.496649029982363*G0_0_1_6_1_0 - 0.496649029982363*G0_0_1_6_1_1 - 0.406349206349206*G0_0_1_7_1_0 - 0.632098765432099*G0_0_1_8_1_1 - 1.17389770723104*G0_0_1_9_1_0 - 0.948148148148148*G0_0_1_9_1_1 + 1.17389770723104*G0_0_1_10_1_0 + 1.12874779541446*G0_0_1_10_1_1 + 0.902998236331569*G0_0_1_11_1_0 + 0.948148148148148*G0_0_1_11_1_1 + 0.112874779541448*G0_1_1_0_0_0 + 0.112874779541448*G0_1_1_0_0_1 + 0.835273368606707*G0_1_1_1_0_0 - 0.383774250440918*G0_1_1_2_0_1 - 0.0451499118165783*G0_1_1_3_0_0 + 1.17389770723105*G0_1_1_3_0_1 + 0.0451499118165783*G0_1_1_4_0_0 + 0.270899470899471*G0_1_1_4_0_1 - 0.948148148148154*G0_1_1_5_0_0 - 1.17389770723105*G0_1_1_5_0_1 + 0.112874779541448*G0_1_1_6_1_0 + 0.112874779541448*G0_1_1_6_1_1 + 0.835273368606707*G0_1_1_7_1_0 - 0.383774250440918*G0_1_1_8_1_1 - 0.0451499118165783*G0_1_1_9_1_0 + 1.17389770723105*G0_1_1_9_1_1 + 0.0451499118165783*G0_1_1_10_1_0 + 0.270899470899471*G0_1_1_10_1_1 - 0.948148148148154*G0_1_1_11_1_0 - 1.17389770723105*G0_1_1_11_1_1; + A[650] = A[621] + 0.0451499118165799*G0_0_1_0_0_0 + 0.0451499118165798*G0_0_1_0_0_1 - 0.135449735449735*G0_0_1_1_0_0 + 0.180599647266315*G0_0_1_2_0_1 + 0.180599647266316*G0_0_1_3_0_0 - 0.135449735449734*G0_0_1_3_0_1 - 0.180599647266316*G0_0_1_4_0_0 - 0.225749559082895*G0_0_1_4_0_1 + 0.0902998236331551*G0_0_1_5_0_0 + 0.135449735449734*G0_0_1_5_0_1 + 0.0451499118165799*G0_0_1_6_1_0 + 0.0451499118165798*G0_0_1_6_1_1 - 0.135449735449735*G0_0_1_7_1_0 + 0.180599647266315*G0_0_1_8_1_1 + 0.180599647266316*G0_0_1_9_1_0 - 0.135449735449734*G0_0_1_9_1_1 - 0.180599647266316*G0_0_1_10_1_0 - 0.225749559082895*G0_0_1_10_1_1 + 0.0902998236331551*G0_0_1_11_1_0 + 0.135449735449734*G0_0_1_11_1_1 - 0.0451499118165798*G0_1_0_0_0_0 - 0.0451499118165798*G0_1_0_0_0_1 + 0.135449735449735*G0_1_0_1_0_0 - 0.180599647266315*G0_1_0_2_0_1 - 0.180599647266316*G0_1_0_3_0_0 + 0.135449735449734*G0_1_0_3_0_1 + 0.180599647266316*G0_1_0_4_0_0 + 0.225749559082895*G0_1_0_4_0_1 - 0.0902998236331551*G0_1_0_5_0_0 - 0.135449735449734*G0_1_0_5_0_1 - 0.0451499118165798*G0_1_0_6_1_0 - 0.0451499118165798*G0_1_0_6_1_1 + 0.135449735449735*G0_1_0_7_1_0 - 0.180599647266315*G0_1_0_8_1_1 - 0.180599647266316*G0_1_0_9_1_0 + 0.135449735449734*G0_1_0_9_1_1 + 0.180599647266316*G0_1_0_10_1_0 + 0.225749559082895*G0_1_0_10_1_1 - 0.0902998236331551*G0_1_0_11_1_0 - 0.135449735449734*G0_1_0_11_1_1; + A[185] = A[650]; + A[817] = 0.0; + A[38] = A[36] + 0.14673721340388*G0_0_0_0_0_0 + 0.146737213403879*G0_0_0_0_0_1 + 0.14673721340388*G0_0_0_2_0_1 + 0.14673721340388*G0_0_0_3_0_0 - 0.14673721340388*G0_0_0_4_0_0 - 0.293474426807759*G0_0_0_4_0_1 - 0.146737213403879*G0_0_0_5_0_0 + 0.14673721340388*G0_0_0_6_1_0 + 0.146737213403879*G0_0_0_6_1_1 + 0.14673721340388*G0_0_0_8_1_1 + 0.14673721340388*G0_0_0_9_1_0 - 0.14673721340388*G0_0_0_10_1_0 - 0.293474426807759*G0_0_0_10_1_1 - 0.146737213403879*G0_0_0_11_1_0; + A[500] = -A[38] + 0.163668430335098*G0_0_1_0_0_0 + 0.163668430335098*G0_0_1_0_0_1 + 0.411992945326281*G0_0_1_1_0_0 - 0.0451499118165794*G0_0_1_2_0_1 + 0.158024691358024*G0_0_1_3_0_0 + 0.615167548500885*G0_0_1_3_0_1 - 0.158024691358024*G0_0_1_4_0_0 - 0.118518518518518*G0_0_1_4_0_1 - 0.575661375661379*G0_0_1_5_0_0 - 0.615167548500885*G0_0_1_5_0_1 + 0.163668430335098*G0_0_1_6_1_0 + 0.163668430335098*G0_0_1_6_1_1 + 0.411992945326281*G0_0_1_7_1_0 - 0.0451499118165794*G0_0_1_8_1_1 + 0.158024691358024*G0_0_1_9_1_0 + 0.615167548500885*G0_0_1_9_1_1 - 0.158024691358024*G0_0_1_10_1_0 - 0.118518518518518*G0_0_1_10_1_1 - 0.575661375661379*G0_0_1_11_1_0 - 0.615167548500885*G0_0_1_11_1_1; + A[504] = -A[500] + 0.0790123456790123*G0_0_0_0_0_0 + 0.0790123456790123*G0_0_0_0_0_1 - 0.186243386243387*G0_0_0_1_0_0 - 0.0225749559082889*G0_0_0_2_0_1 - 0.310405643738976*G0_0_0_3_0_0 - 0.474074074074074*G0_0_0_3_0_1 + 0.310405643738976*G0_0_0_4_0_0 - 0.0564373897707235*G0_0_0_4_0_1 + 0.107231040564374*G0_0_0_5_0_0 + 0.474074074074075*G0_0_0_5_0_1 + 0.0790123456790123*G0_0_0_6_1_0 + 0.0790123456790123*G0_0_0_6_1_1 - 0.186243386243387*G0_0_0_7_1_0 - 0.0225749559082889*G0_0_0_8_1_1 - 0.310405643738976*G0_0_0_9_1_0 - 0.474074074074074*G0_0_0_9_1_1 + 0.310405643738976*G0_0_0_10_1_0 - 0.0564373897707235*G0_0_0_10_1_1 + 0.107231040564374*G0_0_0_11_1_0 + 0.474074074074075*G0_0_0_11_1_1 + 0.0564373897707236*G0_0_1_0_0_0 + 0.0564373897707237*G0_0_1_0_0_1 + 0.0564373897707222*G0_0_1_2_0_1 + 0.0564373897707227*G0_0_1_3_0_0 - 0.0564373897707227*G0_0_1_4_0_0 - 0.112874779541446*G0_0_1_4_0_1 - 0.0564373897707255*G0_0_1_5_0_0 + 0.0564373897707236*G0_0_1_6_1_0 + 0.0564373897707237*G0_0_1_6_1_1 + 0.0564373897707222*G0_0_1_8_1_1 + 0.0564373897707227*G0_0_1_9_1_0 - 0.0564373897707227*G0_0_1_10_1_0 - 0.112874779541446*G0_0_1_10_1_1 - 0.0564373897707255*G0_0_1_11_1_0; + A[123] = A[588]; + A[840] = 0.0; + A[75] = 0.0; + A[152] = A[617]; + A[875] = 0.0; + A[486] = 0.0; + A[589] = A[124]; + A[517] = 0.0; + A[544] = 0.0; + A[508] = A[43]; + A[639] = 0.0; + A[535] = A[70]; + A[666] = 0.0; + A[697] = 0.0; + A[308] = -A[305] - 0.12416225749559*G0_0_1_0_0_0 - 0.12416225749559*G0_0_1_0_0_1 - 0.124162257495589*G0_0_1_1_0_0 - 0.124162257495588*G0_0_1_3_0_1 + 0.124162257495589*G0_0_1_4_0_1 + 0.248324514991179*G0_0_1_5_0_0 + 0.124162257495588*G0_0_1_5_0_1 - 0.12416225749559*G0_0_1_6_1_0 - 0.12416225749559*G0_0_1_6_1_1 - 0.124162257495589*G0_0_1_7_1_0 - 0.124162257495588*G0_0_1_9_1_1 + 0.124162257495589*G0_0_1_10_1_1 + 0.248324514991179*G0_0_1_11_1_0 + 0.124162257495588*G0_0_1_11_1_1 + 0.2652557319224*G0_1_1_0_0_0 + 0.2652557319224*G0_1_1_0_0_1 - 0.389417989417987*G0_1_1_1_0_0 + 0.434567901234568*G0_1_1_2_0_1 + 0.21446208112875*G0_1_1_3_0_0 - 0.609523809523806*G0_1_1_3_0_1 - 0.21446208112875*G0_1_1_4_0_0 - 0.699823633156968*G0_1_1_4_0_1 + 0.124162257495587*G0_1_1_5_0_0 + 0.609523809523806*G0_1_1_5_0_1 + 0.2652557319224*G0_1_1_6_1_0 + 0.2652557319224*G0_1_1_6_1_1 - 0.389417989417987*G0_1_1_7_1_0 + 0.434567901234568*G0_1_1_8_1_1 + 0.21446208112875*G0_1_1_9_1_0 - 0.609523809523806*G0_1_1_9_1_1 - 0.21446208112875*G0_1_1_10_1_0 - 0.699823633156968*G0_1_1_10_1_1 + 0.124162257495587*G0_1_1_11_1_0 + 0.609523809523806*G0_1_1_11_1_1; + A[264] = 0.0; + A[335] = -A[803] - 0.225749559082894*G0_0_1_0_0_0 - 0.225749559082894*G0_0_1_0_0_1 - 0.225749559082896*G0_0_1_1_0_0 - 0.225749559082898*G0_0_1_3_0_1 + 0.225749559082894*G0_0_1_4_0_1 + 0.45149911816579*G0_0_1_5_0_0 + 0.225749559082898*G0_0_1_5_0_1 - 0.225749559082894*G0_0_1_6_1_0 - 0.225749559082894*G0_0_1_6_1_1 - 0.225749559082896*G0_0_1_7_1_0 - 0.225749559082898*G0_0_1_9_1_1 + 0.225749559082894*G0_0_1_10_1_1 + 0.45149911816579*G0_0_1_11_1_0 + 0.225749559082898*G0_0_1_11_1_1 - 0.112874779541447*G0_1_1_0_0_0 - 0.112874779541447*G0_1_1_0_0_1 - 0.835273368606707*G0_1_1_1_0_0 + 0.383774250440919*G0_1_1_2_0_1 + 0.045149911816579*G0_1_1_3_0_0 - 1.17389770723105*G0_1_1_3_0_1 - 0.045149911816579*G0_1_1_4_0_0 - 0.270899470899472*G0_1_1_4_0_1 + 0.948148148148154*G0_1_1_5_0_0 + 1.17389770723105*G0_1_1_5_0_1 - 0.112874779541447*G0_1_1_6_1_0 - 0.112874779541447*G0_1_1_6_1_1 - 0.835273368606707*G0_1_1_7_1_0 + 0.383774250440919*G0_1_1_8_1_1 + 0.045149911816579*G0_1_1_9_1_0 - 1.17389770723105*G0_1_1_9_1_1 - 0.045149911816579*G0_1_1_10_1_0 - 0.270899470899472*G0_1_1_10_1_1 + 0.948148148148154*G0_1_1_11_1_0 + 1.17389770723105*G0_1_1_11_1_1; + A[273] = A[335] - 0.406349206349206*G0_0_0_0_0_0 - 0.406349206349206*G0_0_0_0_0_1 - 0.496649029982362*G0_0_0_1_0_0 - 0.045149911816578*G0_0_0_2_0_1 - 0.180599647266312*G0_0_0_3_0_0 - 0.632098765432096*G0_0_0_3_0_1 + 0.180599647266312*G0_0_0_4_0_0 + 0.451499118165783*G0_0_0_4_0_1 + 0.902998236331567*G0_0_0_5_0_0 + 0.632098765432096*G0_0_0_5_0_1 - 0.406349206349206*G0_0_0_6_1_0 - 0.406349206349206*G0_0_0_6_1_1 - 0.496649029982362*G0_0_0_7_1_0 - 0.045149911816578*G0_0_0_8_1_1 - 0.180599647266312*G0_0_0_9_1_0 - 0.632098765432096*G0_0_0_9_1_1 + 0.180599647266312*G0_0_0_10_1_0 + 0.451499118165783*G0_0_0_10_1_1 + 0.902998236331567*G0_0_0_11_1_0 + 0.632098765432096*G0_0_0_11_1_1 - 0.225749559082893*G0_0_1_0_0_0 - 0.225749559082893*G0_0_1_0_0_1 - 0.496649029982361*G0_0_1_1_0_0 + 0.135449735449734*G0_0_1_2_0_1 - 0.632098765432094*G0_0_1_3_0_1 + 0.0902998236331579*G0_0_1_4_0_1 + 0.722398589065253*G0_0_1_5_0_0 + 0.632098765432094*G0_0_1_5_0_1 - 0.225749559082893*G0_0_1_6_1_0 - 0.225749559082893*G0_0_1_6_1_1 - 0.496649029982361*G0_0_1_7_1_0 + 0.135449735449734*G0_0_1_8_1_1 - 0.632098765432094*G0_0_1_9_1_1 + 0.0902998236331579*G0_0_1_10_1_1 + 0.722398589065253*G0_0_1_11_1_0 + 0.632098765432094*G0_0_1_11_1_1 - 0.316049382716049*G0_1_0_0_0_0 - 0.316049382716049*G0_1_0_0_0_1 - 0.496649029982363*G0_1_0_1_0_0 + 0.0451499118165784*G0_1_0_2_0_1 - 0.0902998236331569*G0_1_0_3_0_0 - 0.632098765432098*G0_1_0_3_0_1 + 0.0902998236331569*G0_1_0_4_0_0 + 0.270899470899471*G0_1_0_4_0_1 + 0.812698412698412*G0_1_0_5_0_0 + 0.632098765432098*G0_1_0_5_0_1 - 0.316049382716049*G0_1_0_6_1_0 - 0.316049382716049*G0_1_0_6_1_1 - 0.496649029982363*G0_1_0_7_1_0 + 0.0451499118165784*G0_1_0_8_1_1 - 0.0902998236331569*G0_1_0_9_1_0 - 0.632098765432098*G0_1_0_9_1_1 + 0.0902998236331569*G0_1_0_10_1_0 + 0.270899470899471*G0_1_0_10_1_1 + 0.812698412698412*G0_1_0_11_1_0 + 0.632098765432098*G0_1_0_11_1_1 - 0.180599647266312*G0_1_1_0_0_0 - 0.180599647266312*G0_1_1_0_0_1 - 0.180599647266315*G0_1_1_2_0_1 - 0.180599647266314*G0_1_1_3_0_0 + 0.180599647266314*G0_1_1_4_0_0 + 0.361199294532627*G0_1_1_4_0_1 + 0.180599647266308*G0_1_1_5_0_0 - 0.180599647266312*G0_1_1_6_1_0 - 0.180599647266312*G0_1_1_6_1_1 - 0.180599647266315*G0_1_1_8_1_1 - 0.180599647266314*G0_1_1_9_1_0 + 0.180599647266314*G0_1_1_10_1_0 + 0.361199294532627*G0_1_1_10_1_1 + 0.180599647266308*G0_1_1_11_1_0; + A[738] = A[273]; + A[291] = 0.0; + A[438] = 0.0; + A[318] = 0.0; + A[776] = A[805] - 0.237037037037038*G0_0_1_0_0_0 - 0.237037037037038*G0_0_1_0_0_1 + 1.70440917107584*G0_0_1_1_0_0 - 0.823985890652557*G0_0_1_2_0_1 + 0.293474426807758*G0_0_1_3_0_0 + 2.82186948853615*G0_0_1_3_0_1 - 0.293474426807758*G0_0_1_4_0_0 + 1.0610229276896*G0_0_1_4_0_1 - 1.4673721340388*G0_0_1_5_0_0 - 2.82186948853615*G0_0_1_5_0_1 - 0.237037037037038*G0_0_1_6_1_0 - 0.237037037037038*G0_0_1_6_1_1 + 1.70440917107584*G0_0_1_7_1_0 - 0.823985890652557*G0_0_1_8_1_1 + 0.293474426807758*G0_0_1_9_1_0 + 2.82186948853615*G0_0_1_9_1_1 - 0.293474426807758*G0_0_1_10_1_0 + 1.0610229276896*G0_0_1_10_1_1 - 1.4673721340388*G0_0_1_11_1_0 - 2.82186948853615*G0_0_1_11_1_1 + 0.237037037037038*G0_1_0_0_0_0 + 0.237037037037038*G0_1_0_0_0_1 - 1.70440917107584*G0_1_0_1_0_0 + 0.823985890652557*G0_1_0_2_0_1 - 0.293474426807758*G0_1_0_3_0_0 - 2.82186948853615*G0_1_0_3_0_1 + 0.293474426807758*G0_1_0_4_0_0 - 1.0610229276896*G0_1_0_4_0_1 + 1.4673721340388*G0_1_0_5_0_0 + 2.82186948853615*G0_1_0_5_0_1 + 0.237037037037038*G0_1_0_6_1_0 + 0.237037037037038*G0_1_0_6_1_1 - 1.70440917107584*G0_1_0_7_1_0 + 0.823985890652557*G0_1_0_8_1_1 - 0.293474426807758*G0_1_0_9_1_0 - 2.82186948853615*G0_1_0_9_1_1 + 0.293474426807758*G0_1_0_10_1_0 - 1.0610229276896*G0_1_0_10_1_1 + 1.4673721340388*G0_1_0_11_1_0 + 2.82186948853615*G0_1_0_11_1_1; + A[247] = A[776] - 1.59153439153439*G0_0_0_0_0_0 - 1.59153439153439*G0_0_0_0_0_1 + 2.67513227513227*G0_0_0_1_0_0 - 3.08148148148148*G0_0_0_2_0_1 - 1.8962962962963*G0_0_0_3_0_0 + 3.86031746031746*G0_0_0_3_0_1 + 1.8962962962963*G0_0_0_4_0_0 + 4.67301587301587*G0_0_0_4_0_1 - 1.08359788359788*G0_0_0_5_0_0 - 3.86031746031746*G0_0_0_5_0_1 - 1.59153439153439*G0_0_0_6_1_0 - 1.59153439153439*G0_0_0_6_1_1 + 2.67513227513227*G0_0_0_7_1_0 - 3.08148148148148*G0_0_0_8_1_1 - 1.8962962962963*G0_0_0_9_1_0 + 3.86031746031746*G0_0_0_9_1_1 + 1.8962962962963*G0_0_0_10_1_0 + 4.67301587301587*G0_0_0_10_1_1 - 1.08359788359788*G0_0_0_11_1_0 - 3.86031746031746*G0_0_0_11_1_1 + 1.68183421516755*G0_0_1_1_0_0 - 1.68183421516755*G0_0_1_2_0_1 - 1.68183421516755*G0_0_1_3_0_0 + 1.68183421516755*G0_0_1_3_0_1 + 1.68183421516755*G0_0_1_4_0_0 + 1.68183421516755*G0_0_1_4_0_1 - 1.68183421516755*G0_0_1_5_0_0 - 1.68183421516755*G0_0_1_5_0_1 + 1.68183421516755*G0_0_1_7_1_0 - 1.68183421516755*G0_0_1_8_1_1 - 1.68183421516755*G0_0_1_9_1_0 + 1.68183421516755*G0_0_1_9_1_1 + 1.68183421516755*G0_0_1_10_1_0 + 1.68183421516755*G0_0_1_10_1_1 - 1.68183421516755*G0_0_1_11_1_0 - 1.68183421516755*G0_0_1_11_1_1 + 4.21022927689594*G0_1_0_1_0_0 - 4.21022927689594*G0_1_0_2_0_1 - 4.21022927689595*G0_1_0_3_0_0 + 4.21022927689594*G0_1_0_3_0_1 + 4.21022927689595*G0_1_0_4_0_0 + 4.21022927689595*G0_1_0_4_0_1 - 4.21022927689594*G0_1_0_5_0_0 - 4.21022927689594*G0_1_0_5_0_1 + 4.21022927689594*G0_1_0_7_1_0 - 4.21022927689594*G0_1_0_8_1_1 - 4.21022927689595*G0_1_0_9_1_0 + 4.21022927689594*G0_1_0_9_1_1 + 4.21022927689595*G0_1_0_10_1_0 + 4.21022927689595*G0_1_0_10_1_1 - 4.21022927689594*G0_1_0_11_1_0 - 4.21022927689594*G0_1_0_11_1_1 + 1.59153439153439*G0_1_1_0_0_0 + 1.59153439153439*G0_1_1_0_0_1 + 3.08148148148148*G0_1_1_1_0_0 - 2.67513227513228*G0_1_1_2_0_1 - 3.86031746031746*G0_1_1_3_0_0 + 1.89629629629629*G0_1_1_3_0_1 + 3.86031746031746*G0_1_1_4_0_0 + 1.08359788359789*G0_1_1_4_0_1 - 4.67301587301586*G0_1_1_5_0_0 - 1.89629629629629*G0_1_1_5_0_1 + 1.59153439153439*G0_1_1_6_1_0 + 1.59153439153439*G0_1_1_6_1_1 + 3.08148148148148*G0_1_1_7_1_0 - 2.67513227513228*G0_1_1_8_1_1 - 3.86031746031746*G0_1_1_9_1_0 + 1.89629629629629*G0_1_1_9_1_1 + 3.86031746031746*G0_1_1_10_1_0 + 1.08359788359789*G0_1_1_10_1_1 - 4.67301587301586*G0_1_1_11_1_0 - 1.89629629629629*G0_1_1_11_1_1; + A[683] = A[247] + 0.237037037037036*G0_0_1_0_0_0 + 0.237037037037036*G0_0_1_0_0_1 + 0.823985890652558*G0_0_1_1_0_0 - 1.70440917107584*G0_0_1_2_0_1 - 2.82186948853616*G0_0_1_3_0_0 - 0.29347442680776*G0_0_1_3_0_1 + 2.82186948853616*G0_0_1_4_0_0 + 1.4673721340388*G0_0_1_4_0_1 - 1.06102292768959*G0_0_1_5_0_0 + 0.29347442680776*G0_0_1_5_0_1 + 0.237037037037036*G0_0_1_6_1_0 + 0.237037037037036*G0_0_1_6_1_1 + 0.823985890652558*G0_0_1_7_1_0 - 1.70440917107584*G0_0_1_8_1_1 - 2.82186948853616*G0_0_1_9_1_0 - 0.29347442680776*G0_0_1_9_1_1 + 2.82186948853616*G0_0_1_10_1_0 + 1.4673721340388*G0_0_1_10_1_1 - 1.06102292768959*G0_0_1_11_1_0 + 0.29347442680776*G0_0_1_11_1_1 - 0.237037037037036*G0_1_0_0_0_0 - 0.237037037037036*G0_1_0_0_0_1 - 0.823985890652558*G0_1_0_1_0_0 + 1.70440917107584*G0_1_0_2_0_1 + 2.82186948853616*G0_1_0_3_0_0 + 0.29347442680776*G0_1_0_3_0_1 - 2.82186948853616*G0_1_0_4_0_0 - 1.4673721340388*G0_1_0_4_0_1 + 1.06102292768959*G0_1_0_5_0_0 - 0.29347442680776*G0_1_0_5_0_1 - 0.237037037037036*G0_1_0_6_1_0 - 0.237037037037036*G0_1_0_6_1_1 - 0.823985890652558*G0_1_0_7_1_0 + 1.70440917107584*G0_1_0_8_1_1 + 2.82186948853616*G0_1_0_9_1_0 + 0.29347442680776*G0_1_0_9_1_1 - 2.82186948853616*G0_1_0_10_1_0 - 1.4673721340388*G0_1_0_10_1_1 + 1.06102292768959*G0_1_0_11_1_0 - 0.29347442680776*G0_1_0_11_1_1; + A[712] = A[247]; + A[303] = -A[776] + 1.48430335097002*G0_0_0_0_0_0 + 1.48430335097002*G0_0_0_0_0_1 - 1.46172839506173*G0_0_0_1_0_0 + 1.1005291005291*G0_0_0_2_0_1 - 0.744973544973542*G0_0_0_3_0_0 - 3.30723104056438*G0_0_0_3_0_1 + 0.744973544973542*G0_0_0_4_0_0 - 2.58483245149912*G0_0_0_4_0_1 - 0.022574955908284*G0_0_0_5_0_0 + 3.30723104056438*G0_0_0_5_0_1 + 1.48430335097002*G0_0_0_6_1_0 + 1.48430335097002*G0_0_0_6_1_1 - 1.46172839506173*G0_0_0_7_1_0 + 1.1005291005291*G0_0_0_8_1_1 - 0.744973544973542*G0_0_0_9_1_0 - 3.30723104056438*G0_0_0_9_1_1 + 0.744973544973542*G0_0_0_10_1_0 - 2.58483245149912*G0_0_0_10_1_1 - 0.022574955908284*G0_0_0_11_1_0 + 3.30723104056438*G0_0_0_11_1_1 + 0.112874779541445*G0_1_0_0_0_0 + 0.112874779541445*G0_1_0_0_0_1 - 2.06560846560847*G0_1_0_1_0_0 + 1.06102292768959*G0_1_0_2_0_1 - 0.0564373897707211*G0_1_0_3_0_0 - 3.18306878306878*G0_1_0_3_0_1 + 0.0564373897707211*G0_1_0_4_0_0 - 1.17389770723104*G0_1_0_4_0_1 + 1.95273368606702*G0_1_0_5_0_0 + 3.18306878306879*G0_1_0_5_0_1 + 0.112874779541445*G0_1_0_6_1_0 + 0.112874779541445*G0_1_0_6_1_1 - 2.06560846560847*G0_1_0_7_1_0 + 1.06102292768959*G0_1_0_8_1_1 - 0.0564373897707211*G0_1_0_9_1_0 - 3.18306878306878*G0_1_0_9_1_1 + 0.0564373897707211*G0_1_0_10_1_0 - 1.17389770723104*G0_1_0_10_1_1 + 1.95273368606702*G0_1_0_11_1_0 + 3.18306878306879*G0_1_0_11_1_1; + A[461] = 0.0; + A[357] = 0.0; + A[4] = A[469]; + A[721] = 0.0; + A[388] = 0.0; + A[31] = 0.221340388007054*G0_0_0_0_0_0 + 0.221340388007055*G0_0_0_0_0_1 + 0.815696649029982*G0_0_0_1_0_0 - 0.221340388007055*G0_0_0_2_0_1 + 0.151675485008817*G0_0_0_3_0_0 + 1.18871252204585*G0_0_0_3_0_1 - 0.151675485008817*G0_0_0_4_0_0 - 1.03703703703704*G0_0_0_5_0_0 - 1.18871252204585*G0_0_0_5_0_1 + 0.221340388007054*G0_0_0_6_1_0 + 0.221340388007055*G0_0_0_6_1_1 + 0.815696649029982*G0_0_0_7_1_0 - 0.221340388007055*G0_0_0_8_1_1 + 0.151675485008817*G0_0_0_9_1_0 + 1.18871252204585*G0_0_0_9_1_1 - 0.151675485008817*G0_0_0_10_1_0 - 1.03703703703704*G0_0_0_11_1_0 - 1.18871252204585*G0_0_0_11_1_1; + A[130] = A[769] - 0.0423280423280404*G0_0_1_0_0_0 - 0.0423280423280405*G0_0_1_0_0_1 - 0.084656084656081*G0_0_1_1_0_0 + 0.042328042328041*G0_0_1_2_0_1 + 0.0423280423280413*G0_0_1_3_0_0 - 0.0846560846560808*G0_0_1_3_0_1 - 0.0423280423280413*G0_0_1_4_0_0 + 0.126984126984121*G0_0_1_5_0_0 + 0.0846560846560807*G0_0_1_5_0_1 - 0.0423280423280404*G0_0_1_6_1_0 - 0.0423280423280405*G0_0_1_6_1_1 - 0.084656084656081*G0_0_1_7_1_0 + 0.042328042328041*G0_0_1_8_1_1 + 0.0423280423280413*G0_0_1_9_1_0 - 0.0846560846560808*G0_0_1_9_1_1 - 0.0423280423280413*G0_0_1_10_1_0 + 0.126984126984121*G0_0_1_11_1_0 + 0.0846560846560807*G0_0_1_11_1_1 + 0.0423280423280403*G0_1_0_0_0_0 + 0.0423280423280404*G0_1_0_0_0_1 + 0.0846560846560808*G0_1_0_1_0_0 - 0.042328042328041*G0_1_0_2_0_1 - 0.0423280423280414*G0_1_0_3_0_0 + 0.0846560846560806*G0_1_0_3_0_1 + 0.0423280423280414*G0_1_0_4_0_0 - 0.126984126984121*G0_1_0_5_0_0 - 0.0846560846560805*G0_1_0_5_0_1 + 0.0423280423280403*G0_1_0_6_1_0 + 0.0423280423280404*G0_1_0_6_1_1 + 0.0846560846560808*G0_1_0_7_1_0 - 0.042328042328041*G0_1_0_8_1_1 - 0.0423280423280414*G0_1_0_9_1_0 + 0.0846560846560806*G0_1_0_9_1_1 + 0.0423280423280414*G0_1_0_10_1_0 - 0.126984126984121*G0_1_0_11_1_0 - 0.0846560846560805*G0_1_0_11_1_1; + A[161] = -A[716] - 0.225749559082894*G0_1_0_0_0_0 - 0.225749559082894*G0_1_0_0_0_1 - 0.225749559082896*G0_1_0_1_0_0 - 0.225749559082897*G0_1_0_3_0_1 + 0.225749559082894*G0_1_0_4_0_1 + 0.45149911816579*G0_1_0_5_0_0 + 0.225749559082898*G0_1_0_5_0_1 - 0.225749559082894*G0_1_0_6_1_0 - 0.225749559082894*G0_1_0_6_1_1 - 0.225749559082896*G0_1_0_7_1_0 - 0.225749559082897*G0_1_0_9_1_1 + 0.225749559082894*G0_1_0_10_1_1 + 0.45149911816579*G0_1_0_11_1_0 + 0.225749559082898*G0_1_0_11_1_1 - 0.112874779541447*G0_1_1_0_0_0 - 0.112874779541447*G0_1_1_0_0_1 - 0.835273368606707*G0_1_1_1_0_0 + 0.383774250440919*G0_1_1_2_0_1 + 0.045149911816579*G0_1_1_3_0_0 - 1.17389770723105*G0_1_1_3_0_1 - 0.045149911816579*G0_1_1_4_0_0 - 0.270899470899472*G0_1_1_4_0_1 + 0.948148148148154*G0_1_1_5_0_0 + 1.17389770723105*G0_1_1_5_0_1 - 0.112874779541447*G0_1_1_6_1_0 - 0.112874779541447*G0_1_1_6_1_1 - 0.835273368606707*G0_1_1_7_1_0 + 0.383774250440919*G0_1_1_8_1_1 + 0.045149911816579*G0_1_1_9_1_0 - 1.17389770723105*G0_1_1_9_1_1 - 0.045149911816579*G0_1_1_10_1_0 - 0.270899470899472*G0_1_1_10_1_1 + 0.948148148148154*G0_1_1_11_1_0 + 1.17389770723105*G0_1_1_11_1_1; + A[113] = 0.0; + A[180] = A[645]; + A[136] = 0.0; + A[594] = A[274] + 0.0112874779541452*G0_0_1_0_0_0 + 0.0112874779541453*G0_0_1_0_0_1 + 0.0677248677248659*G0_0_1_1_0_0 - 0.056437389770723*G0_0_1_2_0_1 - 0.0564373897707253*G0_0_1_3_0_0 + 0.0677248677248636*G0_0_1_3_0_1 + 0.0564373897707253*G0_0_1_4_0_0 + 0.0451499118165777*G0_0_1_4_0_1 - 0.0790123456790111*G0_0_1_5_0_0 - 0.0677248677248633*G0_0_1_5_0_1 + 0.0112874779541452*G0_0_1_6_1_0 + 0.0112874779541453*G0_0_1_6_1_1 + 0.0677248677248659*G0_0_1_7_1_0 - 0.056437389770723*G0_0_1_8_1_1 - 0.0564373897707253*G0_0_1_9_1_0 + 0.0677248677248636*G0_0_1_9_1_1 + 0.0564373897707253*G0_0_1_10_1_0 + 0.0451499118165777*G0_0_1_10_1_1 - 0.0790123456790111*G0_0_1_11_1_0 - 0.0677248677248633*G0_0_1_11_1_1 - 0.0112874779541452*G0_1_0_0_0_0 - 0.0112874779541453*G0_1_0_0_0_1 - 0.0677248677248658*G0_1_0_1_0_0 + 0.056437389770723*G0_1_0_2_0_1 + 0.0564373897707255*G0_1_0_3_0_0 - 0.0677248677248635*G0_1_0_3_0_1 - 0.0564373897707255*G0_1_0_4_0_0 - 0.0451499118165778*G0_1_0_4_0_1 + 0.079012345679011*G0_1_0_5_0_0 + 0.0677248677248633*G0_1_0_5_0_1 - 0.0112874779541452*G0_1_0_6_1_0 - 0.0112874779541453*G0_1_0_6_1_1 - 0.0677248677248658*G0_1_0_7_1_0 + 0.056437389770723*G0_1_0_8_1_1 + 0.0564373897707255*G0_1_0_9_1_0 - 0.0677248677248635*G0_1_0_9_1_1 - 0.0564373897707255*G0_1_0_10_1_0 - 0.0451499118165778*G0_1_0_10_1_1 + 0.079012345679011*G0_1_0_11_1_0 + 0.0677248677248633*G0_1_0_11_1_1; + A[215] = -A[683] + 0.112874779541445*G0_0_1_0_0_0 + 0.112874779541445*G0_0_1_0_0_1 + 1.06102292768959*G0_0_1_1_0_0 - 2.06560846560847*G0_0_1_2_0_1 - 3.18306878306879*G0_0_1_3_0_0 - 0.0564373897707249*G0_0_1_3_0_1 + 3.18306878306879*G0_0_1_4_0_0 + 1.95273368606702*G0_0_1_4_0_1 - 1.17389770723104*G0_0_1_5_0_0 + 0.056437389770725*G0_0_1_5_0_1 + 0.112874779541445*G0_0_1_6_1_0 + 0.112874779541445*G0_0_1_6_1_1 + 1.06102292768959*G0_0_1_7_1_0 - 2.06560846560847*G0_0_1_8_1_1 - 3.18306878306879*G0_0_1_9_1_0 - 0.0564373897707249*G0_0_1_9_1_1 + 3.18306878306879*G0_0_1_10_1_0 + 1.95273368606702*G0_0_1_10_1_1 - 1.17389770723104*G0_0_1_11_1_0 + 0.056437389770725*G0_0_1_11_1_1 + 1.48430335097001*G0_1_1_0_0_0 + 1.48430335097001*G0_1_1_0_0_1 + 1.1005291005291*G0_1_1_1_0_0 - 1.46172839506173*G0_1_1_2_0_1 - 3.30723104056438*G0_1_1_3_0_0 - 0.744973544973545*G0_1_1_3_0_1 + 3.30723104056438*G0_1_1_4_0_0 - 0.0225749559082831*G0_1_1_4_0_1 - 2.58483245149911*G0_1_1_5_0_0 + 0.744973544973545*G0_1_1_5_0_1 + 1.48430335097001*G0_1_1_6_1_0 + 1.48430335097001*G0_1_1_6_1_1 + 1.1005291005291*G0_1_1_7_1_0 - 1.46172839506173*G0_1_1_8_1_1 - 3.30723104056438*G0_1_1_9_1_0 - 0.744973544973545*G0_1_1_9_1_1 + 3.30723104056438*G0_1_1_10_1_0 - 0.0225749559082831*G0_1_1_10_1_1 - 2.58483245149911*G0_1_1_11_1_0 + 0.744973544973545*G0_1_1_11_1_1; + A[171] = 0.0; + A[619] = A[154]; + A[499] = A[34]; + A[206] = 0.0; + A[648] = -A[656] + 0.609523809523807*G0_0_0_0_0_0 + 0.609523809523806*G0_0_0_0_0_1 + 0.383774250440916*G0_0_0_1_0_0 - 0.112874779541446*G0_0_0_2_0_1 - 0.451499118165783*G0_0_0_3_0_0 + 0.0451499118165783*G0_0_0_3_0_1 + 0.451499118165783*G0_0_0_4_0_0 - 0.49664902998236*G0_0_0_4_0_1 - 0.993298059964722*G0_0_0_5_0_0 - 0.0451499118165785*G0_0_0_5_0_1 + 0.609523809523807*G0_0_0_6_1_0 + 0.609523809523806*G0_0_0_6_1_1 + 0.383774250440916*G0_0_0_7_1_0 - 0.112874779541446*G0_0_0_8_1_1 - 0.451499118165783*G0_0_0_9_1_0 + 0.0451499118165783*G0_0_0_9_1_1 + 0.451499118165783*G0_0_0_10_1_0 - 0.49664902998236*G0_0_0_10_1_1 - 0.993298059964722*G0_0_0_11_1_0 - 0.0451499118165785*G0_0_0_11_1_1 - 0.225749559082895*G0_1_0_0_0_0 - 0.225749559082895*G0_1_0_0_0_1 - 0.225749559082893*G0_1_0_2_0_1 - 0.225749559082891*G0_1_0_3_0_0 + 0.225749559082891*G0_1_0_4_0_0 + 0.451499118165788*G0_1_0_4_0_1 + 0.225749559082895*G0_1_0_5_0_0 - 0.225749559082895*G0_1_0_6_1_0 - 0.225749559082895*G0_1_0_6_1_1 - 0.225749559082893*G0_1_0_8_1_1 - 0.225749559082891*G0_1_0_9_1_0 + 0.225749559082891*G0_1_0_10_1_0 + 0.451499118165788*G0_1_0_10_1_1 + 0.225749559082895*G0_1_0_11_1_0; + A[314] = A[648] - 0.0338624338624325*G0_0_0_0_0_0 - 0.0338624338624323*G0_0_0_0_0_1 + 0.0338624338624344*G0_0_0_1_0_0 + 0.0338624338624351*G0_0_0_2_0_1 + 0.135449735449737*G0_0_0_3_0_0 + 0.135449735449736*G0_0_0_3_0_1 - 0.135449735449737*G0_0_0_4_0_0 - 0.135449735449736*G0_0_0_5_0_1 - 0.0338624338624325*G0_0_0_6_1_0 - 0.0338624338624323*G0_0_0_6_1_1 + 0.0338624338624344*G0_0_0_7_1_0 + 0.0338624338624351*G0_0_0_8_1_1 + 0.135449735449737*G0_0_0_9_1_0 + 0.135449735449736*G0_0_0_9_1_1 - 0.135449735449737*G0_0_0_10_1_0 - 0.135449735449736*G0_0_0_11_1_1 + 0.253968253968252*G0_0_1_0_0_0 + 0.253968253968252*G0_0_1_0_0_1 + 0.332980599647264*G0_0_1_1_0_0 - 0.0282186948853606*G0_0_1_2_0_1 + 0.022574955908291*G0_0_1_3_0_0 + 0.383774250440916*G0_0_1_3_0_1 - 0.022574955908291*G0_0_1_4_0_0 - 0.225749559082891*G0_0_1_4_0_1 - 0.586948853615516*G0_0_1_5_0_0 - 0.383774250440916*G0_0_1_5_0_1 + 0.253968253968252*G0_0_1_6_1_0 + 0.253968253968252*G0_0_1_6_1_1 + 0.332980599647264*G0_0_1_7_1_0 - 0.0282186948853606*G0_0_1_8_1_1 + 0.022574955908291*G0_0_1_9_1_0 + 0.383774250440916*G0_0_1_9_1_1 - 0.022574955908291*G0_0_1_10_1_0 - 0.225749559082891*G0_0_1_10_1_1 - 0.586948853615516*G0_0_1_11_1_0 - 0.383774250440916*G0_0_1_11_1_1 - 0.0395061728395072*G0_1_0_0_0_0 - 0.0395061728395071*G0_1_0_0_0_1 - 0.0507936507936526*G0_1_0_1_0_0 + 0.0620811287477974*G0_1_0_2_0_1 + 0.112874779541449*G0_1_0_3_0_0 - 0.112874779541449*G0_1_0_4_0_0 - 0.0225749559082902*G0_1_0_4_0_1 + 0.0902998236331598*G0_1_0_5_0_0 - 0.0395061728395072*G0_1_0_6_1_0 - 0.0395061728395071*G0_1_0_6_1_1 - 0.0507936507936526*G0_1_0_7_1_0 + 0.0620811287477974*G0_1_0_8_1_1 + 0.112874779541449*G0_1_0_9_1_0 - 0.112874779541449*G0_1_0_10_1_0 - 0.0225749559082902*G0_1_0_10_1_1 + 0.0902998236331598*G0_1_0_11_1_0 - 0.428924162257496*G0_1_1_0_0_0 - 0.428924162257496*G0_1_1_0_0_1 + 0.677248677248675*G0_1_1_1_0_0 - 0.699823633156965*G0_1_1_2_0_1 - 0.293474426807761*G0_1_1_3_0_0 + 1.08359788359788*G0_1_1_3_0_1 + 0.293474426807761*G0_1_1_4_0_0 + 1.12874779541446*G0_1_1_4_0_1 - 0.248324514991179*G0_1_1_5_0_0 - 1.08359788359788*G0_1_1_5_0_1 - 0.428924162257496*G0_1_1_6_1_0 - 0.428924162257496*G0_1_1_6_1_1 + 0.677248677248675*G0_1_1_7_1_0 - 0.699823633156965*G0_1_1_8_1_1 - 0.293474426807761*G0_1_1_9_1_0 + 1.08359788359788*G0_1_1_9_1_1 + 0.293474426807761*G0_1_1_10_1_0 + 1.12874779541446*G0_1_1_10_1_1 - 0.248324514991179*G0_1_1_11_1_0 - 1.08359788359788*G0_1_1_11_1_1; + A[132] = A[314] + 0.71111111111111*G0_0_0_0_0_0 + 0.71111111111111*G0_0_0_0_0_1 + 0.507936507936507*G0_0_0_1_0_0 + 0.711111111111108*G0_0_0_2_0_1 + 1.21904761904761*G0_0_0_3_0_0 + 1.01587301587301*G0_0_0_3_0_1 - 1.21904761904761*G0_0_0_4_0_0 - 1.42222222222222*G0_0_0_4_0_1 - 1.21904761904762*G0_0_0_5_0_0 - 1.01587301587301*G0_0_0_5_0_1 + 0.71111111111111*G0_0_0_6_1_0 + 0.71111111111111*G0_0_0_6_1_1 + 0.507936507936507*G0_0_0_7_1_0 + 0.711111111111108*G0_0_0_8_1_1 + 1.21904761904761*G0_0_0_9_1_0 + 1.01587301587301*G0_0_0_9_1_1 - 1.21904761904761*G0_0_0_10_1_0 - 1.42222222222222*G0_0_0_10_1_1 - 1.21904761904762*G0_0_0_11_1_0 - 1.01587301587301*G0_0_0_11_1_1 + 0.440211640211639*G0_0_1_0_0_0 + 0.440211640211639*G0_0_1_0_0_1 + 0.169312169312169*G0_0_1_1_0_0 + 0.778835978835978*G0_0_1_2_0_1 + 1.28677248677249*G0_0_1_3_0_0 + 0.677248677248677*G0_0_1_3_0_1 - 1.28677248677249*G0_0_1_4_0_0 - 1.21904761904762*G0_0_1_4_0_1 - 0.609523809523808*G0_0_1_5_0_0 - 0.677248677248677*G0_0_1_5_0_1 + 0.440211640211639*G0_0_1_6_1_0 + 0.440211640211639*G0_0_1_6_1_1 + 0.169312169312169*G0_0_1_7_1_0 + 0.778835978835978*G0_0_1_8_1_1 + 1.28677248677249*G0_0_1_9_1_0 + 0.677248677248677*G0_0_1_9_1_1 - 1.28677248677249*G0_0_1_10_1_0 - 1.21904761904762*G0_0_1_10_1_1 - 0.609523809523808*G0_0_1_11_1_0 - 0.677248677248677*G0_0_1_11_1_1 + 0.77883597883598*G0_1_0_0_0_0 + 0.77883597883598*G0_1_0_0_0_1 + 0.846560846560844*G0_1_0_1_0_0 + 0.440211640211638*G0_1_0_2_0_1 + 0.94814814814814*G0_1_0_3_0_0 + 1.35449735449735*G0_1_0_3_0_1 - 0.94814814814814*G0_1_0_4_0_0 - 1.21904761904762*G0_1_0_4_0_1 - 1.62539682539682*G0_1_0_5_0_0 - 1.35449735449735*G0_1_0_5_0_1 + 0.77883597883598*G0_1_0_6_1_0 + 0.77883597883598*G0_1_0_6_1_1 + 0.846560846560844*G0_1_0_7_1_0 + 0.440211640211638*G0_1_0_8_1_1 + 0.94814814814814*G0_1_0_9_1_0 + 1.35449735449735*G0_1_0_9_1_1 - 0.94814814814814*G0_1_0_10_1_0 - 1.21904761904762*G0_1_0_10_1_1 - 1.62539682539682*G0_1_0_11_1_0 - 1.35449735449735*G0_1_0_11_1_1 + 1.21904761904762*G0_1_1_0_0_0 + 1.21904761904762*G0_1_1_0_0_1 + 1.21904761904762*G0_1_1_2_0_1 + 1.21904761904762*G0_1_1_3_0_0 - 1.21904761904762*G0_1_1_4_0_0 - 2.43809523809524*G0_1_1_4_0_1 - 1.21904761904761*G0_1_1_5_0_0 + 1.21904761904762*G0_1_1_6_1_0 + 1.21904761904762*G0_1_1_6_1_1 + 1.21904761904762*G0_1_1_8_1_1 + 1.21904761904762*G0_1_1_9_1_0 - 1.21904761904762*G0_1_1_10_1_0 - 2.43809523809524*G0_1_1_10_1_1 - 1.21904761904761*G0_1_1_11_1_0; + A[597] = A[132]; + A[312] = A[314] + 2.16719576719576*G0_0_0_0_0_0 + 2.16719576719576*G0_0_0_0_0_1 + 2.16719576719577*G0_0_0_1_0_0 + 2.16719576719577*G0_0_0_3_0_1 - 2.16719576719576*G0_0_0_4_0_1 - 4.33439153439153*G0_0_0_5_0_0 - 2.16719576719577*G0_0_0_5_0_1 + 2.16719576719576*G0_0_0_6_1_0 + 2.16719576719576*G0_0_0_6_1_1 + 2.16719576719577*G0_0_0_7_1_0 + 2.16719576719577*G0_0_0_9_1_1 - 2.16719576719576*G0_0_0_10_1_1 - 4.33439153439153*G0_0_0_11_1_0 - 2.16719576719577*G0_0_0_11_1_1 - 1.35449735449735*G0_0_1_0_0_0 - 1.35449735449735*G0_0_1_0_0_1 + 1.08359788359788*G0_0_1_1_0_0 - 0.812698412698413*G0_0_1_2_0_1 + 0.812698412698407*G0_0_1_3_0_0 + 2.7089947089947*G0_0_1_3_0_1 - 0.812698412698407*G0_0_1_4_0_0 + 2.16719576719577*G0_0_1_4_0_1 + 0.270899470899469*G0_0_1_5_0_0 - 2.7089947089947*G0_0_1_5_0_1 - 1.35449735449735*G0_0_1_6_1_0 - 1.35449735449735*G0_0_1_6_1_1 + 1.08359788359788*G0_0_1_7_1_0 - 0.812698412698413*G0_0_1_8_1_1 + 0.812698412698407*G0_0_1_9_1_0 + 2.7089947089947*G0_0_1_9_1_1 - 0.812698412698407*G0_0_1_10_1_0 + 2.16719576719577*G0_0_1_10_1_1 + 0.270899470899469*G0_0_1_11_1_0 - 2.7089947089947*G0_0_1_11_1_1 - 0.270899470899471*G0_1_0_0_0_0 - 0.27089947089947*G0_1_0_0_0_1 + 1.62539682539682*G0_1_0_1_0_0 - 0.270899470899473*G0_1_0_2_0_1 + 1.35449735449735*G0_1_0_3_0_0 + 3.25079365079364*G0_1_0_3_0_1 - 1.35449735449735*G0_1_0_4_0_0 + 0.541798941798944*G0_1_0_4_0_1 - 1.35449735449735*G0_1_0_5_0_0 - 3.25079365079364*G0_1_0_5_0_1 - 0.270899470899471*G0_1_0_6_1_0 - 0.27089947089947*G0_1_0_6_1_1 + 1.62539682539682*G0_1_0_7_1_0 - 0.270899470899473*G0_1_0_8_1_1 + 1.35449735449735*G0_1_0_9_1_0 + 3.25079365079364*G0_1_0_9_1_1 - 1.35449735449735*G0_1_0_10_1_0 + 0.541798941798944*G0_1_0_10_1_1 - 1.35449735449735*G0_1_0_11_1_0 - 3.25079365079364*G0_1_0_11_1_1 + 1.08359788359789*G0_1_1_0_0_0 + 1.08359788359789*G0_1_1_0_0_1 + 1.08359788359788*G0_1_1_2_0_1 + 1.08359788359788*G0_1_1_3_0_0 - 1.08359788359788*G0_1_1_4_0_0 - 2.16719576719577*G0_1_1_4_0_1 - 1.08359788359788*G0_1_1_5_0_0 + 1.08359788359789*G0_1_1_6_1_0 + 1.08359788359789*G0_1_1_6_1_1 + 1.08359788359788*G0_1_1_8_1_1 + 1.08359788359788*G0_1_1_9_1_0 - 1.08359788359788*G0_1_1_10_1_0 - 2.16719576719577*G0_1_1_10_1_1 - 1.08359788359788*G0_1_1_11_1_0; + A[367] = A[312] - 1.59153439153438*G0_0_0_0_0_0 - 1.59153439153438*G0_0_0_0_0_1 - 1.79470899470899*G0_0_0_1_0_0 + 0.711111111111115*G0_0_0_2_0_1 + 1.21904761904762*G0_0_0_3_0_0 - 1.28677248677248*G0_0_0_3_0_1 - 1.21904761904762*G0_0_0_4_0_0 + 0.880423280423269*G0_0_0_4_0_1 + 3.38624338624338*G0_0_0_5_0_0 + 1.28677248677248*G0_0_0_5_0_1 - 1.59153439153438*G0_0_0_6_1_0 - 1.59153439153438*G0_0_0_6_1_1 - 1.79470899470899*G0_0_0_7_1_0 + 0.711111111111115*G0_0_0_8_1_1 + 1.21904761904762*G0_0_0_9_1_0 - 1.28677248677248*G0_0_0_9_1_1 - 1.21904761904762*G0_0_0_10_1_0 + 0.880423280423269*G0_0_0_10_1_1 + 3.38624338624338*G0_0_0_11_1_0 + 1.28677248677248*G0_0_0_11_1_1 - 2.16719576719577*G0_0_1_1_0_0 + 2.16719576719577*G0_0_1_2_0_1 + 2.16719576719577*G0_0_1_3_0_0 - 2.16719576719576*G0_0_1_3_0_1 - 2.16719576719577*G0_0_1_4_0_0 - 2.16719576719577*G0_0_1_4_0_1 + 2.16719576719577*G0_0_1_5_0_0 + 2.16719576719576*G0_0_1_5_0_1 - 2.16719576719577*G0_0_1_7_1_0 + 2.16719576719577*G0_0_1_8_1_1 + 2.16719576719577*G0_0_1_9_1_0 - 2.16719576719576*G0_0_1_9_1_1 - 2.16719576719577*G0_0_1_10_1_0 - 2.16719576719577*G0_0_1_10_1_1 + 2.16719576719577*G0_0_1_11_1_0 + 2.16719576719576*G0_0_1_11_1_1 - 1.82857142857143*G0_1_0_1_0_0 + 1.82857142857143*G0_1_0_2_0_1 + 1.82857142857143*G0_1_0_3_0_0 - 1.82857142857142*G0_1_0_3_0_1 - 1.82857142857143*G0_1_0_4_0_0 - 1.82857142857143*G0_1_0_4_0_1 + 1.82857142857142*G0_1_0_5_0_0 + 1.82857142857142*G0_1_0_5_0_1 - 1.82857142857143*G0_1_0_7_1_0 + 1.82857142857143*G0_1_0_8_1_1 + 1.82857142857143*G0_1_0_9_1_0 - 1.82857142857142*G0_1_0_9_1_1 - 1.82857142857143*G0_1_0_10_1_0 - 1.82857142857143*G0_1_0_10_1_1 + 1.82857142857142*G0_1_0_11_1_0 + 1.82857142857142*G0_1_0_11_1_1 + 1.59153439153439*G0_1_1_0_0_0 + 1.59153439153439*G0_1_1_0_0_1 - 0.711111111111109*G0_1_1_1_0_0 + 1.79470899470899*G0_1_1_2_0_1 + 1.28677248677249*G0_1_1_3_0_0 - 1.21904761904761*G0_1_1_3_0_1 - 1.28677248677249*G0_1_1_4_0_0 - 3.38624338624338*G0_1_1_4_0_1 - 0.880423280423279*G0_1_1_5_0_0 + 1.21904761904761*G0_1_1_5_0_1 + 1.59153439153439*G0_1_1_6_1_0 + 1.59153439153439*G0_1_1_6_1_1 - 0.711111111111109*G0_1_1_7_1_0 + 1.79470899470899*G0_1_1_8_1_1 + 1.28677248677249*G0_1_1_9_1_0 - 1.21904761904761*G0_1_1_9_1_1 - 1.28677248677249*G0_1_1_10_1_0 - 3.38624338624338*G0_1_1_10_1_1 - 0.880423280423279*G0_1_1_11_1_0 + 1.21904761904761*G0_1_1_11_1_1; + A[892] = A[367] - 0.541798941798948*G0_0_0_0_0_0 - 0.541798941798947*G0_0_0_0_0_1 + 1.08359788359788*G0_0_0_1_0_0 - 4.87619047619048*G0_0_0_2_0_1 - 8.12698412698414*G0_0_0_3_0_0 - 2.16719576719577*G0_0_0_3_0_1 + 8.12698412698414*G0_0_0_4_0_0 + 5.41798941798943*G0_0_0_4_0_1 - 0.541798941798937*G0_0_0_5_0_0 + 2.16719576719577*G0_0_0_5_0_1 - 0.541798941798948*G0_0_0_6_1_0 - 0.541798941798947*G0_0_0_6_1_1 + 1.08359788359788*G0_0_0_7_1_0 - 4.87619047619048*G0_0_0_8_1_1 - 8.12698412698414*G0_0_0_9_1_0 - 2.16719576719577*G0_0_0_9_1_1 + 8.12698412698414*G0_0_0_10_1_0 + 5.41798941798943*G0_0_0_10_1_1 - 0.541798941798937*G0_0_0_11_1_0 + 2.16719576719577*G0_0_0_11_1_1 + 0.270899470899466*G0_0_1_0_0_0 + 0.270899470899466*G0_0_1_0_0_1 + 1.62539682539683*G0_0_1_1_0_0 - 4.60529100529101*G0_0_1_2_0_1 - 7.85608465608466*G0_0_1_3_0_0 - 1.62539682539683*G0_0_1_3_0_1 + 7.85608465608466*G0_0_1_4_0_0 + 4.33439153439154*G0_0_1_4_0_1 - 1.89629629629629*G0_0_1_5_0_0 + 1.62539682539683*G0_0_1_5_0_1 + 0.270899470899466*G0_0_1_6_1_0 + 0.270899470899466*G0_0_1_6_1_1 + 1.62539682539683*G0_0_1_7_1_0 - 4.60529100529101*G0_0_1_8_1_1 - 7.85608465608466*G0_0_1_9_1_0 - 1.62539682539683*G0_0_1_9_1_1 + 7.85608465608466*G0_0_1_10_1_0 + 4.33439153439154*G0_0_1_10_1_1 - 1.89629629629629*G0_0_1_11_1_0 + 1.62539682539683*G0_0_1_11_1_1 - 0.270899470899474*G0_1_0_0_0_0 - 0.270899470899473*G0_1_0_0_0_1 + 0.541798941798941*G0_1_0_1_0_0 - 4.06349206349207*G0_1_0_2_0_1 - 7.31428571428571*G0_1_0_3_0_0 - 2.70899470899471*G0_1_0_3_0_1 + 7.31428571428571*G0_1_0_4_0_0 + 4.33439153439154*G0_1_0_4_0_1 - 0.270899470899468*G0_1_0_5_0_0 + 2.70899470899471*G0_1_0_5_0_1 - 0.270899470899474*G0_1_0_6_1_0 - 0.270899470899473*G0_1_0_6_1_1 + 0.541798941798941*G0_1_0_7_1_0 - 4.06349206349207*G0_1_0_8_1_1 - 7.31428571428571*G0_1_0_9_1_0 - 2.70899470899471*G0_1_0_9_1_1 + 7.31428571428571*G0_1_0_10_1_0 + 4.33439153439154*G0_1_0_10_1_1 - 0.270899470899468*G0_1_0_11_1_0 + 2.70899470899471*G0_1_0_11_1_1 - 4.33439153439153*G0_1_1_0_0_0 - 4.33439153439153*G0_1_1_0_0_1 - 4.33439153439154*G0_1_1_2_0_1 - 4.33439153439154*G0_1_1_3_0_0 + 4.33439153439154*G0_1_1_4_0_0 + 8.66878306878307*G0_1_1_4_0_1 + 4.33439153439153*G0_1_1_5_0_0 - 4.33439153439153*G0_1_1_6_1_0 - 4.33439153439153*G0_1_1_6_1_1 - 4.33439153439154*G0_1_1_8_1_1 - 4.33439153439154*G0_1_1_9_1_0 + 4.33439153439154*G0_1_1_10_1_0 + 8.66878306878307*G0_1_1_10_1_1 + 4.33439153439153*G0_1_1_11_1_0; + A[427] = A[892]; + A[370] = A[312] + 0.744973544973543*G0_0_1_0_0_0 + 0.744973544973544*G0_0_1_0_0_1 + 0.203174603174602*G0_0_1_1_0_0 + 0.541798941798941*G0_0_1_2_0_1 + 0.541798941798942*G0_0_1_3_0_0 + 0.203174603174603*G0_0_1_3_0_1 - 0.541798941798942*G0_0_1_4_0_0 - 1.28677248677248*G0_0_1_4_0_1 - 0.948148148148145*G0_0_1_5_0_0 - 0.203174603174602*G0_0_1_5_0_1 + 0.744973544973543*G0_0_1_6_1_0 + 0.744973544973544*G0_0_1_6_1_1 + 0.203174603174602*G0_0_1_7_1_0 + 0.541798941798941*G0_0_1_8_1_1 + 0.541798941798942*G0_0_1_9_1_0 + 0.203174603174603*G0_0_1_9_1_1 - 0.541798941798942*G0_0_1_10_1_0 - 1.28677248677248*G0_0_1_10_1_1 - 0.948148148148145*G0_0_1_11_1_0 - 0.203174603174602*G0_0_1_11_1_1 - 0.744973544973544*G0_1_0_0_0_0 - 0.744973544973544*G0_1_0_0_0_1 - 0.203174603174602*G0_1_0_1_0_0 - 0.541798941798942*G0_1_0_2_0_1 - 0.541798941798942*G0_1_0_3_0_0 - 0.203174603174603*G0_1_0_3_0_1 + 0.541798941798942*G0_1_0_4_0_0 + 1.28677248677249*G0_1_0_4_0_1 + 0.948148148148146*G0_1_0_5_0_0 + 0.203174603174602*G0_1_0_5_0_1 - 0.744973544973544*G0_1_0_6_1_0 - 0.744973544973544*G0_1_0_6_1_1 - 0.203174603174602*G0_1_0_7_1_0 - 0.541798941798942*G0_1_0_8_1_1 - 0.541798941798942*G0_1_0_9_1_0 - 0.203174603174603*G0_1_0_9_1_1 + 0.541798941798942*G0_1_0_10_1_0 + 1.28677248677249*G0_1_0_10_1_1 + 0.948148148148146*G0_1_0_11_1_0 + 0.203174603174602*G0_1_0_11_1_1; + A[134] = A[314] - 1.45608465608466*G0_0_0_0_0_0 - 1.45608465608466*G0_0_0_0_0_1 - 0.0338624338624344*G0_0_0_1_0_0 - 4.16507936507936*G0_0_0_2_0_1 - 6.9079365079365*G0_0_0_3_0_0 - 2.77671957671957*G0_0_0_3_0_1 + 6.9079365079365*G0_0_0_4_0_0 + 5.62116402116402*G0_0_0_4_0_1 + 1.48994708994709*G0_0_0_5_0_0 + 2.77671957671957*G0_0_0_5_0_1 - 1.45608465608466*G0_0_0_6_1_0 - 1.45608465608466*G0_0_0_6_1_1 - 0.0338624338624344*G0_0_0_7_1_0 - 4.16507936507936*G0_0_0_8_1_1 - 6.9079365079365*G0_0_0_9_1_0 - 2.77671957671957*G0_0_0_9_1_1 + 6.9079365079365*G0_0_0_10_1_0 + 5.62116402116402*G0_0_0_10_1_1 + 1.48994708994709*G0_0_0_11_1_0 + 2.77671957671957*G0_0_0_11_1_1 - 1.45608465608465*G0_0_1_0_0_0 - 1.45608465608465*G0_0_1_0_0_1 - 0.914285714285713*G0_0_1_1_0_0 - 1.65925925925926*G0_0_1_2_0_1 - 2.77671957671958*G0_0_1_3_0_0 - 2.03174603174603*G0_0_1_3_0_1 + 2.77671957671958*G0_0_1_4_0_0 + 3.11534391534392*G0_0_1_4_0_1 + 2.37037037037037*G0_0_1_5_0_0 + 2.03174603174603*G0_0_1_5_0_1 - 1.45608465608465*G0_0_1_6_1_0 - 1.45608465608465*G0_0_1_6_1_1 - 0.914285714285713*G0_0_1_7_1_0 - 1.65925925925926*G0_0_1_8_1_1 - 2.77671957671958*G0_0_1_9_1_0 - 2.03174603174603*G0_0_1_9_1_1 + 2.77671957671958*G0_0_1_10_1_0 + 3.11534391534392*G0_0_1_10_1_1 + 2.37037037037037*G0_0_1_11_1_0 + 2.03174603174603*G0_0_1_11_1_1 - 0.575661375661374*G0_1_0_0_0_0 - 0.575661375661375*G0_1_0_0_0_1 - 0.778835978835978*G0_1_0_1_0_0 - 0.914285714285717*G0_1_0_2_0_1 - 2.03174603174604*G0_1_0_3_0_0 - 1.8962962962963*G0_1_0_3_0_1 + 2.03174603174604*G0_1_0_4_0_0 + 1.48994708994709*G0_1_0_4_0_1 + 1.35449735449735*G0_1_0_5_0_0 + 1.8962962962963*G0_1_0_5_0_1 - 0.575661375661374*G0_1_0_6_1_0 - 0.575661375661375*G0_1_0_6_1_1 - 0.778835978835978*G0_1_0_7_1_0 - 0.914285714285717*G0_1_0_8_1_1 - 2.03174603174604*G0_1_0_9_1_0 - 1.8962962962963*G0_1_0_9_1_1 + 2.03174603174604*G0_1_0_10_1_0 + 1.48994708994709*G0_1_0_10_1_1 + 1.35449735449735*G0_1_0_11_1_0 + 1.8962962962963*G0_1_0_11_1_1 + 0.135449735449737*G0_1_1_0_0_0 + 0.135449735449737*G0_1_1_0_0_1 + 0.135449735449733*G0_1_1_2_0_1 + 0.13544973544973*G0_1_1_3_0_0 - 0.13544973544973*G0_1_1_4_0_0 - 0.27089947089947*G0_1_1_4_0_1 - 0.135449735449739*G0_1_1_5_0_0 + 0.135449735449737*G0_1_1_6_1_0 + 0.135449735449737*G0_1_1_6_1_1 + 0.135449735449733*G0_1_1_8_1_1 + 0.13544973544973*G0_1_1_9_1_0 - 0.13544973544973*G0_1_1_10_1_0 - 0.27089947089947*G0_1_1_10_1_1 - 0.135449735449739*G0_1_1_11_1_0; + A[394] = A[134] + 1.08359788359789*G0_0_0_0_0_0 + 1.08359788359789*G0_0_0_0_0_1 - 0.541798941798939*G0_0_0_1_0_0 + 4.87619047619047*G0_0_0_2_0_1 + 8.12698412698412*G0_0_0_3_0_0 + 2.70899470899471*G0_0_0_3_0_1 - 8.12698412698412*G0_0_0_4_0_0 - 5.95978835978836*G0_0_0_4_0_1 - 0.541798941798946*G0_0_0_5_0_0 - 2.70899470899471*G0_0_0_5_0_1 + 1.08359788359789*G0_0_0_6_1_0 + 1.08359788359789*G0_0_0_6_1_1 - 0.541798941798939*G0_0_0_7_1_0 + 4.87619047619047*G0_0_0_8_1_1 + 8.12698412698412*G0_0_0_9_1_0 + 2.70899470899471*G0_0_0_9_1_1 - 8.12698412698412*G0_0_0_10_1_0 - 5.95978835978836*G0_0_0_10_1_1 - 0.541798941798946*G0_0_0_11_1_0 - 2.70899470899471*G0_0_0_11_1_1 - 1.01587301587301*G0_0_1_1_0_0 + 1.01587301587302*G0_0_1_2_0_1 + 1.01587301587303*G0_0_1_3_0_0 - 1.015873015873*G0_0_1_3_0_1 - 1.01587301587303*G0_0_1_4_0_0 - 1.01587301587302*G0_0_1_4_0_1 + 1.01587301587301*G0_0_1_5_0_0 + 1.015873015873*G0_0_1_5_0_1 - 1.01587301587301*G0_0_1_7_1_0 + 1.01587301587302*G0_0_1_8_1_1 + 1.01587301587303*G0_0_1_9_1_0 - 1.015873015873*G0_0_1_9_1_1 - 1.01587301587303*G0_0_1_10_1_0 - 1.01587301587302*G0_0_1_10_1_1 + 1.01587301587301*G0_0_1_11_1_0 + 1.015873015873*G0_0_1_11_1_1 - 0.0677248677248644*G0_1_0_1_0_0 + 0.0677248677248725*G0_1_0_2_0_1 + 0.0677248677248792*G0_1_0_3_0_0 - 0.0677248677248579*G0_1_0_3_0_1 - 0.0677248677248792*G0_1_0_4_0_0 - 0.0677248677248743*G0_1_0_4_0_1 + 0.0677248677248627*G0_1_0_5_0_0 + 0.0677248677248579*G0_1_0_5_0_1 - 0.0677248677248644*G0_1_0_7_1_0 + 0.0677248677248725*G0_1_0_8_1_1 + 0.0677248677248792*G0_1_0_9_1_0 - 0.0677248677248579*G0_1_0_9_1_1 - 0.0677248677248792*G0_1_0_10_1_0 - 0.0677248677248743*G0_1_0_10_1_1 + 0.0677248677248627*G0_1_0_11_1_0 + 0.0677248677248579*G0_1_0_11_1_1 - 1.08359788359788*G0_1_1_0_0_0 - 1.08359788359788*G0_1_1_0_0_1 - 4.87619047619047*G0_1_1_1_0_0 + 0.541798941798944*G0_1_1_2_0_1 - 2.7089947089947*G0_1_1_3_0_0 - 8.12698412698411*G0_1_1_3_0_1 + 2.7089947089947*G0_1_1_4_0_0 + 0.541798941798935*G0_1_1_4_0_1 + 5.95978835978835*G0_1_1_5_0_0 + 8.12698412698412*G0_1_1_5_0_1 - 1.08359788359788*G0_1_1_6_1_0 - 1.08359788359788*G0_1_1_6_1_1 - 4.87619047619047*G0_1_1_7_1_0 + 0.541798941798944*G0_1_1_8_1_1 - 2.7089947089947*G0_1_1_9_1_0 - 8.12698412698411*G0_1_1_9_1_1 + 2.7089947089947*G0_1_1_10_1_0 + 0.541798941798935*G0_1_1_10_1_1 + 5.95978835978835*G0_1_1_11_1_0 + 8.12698412698412*G0_1_1_11_1_1; + A[599] = A[134]; + A[688] = A[367] - 1.08359788359789*G0_0_0_0_0_0 - 1.08359788359789*G0_0_0_0_0_1 - 1.08359788359789*G0_0_0_1_0_0 - 1.08359788359789*G0_0_0_3_0_1 + 1.08359788359789*G0_0_0_4_0_1 + 2.16719576719577*G0_0_0_5_0_0 + 1.08359788359789*G0_0_0_5_0_1 - 1.08359788359789*G0_0_0_6_1_0 - 1.08359788359789*G0_0_0_6_1_1 - 1.08359788359789*G0_0_0_7_1_0 - 1.08359788359789*G0_0_0_9_1_1 + 1.08359788359789*G0_0_0_10_1_1 + 2.16719576719577*G0_0_0_11_1_0 + 1.08359788359789*G0_0_0_11_1_1 + 1.01587301587301*G0_0_1_0_0_0 + 1.01587301587301*G0_0_1_0_0_1 + 0.812698412698409*G0_0_1_1_0_0 - 1.42222222222222*G0_0_1_2_0_1 - 3.04761904761905*G0_0_1_3_0_0 - 0.81269841269842*G0_0_1_3_0_1 + 3.04761904761905*G0_0_1_4_0_0 + 0.40634920634921*G0_0_1_4_0_1 - 1.82857142857142*G0_0_1_5_0_0 + 0.81269841269842*G0_0_1_5_0_1 + 1.01587301587301*G0_0_1_6_1_0 + 1.01587301587301*G0_0_1_6_1_1 + 0.812698412698409*G0_0_1_7_1_0 - 1.42222222222222*G0_0_1_8_1_1 - 3.04761904761905*G0_0_1_9_1_0 - 0.81269841269842*G0_0_1_9_1_1 + 3.04761904761905*G0_0_1_10_1_0 + 0.40634920634921*G0_0_1_10_1_1 - 1.82857142857142*G0_0_1_11_1_0 + 0.81269841269842*G0_0_1_11_1_1 + 0.609523809523808*G0_1_0_0_0_0 + 0.609523809523808*G0_1_0_0_0_1 + 0.27089947089947*G0_1_0_1_0_0 - 1.28677248677249*G0_1_0_2_0_1 - 2.91216931216932*G0_1_0_3_0_0 - 1.35449735449736*G0_1_0_3_0_1 + 2.91216931216932*G0_1_0_4_0_0 + 0.677248677248682*G0_1_0_4_0_1 - 0.880423280423278*G0_1_0_5_0_0 + 1.35449735449736*G0_1_0_5_0_1 + 0.609523809523808*G0_1_0_6_1_0 + 0.609523809523808*G0_1_0_6_1_1 + 0.27089947089947*G0_1_0_7_1_0 - 1.28677248677249*G0_1_0_8_1_1 - 2.91216931216932*G0_1_0_9_1_0 - 1.35449735449736*G0_1_0_9_1_1 + 2.91216931216932*G0_1_0_10_1_0 + 0.677248677248682*G0_1_0_10_1_1 - 0.880423280423278*G0_1_0_11_1_0 + 1.35449735449736*G0_1_0_11_1_1 - 2.16719576719576*G0_1_1_0_0_0 - 2.16719576719576*G0_1_1_0_0_1 - 2.16719576719577*G0_1_1_2_0_1 - 2.16719576719577*G0_1_1_3_0_0 + 2.16719576719577*G0_1_1_4_0_0 + 4.33439153439153*G0_1_1_4_0_1 + 2.16719576719576*G0_1_1_5_0_0 - 2.16719576719576*G0_1_1_6_1_0 - 2.16719576719576*G0_1_1_6_1_1 - 2.16719576719577*G0_1_1_8_1_1 - 2.16719576719577*G0_1_1_9_1_0 + 2.16719576719577*G0_1_1_10_1_0 + 4.33439153439153*G0_1_1_10_1_1 + 2.16719576719576*G0_1_1_11_1_0; + A[832] = A[367]; + A[96] = A[648] - 0.0451499118165797*G0_0_1_0_0_0 - 0.0451499118165797*G0_0_1_0_0_1 + 0.0451499118165783*G0_0_1_1_0_0 - 0.0902998236331573*G0_0_1_2_0_1 - 0.0902998236331566*G0_0_1_3_0_0 + 0.0451499118165788*G0_0_1_3_0_1 + 0.0902998236331566*G0_0_1_4_0_0 + 0.135449735449737*G0_0_1_4_0_1 - 0.0451499118165788*G0_0_1_5_0_1 - 0.0451499118165797*G0_0_1_6_1_0 - 0.0451499118165797*G0_0_1_6_1_1 + 0.0451499118165783*G0_0_1_7_1_0 - 0.0902998236331573*G0_0_1_8_1_1 - 0.0902998236331566*G0_0_1_9_1_0 + 0.0451499118165788*G0_0_1_9_1_1 + 0.0902998236331566*G0_0_1_10_1_0 + 0.135449735449737*G0_0_1_10_1_1 - 0.0451499118165788*G0_0_1_11_1_1 + 0.0451499118165797*G0_1_0_0_0_0 + 0.0451499118165797*G0_1_0_0_0_1 - 0.0451499118165783*G0_1_0_1_0_0 + 0.0902998236331572*G0_1_0_2_0_1 + 0.0902998236331566*G0_1_0_3_0_0 - 0.0451499118165788*G0_1_0_3_0_1 - 0.0902998236331566*G0_1_0_4_0_0 - 0.135449735449737*G0_1_0_4_0_1 + 0.0451499118165788*G0_1_0_5_0_1 + 0.0451499118165797*G0_1_0_6_1_0 + 0.0451499118165797*G0_1_0_6_1_1 - 0.0451499118165783*G0_1_0_7_1_0 + 0.0902998236331572*G0_1_0_8_1_1 + 0.0902998236331566*G0_1_0_9_1_0 - 0.0451499118165788*G0_1_0_9_1_1 - 0.0902998236331566*G0_1_0_10_1_0 - 0.135449735449737*G0_1_0_10_1_1 + 0.0451499118165788*G0_1_0_11_1_1; + A[801] = -A[96] + 0.609523809523807*G0_0_0_0_0_0 + 0.609523809523806*G0_0_0_0_0_1 + 0.383774250440916*G0_0_0_1_0_0 - 0.112874779541446*G0_0_0_2_0_1 - 0.451499118165783*G0_0_0_3_0_0 + 0.0451499118165785*G0_0_0_3_0_1 + 0.451499118165783*G0_0_0_4_0_0 - 0.49664902998236*G0_0_0_4_0_1 - 0.993298059964722*G0_0_0_5_0_0 - 0.0451499118165785*G0_0_0_5_0_1 + 0.609523809523807*G0_0_0_6_1_0 + 0.609523809523806*G0_0_0_6_1_1 + 0.383774250440916*G0_0_0_7_1_0 - 0.112874779541446*G0_0_0_8_1_1 - 0.451499118165783*G0_0_0_9_1_0 + 0.0451499118165785*G0_0_0_9_1_1 + 0.451499118165783*G0_0_0_10_1_0 - 0.49664902998236*G0_0_0_10_1_1 - 0.993298059964722*G0_0_0_11_1_0 - 0.0451499118165785*G0_0_0_11_1_1 - 0.225749559082895*G0_0_1_0_0_0 - 0.225749559082895*G0_0_1_0_0_1 - 0.225749559082893*G0_0_1_2_0_1 - 0.225749559082892*G0_0_1_3_0_0 + 0.225749559082892*G0_0_1_4_0_0 + 0.451499118165788*G0_0_1_4_0_1 + 0.225749559082895*G0_0_1_5_0_0 - 0.225749559082895*G0_0_1_6_1_0 - 0.225749559082895*G0_0_1_6_1_1 - 0.225749559082893*G0_0_1_8_1_1 - 0.225749559082892*G0_0_1_9_1_0 + 0.225749559082892*G0_0_1_10_1_0 + 0.451499118165788*G0_0_1_10_1_1 + 0.225749559082895*G0_0_1_11_1_0; + A[336] = A[801]; + A[364] = A[132] + 0.338624338624337*G0_0_1_1_0_0 - 0.338624338624339*G0_0_1_2_0_1 - 0.338624338624344*G0_0_1_3_0_0 + 0.338624338624332*G0_0_1_3_0_1 + 0.338624338624344*G0_0_1_4_0_0 + 0.338624338624337*G0_0_1_4_0_1 - 0.33862433862434*G0_0_1_5_0_0 - 0.338624338624332*G0_0_1_5_0_1 + 0.338624338624337*G0_0_1_7_1_0 - 0.338624338624339*G0_0_1_8_1_1 - 0.338624338624344*G0_0_1_9_1_0 + 0.338624338624332*G0_0_1_9_1_1 + 0.338624338624344*G0_0_1_10_1_0 + 0.338624338624337*G0_0_1_10_1_1 - 0.33862433862434*G0_0_1_11_1_0 - 0.338624338624332*G0_0_1_11_1_1 - 0.338624338624337*G0_1_0_1_0_0 + 0.338624338624339*G0_1_0_2_0_1 + 0.338624338624344*G0_1_0_3_0_0 - 0.338624338624332*G0_1_0_3_0_1 - 0.338624338624344*G0_1_0_4_0_0 - 0.338624338624337*G0_1_0_4_0_1 + 0.338624338624339*G0_1_0_5_0_0 + 0.338624338624332*G0_1_0_5_0_1 - 0.338624338624337*G0_1_0_7_1_0 + 0.338624338624339*G0_1_0_8_1_1 + 0.338624338624344*G0_1_0_9_1_0 - 0.338624338624332*G0_1_0_9_1_1 - 0.338624338624344*G0_1_0_10_1_0 - 0.338624338624337*G0_1_0_10_1_1 + 0.338624338624339*G0_1_0_11_1_0 + 0.338624338624332*G0_1_0_11_1_1; + A[687] = A[367] + 0.744973544973547*G0_0_1_0_0_0 + 0.744973544973546*G0_0_1_0_0_1 + 0.541798941798943*G0_0_1_1_0_0 + 0.203174603174604*G0_0_1_2_0_1 + 0.203174603174602*G0_0_1_3_0_0 + 0.541798941798942*G0_0_1_3_0_1 - 0.203174603174602*G0_0_1_4_0_0 - 0.948148148148151*G0_0_1_4_0_1 - 1.28677248677249*G0_0_1_5_0_0 - 0.541798941798942*G0_0_1_5_0_1 + 0.744973544973547*G0_0_1_6_1_0 + 0.744973544973546*G0_0_1_6_1_1 + 0.541798941798943*G0_0_1_7_1_0 + 0.203174603174604*G0_0_1_8_1_1 + 0.203174603174602*G0_0_1_9_1_0 + 0.541798941798942*G0_0_1_9_1_1 - 0.203174603174602*G0_0_1_10_1_0 - 0.948148148148151*G0_0_1_10_1_1 - 1.28677248677249*G0_0_1_11_1_0 - 0.541798941798942*G0_0_1_11_1_1 - 0.744973544973547*G0_1_0_0_0_0 - 0.744973544973547*G0_1_0_0_0_1 - 0.541798941798943*G0_1_0_1_0_0 - 0.203174603174604*G0_1_0_2_0_1 - 0.203174603174603*G0_1_0_3_0_0 - 0.541798941798942*G0_1_0_3_0_1 + 0.203174603174603*G0_1_0_4_0_0 + 0.948148148148151*G0_1_0_4_0_1 + 1.28677248677249*G0_1_0_5_0_0 + 0.541798941798942*G0_1_0_5_0_1 - 0.744973544973547*G0_1_0_6_1_0 - 0.744973544973547*G0_1_0_6_1_1 - 0.541798941798943*G0_1_0_7_1_0 - 0.203174603174604*G0_1_0_8_1_1 - 0.203174603174603*G0_1_0_9_1_0 - 0.541798941798942*G0_1_0_9_1_1 + 0.203174603174603*G0_1_0_10_1_0 + 0.948148148148151*G0_1_0_10_1_1 + 1.28677248677249*G0_1_0_11_1_0 + 0.541798941798942*G0_1_0_11_1_1; + A[779] = A[314]; + A[829] = A[364]; + A[895] = A[314] - 0.338624338624338*G0_0_1_0_0_0 - 0.338624338624338*G0_0_1_0_0_1 - 0.338624338624338*G0_0_1_1_0_0 - 0.338624338624337*G0_0_1_3_0_1 + 0.338624338624337*G0_0_1_4_0_1 + 0.677248677248677*G0_0_1_5_0_0 + 0.338624338624337*G0_0_1_5_0_1 - 0.338624338624338*G0_0_1_6_1_0 - 0.338624338624338*G0_0_1_6_1_1 - 0.338624338624338*G0_0_1_7_1_0 - 0.338624338624337*G0_0_1_9_1_1 + 0.338624338624337*G0_0_1_10_1_1 + 0.677248677248677*G0_0_1_11_1_0 + 0.338624338624337*G0_0_1_11_1_1 + 0.338624338624339*G0_1_0_0_0_0 + 0.338624338624339*G0_1_0_0_0_1 + 0.338624338624338*G0_1_0_1_0_0 + 0.338624338624337*G0_1_0_3_0_1 - 0.338624338624338*G0_1_0_4_0_1 - 0.677248677248677*G0_1_0_5_0_0 - 0.338624338624337*G0_1_0_5_0_1 + 0.338624338624339*G0_1_0_6_1_0 + 0.338624338624339*G0_1_0_6_1_1 + 0.338624338624338*G0_1_0_7_1_0 + 0.338624338624337*G0_1_0_9_1_1 - 0.338624338624338*G0_1_0_10_1_1 - 0.677248677248677*G0_1_0_11_1_0 - 0.338624338624337*G0_1_0_11_1_1; + A[859] = A[394]; + A[222] = A[687]; + A[397] = A[688] + 0.338624338624342*G0_0_1_0_0_0 + 0.338624338624341*G0_0_1_0_0_1 + 0.338624338624338*G0_0_1_2_0_1 + 0.338624338624339*G0_0_1_3_0_0 - 0.338624338624339*G0_0_1_4_0_0 - 0.677248677248679*G0_0_1_4_0_1 - 0.338624338624345*G0_0_1_5_0_0 + 0.338624338624342*G0_0_1_6_1_0 + 0.338624338624341*G0_0_1_6_1_1 + 0.338624338624338*G0_0_1_8_1_1 + 0.338624338624339*G0_0_1_9_1_0 - 0.338624338624339*G0_0_1_10_1_0 - 0.677248677248679*G0_0_1_10_1_1 - 0.338624338624345*G0_0_1_11_1_0 - 0.338624338624341*G0_1_0_0_0_0 - 0.338624338624341*G0_1_0_0_0_1 - 0.338624338624338*G0_1_0_2_0_1 - 0.338624338624339*G0_1_0_3_0_0 + 0.338624338624339*G0_1_0_4_0_0 + 0.677248677248679*G0_1_0_4_0_1 + 0.338624338624345*G0_1_0_5_0_0 - 0.338624338624341*G0_1_0_6_1_0 - 0.338624338624341*G0_1_0_6_1_1 - 0.338624338624338*G0_1_0_8_1_1 - 0.338624338624339*G0_1_0_9_1_0 + 0.338624338624339*G0_1_0_10_1_0 + 0.677248677248679*G0_1_0_10_1_1 + 0.338624338624345*G0_1_0_11_1_0; + A[685] = A[307] - 0.0846560846560828*G0_0_1_0_0_0 - 0.0846560846560827*G0_0_1_0_0_1 - 0.0423280423280417*G0_0_1_1_0_0 - 0.042328042328042*G0_0_1_2_0_1 - 0.0423280423280431*G0_0_1_3_0_0 - 0.0423280423280427*G0_0_1_3_0_1 + 0.0423280423280431*G0_0_1_4_0_0 + 0.126984126984125*G0_0_1_4_0_1 + 0.126984126984124*G0_0_1_5_0_0 + 0.0423280423280426*G0_0_1_5_0_1 - 0.0846560846560828*G0_0_1_6_1_0 - 0.0846560846560827*G0_0_1_6_1_1 - 0.0423280423280417*G0_0_1_7_1_0 - 0.042328042328042*G0_0_1_8_1_1 - 0.0423280423280431*G0_0_1_9_1_0 - 0.0423280423280427*G0_0_1_9_1_1 + 0.0423280423280431*G0_0_1_10_1_0 + 0.126984126984125*G0_0_1_10_1_1 + 0.126984126984124*G0_0_1_11_1_0 + 0.0423280423280426*G0_0_1_11_1_1 + 0.0846560846560828*G0_1_0_0_0_0 + 0.0846560846560827*G0_1_0_0_0_1 + 0.0423280423280417*G0_1_0_1_0_0 + 0.0423280423280421*G0_1_0_2_0_1 + 0.0423280423280431*G0_1_0_3_0_0 + 0.0423280423280427*G0_1_0_3_0_1 - 0.0423280423280431*G0_1_0_4_0_0 - 0.126984126984125*G0_1_0_4_0_1 - 0.126984126984124*G0_1_0_5_0_0 - 0.0423280423280427*G0_1_0_5_0_1 + 0.0846560846560828*G0_1_0_6_1_0 + 0.0846560846560827*G0_1_0_6_1_1 + 0.0423280423280417*G0_1_0_7_1_0 + 0.0423280423280421*G0_1_0_8_1_1 + 0.0423280423280431*G0_1_0_9_1_0 + 0.0423280423280427*G0_1_0_9_1_1 - 0.0423280423280431*G0_1_0_10_1_0 - 0.126984126984125*G0_1_0_10_1_1 - 0.126984126984124*G0_1_0_11_1_0 - 0.0423280423280427*G0_1_0_11_1_1; + A[565] = -A[805] + 1.48430335097002*G0_0_0_0_0_0 + 1.48430335097002*G0_0_0_0_0_1 - 1.46172839506173*G0_0_0_1_0_0 + 1.1005291005291*G0_0_0_2_0_1 - 0.744973544973542*G0_0_0_3_0_0 - 3.30723104056438*G0_0_0_3_0_1 + 0.744973544973542*G0_0_0_4_0_0 - 2.58483245149912*G0_0_0_4_0_1 - 0.0225749559082837*G0_0_0_5_0_0 + 3.30723104056438*G0_0_0_5_0_1 + 1.48430335097002*G0_0_0_6_1_0 + 1.48430335097002*G0_0_0_6_1_1 - 1.46172839506173*G0_0_0_7_1_0 + 1.1005291005291*G0_0_0_8_1_1 - 0.744973544973542*G0_0_0_9_1_0 - 3.30723104056438*G0_0_0_9_1_1 + 0.744973544973542*G0_0_0_10_1_0 - 2.58483245149912*G0_0_0_10_1_1 - 0.0225749559082837*G0_0_0_11_1_0 + 3.30723104056438*G0_0_0_11_1_1 + 0.112874779541445*G0_0_1_0_0_0 + 0.112874779541445*G0_0_1_0_0_1 - 2.06560846560847*G0_0_1_1_0_0 + 1.06102292768959*G0_0_1_2_0_1 - 0.0564373897707211*G0_0_1_3_0_0 - 3.18306878306879*G0_0_1_3_0_1 + 0.0564373897707211*G0_0_1_4_0_0 - 1.17389770723104*G0_0_1_4_0_1 + 1.95273368606702*G0_0_1_5_0_0 + 3.18306878306879*G0_0_1_5_0_1 + 0.112874779541445*G0_0_1_6_1_0 + 0.112874779541445*G0_0_1_6_1_1 - 2.06560846560847*G0_0_1_7_1_0 + 1.06102292768959*G0_0_1_8_1_1 - 0.0564373897707211*G0_0_1_9_1_0 - 3.18306878306879*G0_0_1_9_1_1 + 0.0564373897707211*G0_0_1_10_1_0 - 1.17389770723104*G0_0_1_10_1_1 + 1.95273368606702*G0_0_1_11_1_0 + 3.18306878306879*G0_0_1_11_1_1; + A[718] = A[252] + 1.08359788359789*G0_1_1_0_0_0 + 1.08359788359789*G0_1_1_0_0_1 + 1.08359788359789*G0_1_1_2_0_1 + 1.08359788359789*G0_1_1_3_0_0 - 1.08359788359789*G0_1_1_4_0_0 - 2.16719576719577*G0_1_1_4_0_1 - 1.08359788359789*G0_1_1_5_0_0 + 1.08359788359789*G0_1_1_6_1_0 + 1.08359788359789*G0_1_1_6_1_1 + 1.08359788359789*G0_1_1_8_1_1 + 1.08359788359789*G0_1_1_9_1_0 - 1.08359788359789*G0_1_1_10_1_0 - 2.16719576719577*G0_1_1_10_1_1 - 1.08359788359789*G0_1_1_11_1_0; + A[658] = -A[718] - 0.632098765432097*G0_0_0_0_0_0 - 0.632098765432097*G0_0_0_0_0_1 - 0.0902998236331573*G0_0_0_1_0_0 + 0.270899470899475*G0_0_0_2_0_1 + 1.08359788359789*G0_0_0_3_0_0 + 0.722398589065258*G0_0_0_3_0_1 - 1.08359788359789*G0_0_0_4_0_0 + 0.361199294532622*G0_0_0_4_0_1 + 0.722398589065255*G0_0_0_5_0_0 - 0.722398589065258*G0_0_0_5_0_1 - 0.632098765432097*G0_0_0_6_1_0 - 0.632098765432097*G0_0_0_6_1_1 - 0.0902998236331573*G0_0_0_7_1_0 + 0.270899470899475*G0_0_0_8_1_1 + 1.08359788359789*G0_0_0_9_1_0 + 0.722398589065258*G0_0_0_9_1_1 - 1.08359788359789*G0_0_0_10_1_0 + 0.361199294532622*G0_0_0_10_1_1 + 0.722398589065255*G0_0_0_11_1_0 - 0.722398589065258*G0_0_0_11_1_1 - 0.225749559082888*G0_0_1_0_0_0 - 0.225749559082888*G0_0_1_0_0_1 + 0.406349206349209*G0_0_1_1_0_0 - 0.496649029982357*G0_0_1_2_0_1 - 0.361199294532617*G0_0_1_3_0_0 + 0.54179894179895*G0_0_1_3_0_1 + 0.361199294532617*G0_0_1_4_0_0 + 0.722398589065245*G0_0_1_4_0_1 - 0.180599647266321*G0_0_1_5_0_0 - 0.541798941798949*G0_0_1_5_0_1 - 0.225749559082888*G0_0_1_6_1_0 - 0.225749559082888*G0_0_1_6_1_1 + 0.406349206349209*G0_0_1_7_1_0 - 0.496649029982357*G0_0_1_8_1_1 - 0.361199294532617*G0_0_1_9_1_0 + 0.54179894179895*G0_0_1_9_1_1 + 0.361199294532617*G0_0_1_10_1_0 + 0.722398589065245*G0_0_1_10_1_1 - 0.180599647266321*G0_0_1_11_1_0 - 0.541798941798949*G0_0_1_11_1_1 + 0.135449735449735*G0_1_0_0_0_0 + 0.135449735449736*G0_1_0_0_0_1 + 0.406349206349204*G0_1_0_1_0_0 - 0.135449735449732*G0_1_0_2_0_1 + 0.54179894179894*G0_1_0_3_0_1 - 0.541798941798939*G0_1_0_5_0_0 - 0.54179894179894*G0_1_0_5_0_1 + 0.135449735449735*G0_1_0_6_1_0 + 0.135449735449736*G0_1_0_6_1_1 + 0.406349206349204*G0_1_0_7_1_0 - 0.135449735449732*G0_1_0_8_1_1 + 0.54179894179894*G0_1_0_9_1_1 - 0.541798941798939*G0_1_0_11_1_0 - 0.54179894179894*G0_1_0_11_1_1 + 0.270899470899467*G0_1_1_0_0_0 + 0.270899470899467*G0_1_1_0_0_1 + 0.812698412698412*G0_1_1_1_0_0 - 0.270899470899471*G0_1_1_2_0_1 + 1.08359788359789*G0_1_1_3_0_1 - 1.08359788359788*G0_1_1_5_0_0 - 1.08359788359789*G0_1_1_5_0_1 + 0.270899470899467*G0_1_1_6_1_0 + 0.270899470899467*G0_1_1_6_1_1 + 0.812698412698412*G0_1_1_7_1_0 - 0.270899470899471*G0_1_1_8_1_1 + 1.08359788359789*G0_1_1_9_1_1 - 1.08359788359788*G0_1_1_11_1_0 - 1.08359788359789*G0_1_1_11_1_1; + A[194] = A[658] + 1.08359788359789*G0_0_0_0_0_0 + 1.08359788359789*G0_0_0_0_0_1 + 1.08359788359789*G0_0_0_2_0_1 + 1.08359788359789*G0_0_0_3_0_0 - 1.08359788359789*G0_0_0_4_0_0 - 2.16719576719577*G0_0_0_4_0_1 - 1.08359788359789*G0_0_0_5_0_0 + 1.08359788359789*G0_0_0_6_1_0 + 1.08359788359789*G0_0_0_6_1_1 + 1.08359788359789*G0_0_0_8_1_1 + 1.08359788359789*G0_0_0_9_1_0 - 1.08359788359789*G0_0_0_10_1_0 - 2.16719576719577*G0_0_0_10_1_1 - 1.08359788359789*G0_0_0_11_1_0 + 1.08359788359788*G0_0_1_0_0_0 + 1.08359788359788*G0_0_1_0_0_1 + 1.08359788359788*G0_0_1_2_0_1 + 1.08359788359788*G0_0_1_3_0_0 - 1.08359788359788*G0_0_1_4_0_0 - 2.16719576719576*G0_0_1_4_0_1 - 1.08359788359788*G0_0_1_5_0_0 + 1.08359788359788*G0_0_1_6_1_0 + 1.08359788359788*G0_0_1_6_1_1 + 1.08359788359788*G0_0_1_8_1_1 + 1.08359788359788*G0_0_1_9_1_0 - 1.08359788359788*G0_0_1_10_1_0 - 2.16719576719576*G0_0_1_10_1_1 - 1.08359788359788*G0_0_1_11_1_0 + 1.08359788359789*G0_1_0_0_0_0 + 1.08359788359789*G0_1_0_0_0_1 + 1.08359788359789*G0_1_0_2_0_1 + 1.08359788359789*G0_1_0_3_0_0 - 1.08359788359789*G0_1_0_4_0_0 - 2.16719576719577*G0_1_0_4_0_1 - 1.08359788359789*G0_1_0_5_0_0 + 1.08359788359789*G0_1_0_6_1_0 + 1.08359788359789*G0_1_0_6_1_1 + 1.08359788359789*G0_1_0_8_1_1 + 1.08359788359789*G0_1_0_9_1_0 - 1.08359788359789*G0_1_0_10_1_0 - 2.16719576719577*G0_1_0_10_1_1 - 1.08359788359789*G0_1_0_11_1_0 + 1.08359788359789*G0_1_1_0_0_0 + 1.08359788359789*G0_1_1_0_0_1 + 1.08359788359789*G0_1_1_2_0_1 + 1.08359788359788*G0_1_1_3_0_0 - 1.08359788359788*G0_1_1_4_0_0 - 2.16719576719578*G0_1_1_4_0_1 - 1.08359788359789*G0_1_1_5_0_0 + 1.08359788359789*G0_1_1_6_1_0 + 1.08359788359789*G0_1_1_6_1_1 + 1.08359788359789*G0_1_1_8_1_1 + 1.08359788359788*G0_1_1_9_1_0 - 1.08359788359788*G0_1_1_10_1_0 - 2.16719576719578*G0_1_1_10_1_1 - 1.08359788359789*G0_1_1_11_1_0; + A[396] = A[658] + 0.0902998236331533*G0_0_1_0_0_0 + 0.0902998236331534*G0_0_1_0_0_1 - 0.180599647266319*G0_0_1_1_0_0 + 0.270899470899471*G0_0_1_2_0_1 + 0.270899470899469*G0_0_1_3_0_0 - 0.18059964726632*G0_0_1_3_0_1 - 0.270899470899469*G0_0_1_4_0_0 - 0.361199294532624*G0_0_1_4_0_1 + 0.0902998236331657*G0_0_1_5_0_0 + 0.18059964726632*G0_0_1_5_0_1 + 0.0902998236331533*G0_0_1_6_1_0 + 0.0902998236331534*G0_0_1_6_1_1 - 0.180599647266319*G0_0_1_7_1_0 + 0.270899470899471*G0_0_1_8_1_1 + 0.270899470899469*G0_0_1_9_1_0 - 0.18059964726632*G0_0_1_9_1_1 - 0.270899470899469*G0_0_1_10_1_0 - 0.361199294532624*G0_0_1_10_1_1 + 0.0902998236331657*G0_0_1_11_1_0 + 0.18059964726632*G0_0_1_11_1_1 - 0.0902998236331533*G0_1_0_0_0_0 - 0.0902998236331534*G0_1_0_0_0_1 + 0.180599647266319*G0_1_0_1_0_0 - 0.270899470899471*G0_1_0_2_0_1 - 0.270899470899469*G0_1_0_3_0_0 + 0.180599647266321*G0_1_0_3_0_1 + 0.270899470899469*G0_1_0_4_0_0 + 0.361199294532624*G0_1_0_4_0_1 - 0.0902998236331655*G0_1_0_5_0_0 - 0.18059964726632*G0_1_0_5_0_1 - 0.0902998236331533*G0_1_0_6_1_0 - 0.0902998236331534*G0_1_0_6_1_1 + 0.180599647266319*G0_1_0_7_1_0 - 0.270899470899471*G0_1_0_8_1_1 - 0.270899470899469*G0_1_0_9_1_0 + 0.180599647266321*G0_1_0_9_1_1 + 0.270899470899469*G0_1_0_10_1_0 + 0.361199294532624*G0_1_0_10_1_1 - 0.0902998236331655*G0_1_0_11_1_0 - 0.18059964726632*G0_1_0_11_1_1; + A[192] = A[658] + 3.25079365079365*G0_0_0_0_0_0 + 3.25079365079365*G0_0_0_0_0_1 + 1.08359788359788*G0_0_0_1_0_0 - 1.08359788359789*G0_0_0_2_0_1 - 4.33439153439153*G0_0_0_3_0_0 - 2.16719576719577*G0_0_0_3_0_1 + 4.33439153439153*G0_0_0_4_0_0 - 2.16719576719576*G0_0_0_4_0_1 - 4.33439153439153*G0_0_0_5_0_0 + 2.16719576719577*G0_0_0_5_0_1 + 3.25079365079365*G0_0_0_6_1_0 + 3.25079365079365*G0_0_0_6_1_1 + 1.08359788359788*G0_0_0_7_1_0 - 1.08359788359789*G0_0_0_8_1_1 - 4.33439153439153*G0_0_0_9_1_0 - 2.16719576719577*G0_0_0_9_1_1 + 4.33439153439153*G0_0_0_10_1_0 - 2.16719576719576*G0_0_0_10_1_1 - 4.33439153439153*G0_0_0_11_1_0 + 2.16719576719577*G0_0_0_11_1_1 + 0.541798941798936*G0_0_1_0_0_0 + 0.541798941798935*G0_0_1_0_0_1 - 0.541798941798945*G0_0_1_1_0_0 - 0.541798941798945*G0_0_1_2_0_1 - 2.16719576719577*G0_0_1_3_0_0 - 2.16719576719577*G0_0_1_3_0_1 + 2.16719576719577*G0_0_1_4_0_0 + 2.16719576719577*G0_0_1_5_0_1 + 0.541798941798936*G0_0_1_6_1_0 + 0.541798941798935*G0_0_1_6_1_1 - 0.541798941798945*G0_0_1_7_1_0 - 0.541798941798945*G0_0_1_8_1_1 - 2.16719576719577*G0_0_1_9_1_0 - 2.16719576719577*G0_0_1_9_1_1 + 2.16719576719577*G0_0_1_10_1_0 + 2.16719576719577*G0_0_1_11_1_1 - 1.62539682539682*G0_1_0_2_0_1 - 3.25079365079365*G0_1_0_3_0_0 - 1.62539682539682*G0_1_0_3_0_1 + 3.25079365079365*G0_1_0_4_0_0 + 1.62539682539682*G0_1_0_4_0_1 + 1.62539682539682*G0_1_0_5_0_1 - 1.62539682539682*G0_1_0_8_1_1 - 3.25079365079365*G0_1_0_9_1_0 - 1.62539682539682*G0_1_0_9_1_1 + 3.25079365079365*G0_1_0_10_1_0 + 1.62539682539682*G0_1_0_10_1_1 + 1.62539682539682*G0_1_0_11_1_1 - 2.7089947089947*G0_1_1_0_0_0 - 2.7089947089947*G0_1_1_0_0_1 - 1.08359788359788*G0_1_1_1_0_0 - 1.62539682539682*G0_1_1_2_0_1 - 1.62539682539683*G0_1_1_3_0_0 - 1.08359788359788*G0_1_1_3_0_1 + 1.62539682539683*G0_1_1_4_0_0 + 4.33439153439153*G0_1_1_4_0_1 + 3.79259259259258*G0_1_1_5_0_0 + 1.08359788359788*G0_1_1_5_0_1 - 2.7089947089947*G0_1_1_6_1_0 - 2.7089947089947*G0_1_1_6_1_1 - 1.08359788359788*G0_1_1_7_1_0 - 1.62539682539682*G0_1_1_8_1_1 - 1.62539682539683*G0_1_1_9_1_0 - 1.08359788359788*G0_1_1_9_1_1 + 1.62539682539683*G0_1_1_10_1_0 + 4.33439153439153*G0_1_1_10_1_1 + 3.79259259259258*G0_1_1_11_1_0 + 1.08359788359788*G0_1_1_11_1_1; + A[567] = A[658] + 0.541798941798941*G0_0_0_0_0_0 + 0.541798941798941*G0_0_0_0_0_1 + 0.541798941798939*G0_0_0_1_0_0 + 0.541798941798936*G0_0_0_3_0_1 - 0.54179894179894*G0_0_0_4_0_1 - 1.08359788359788*G0_0_0_5_0_0 - 0.541798941798936*G0_0_0_5_0_1 + 0.541798941798941*G0_0_0_6_1_0 + 0.541798941798941*G0_0_0_6_1_1 + 0.541798941798939*G0_0_0_7_1_0 + 0.541798941798936*G0_0_0_9_1_1 - 0.54179894179894*G0_0_0_10_1_1 - 1.08359788359788*G0_0_0_11_1_0 - 0.541798941798936*G0_0_0_11_1_1 + 0.406349206349203*G0_0_1_0_0_0 + 0.406349206349203*G0_0_1_0_0_1 + 0.135449735449732*G0_0_1_1_0_0 + 0.135449735449735*G0_0_1_2_0_1 - 0.541798941798938*G0_0_1_4_0_1 - 0.541798941798935*G0_0_1_5_0_0 + 0.406349206349203*G0_0_1_6_1_0 + 0.406349206349203*G0_0_1_6_1_1 + 0.135449735449732*G0_0_1_7_1_0 + 0.135449735449735*G0_0_1_8_1_1 - 0.541798941798938*G0_0_1_10_1_1 - 0.541798941798935*G0_0_1_11_1_0 + 0.135449735449735*G0_1_0_0_0_0 + 0.135449735449735*G0_1_0_0_0_1 + 0.406349206349208*G0_1_0_1_0_0 - 0.406349206349207*G0_1_0_2_0_1 - 0.541798941798941*G0_1_0_3_0_0 + 0.270899470899475*G0_1_0_3_0_1 + 0.541798941798941*G0_1_0_4_0_0 + 0.270899470899472*G0_1_0_4_0_1 - 0.541798941798943*G0_1_0_5_0_0 - 0.270899470899475*G0_1_0_5_0_1 + 0.135449735449735*G0_1_0_6_1_0 + 0.135449735449735*G0_1_0_6_1_1 + 0.406349206349208*G0_1_0_7_1_0 - 0.406349206349207*G0_1_0_8_1_1 - 0.541798941798941*G0_1_0_9_1_0 + 0.270899470899475*G0_1_0_9_1_1 + 0.541798941798941*G0_1_0_10_1_0 + 0.270899470899472*G0_1_0_10_1_1 - 0.541798941798943*G0_1_0_11_1_0 - 0.270899470899475*G0_1_0_11_1_1 - 0.406349206349202*G0_1_1_0_0_0 - 0.406349206349202*G0_1_1_0_0_1 - 0.406349206349203*G0_1_1_1_0_0 - 0.135449735449735*G0_1_1_2_0_1 - 0.27089947089947*G0_1_1_3_0_0 - 0.541798941798938*G0_1_1_3_0_1 + 0.27089947089947*G0_1_1_4_0_0 + 0.541798941798937*G0_1_1_4_0_1 + 0.812698412698406*G0_1_1_5_0_0 + 0.541798941798939*G0_1_1_5_0_1 - 0.406349206349202*G0_1_1_6_1_0 - 0.406349206349202*G0_1_1_6_1_1 - 0.406349206349203*G0_1_1_7_1_0 - 0.135449735449735*G0_1_1_8_1_1 - 0.27089947089947*G0_1_1_9_1_0 - 0.541798941798938*G0_1_1_9_1_1 + 0.27089947089947*G0_1_1_10_1_0 + 0.541798941798937*G0_1_1_10_1_1 + 0.812698412698406*G0_1_1_11_1_0 + 0.541798941798939*G0_1_1_11_1_1; + A[569] = A[567] - 1.08359788359788*G0_0_0_1_0_0 + 1.08359788359788*G0_0_0_2_0_1 + 1.08359788359788*G0_0_0_3_0_0 - 1.08359788359788*G0_0_0_3_0_1 - 1.08359788359788*G0_0_0_4_0_0 - 1.08359788359788*G0_0_0_4_0_1 + 1.08359788359788*G0_0_0_5_0_0 + 1.08359788359788*G0_0_0_5_0_1 - 1.08359788359788*G0_0_0_7_1_0 + 1.08359788359788*G0_0_0_8_1_1 + 1.08359788359788*G0_0_0_9_1_0 - 1.08359788359788*G0_0_0_9_1_1 - 1.08359788359788*G0_0_0_10_1_0 - 1.08359788359788*G0_0_0_10_1_1 + 1.08359788359788*G0_0_0_11_1_0 + 1.08359788359788*G0_0_0_11_1_1; + A[659] = A[194]; + A[342] = -A[567] - 1.30934744268077*G0_0_0_0_0_0 - 1.30934744268077*G0_0_0_0_0_1 - 1.03844797178131*G0_0_0_1_0_0 + 0.677248677248678*G0_0_0_2_0_1 + 1.62539682539682*G0_0_0_3_0_0 - 0.0902998236331614*G0_0_0_3_0_1 - 1.62539682539682*G0_0_0_4_0_0 + 0.632098765432095*G0_0_0_4_0_1 + 2.34779541446208*G0_0_0_5_0_0 + 0.090299823633162*G0_0_0_5_0_1 - 1.30934744268077*G0_0_0_6_1_0 - 1.30934744268077*G0_0_0_6_1_1 - 1.03844797178131*G0_0_0_7_1_0 + 0.677248677248678*G0_0_0_8_1_1 + 1.62539682539682*G0_0_0_9_1_0 - 0.0902998236331614*G0_0_0_9_1_1 - 1.62539682539682*G0_0_0_10_1_0 + 0.632098765432095*G0_0_0_10_1_1 + 2.34779541446208*G0_0_0_11_1_0 + 0.090299823633162*G0_0_0_11_1_1 + 0.451499118165783*G0_0_1_0_0_0 + 0.451499118165784*G0_0_1_0_0_1 + 0.451499118165785*G0_0_1_2_0_1 + 0.451499118165786*G0_0_1_3_0_0 - 0.451499118165786*G0_0_1_4_0_0 - 0.902998236331569*G0_0_1_4_0_1 - 0.451499118165783*G0_0_1_5_0_0 + 0.451499118165783*G0_0_1_6_1_0 + 0.451499118165784*G0_0_1_6_1_1 + 0.451499118165785*G0_0_1_8_1_1 + 0.451499118165786*G0_0_1_9_1_0 - 0.451499118165786*G0_0_1_10_1_0 - 0.902998236331569*G0_0_1_10_1_1 - 0.451499118165783*G0_0_1_11_1_0; + A[401] = -A[342] + 0.0902998236331567*G0_0_0_0_0_0 + 0.0902998236331569*G0_0_0_0_0_1 + 0.632098765432095*G0_0_0_1_0_0 - 0.270899470899469*G0_0_0_2_0_1 + 0.902998236331563*G0_0_0_3_0_1 + 0.180599647266313*G0_0_0_4_0_1 - 0.722398589065252*G0_0_0_5_0_0 - 0.902998236331563*G0_0_0_5_0_1 + 0.0902998236331567*G0_0_0_6_1_0 + 0.0902998236331569*G0_0_0_6_1_1 + 0.632098765432095*G0_0_0_7_1_0 - 0.270899470899469*G0_0_0_8_1_1 + 0.902998236331563*G0_0_0_9_1_1 + 0.180599647266313*G0_0_0_10_1_1 - 0.722398589065252*G0_0_0_11_1_0 - 0.902998236331563*G0_0_0_11_1_1 + 1.0384479717813*G0_0_1_0_0_0 + 1.0384479717813*G0_0_1_0_0_1 + 2.21234567901234*G0_0_1_1_0_0 - 0.225749559082891*G0_0_1_2_0_1 + 0.722398589065255*G0_0_1_3_0_0 + 3.16049382716048*G0_0_1_3_0_1 - 0.722398589065255*G0_0_1_4_0_0 - 0.81269841269841*G0_0_1_4_0_1 - 3.25079365079364*G0_0_1_5_0_0 - 3.16049382716049*G0_0_1_5_0_1 + 1.0384479717813*G0_0_1_6_1_0 + 1.0384479717813*G0_0_1_6_1_1 + 2.21234567901234*G0_0_1_7_1_0 - 0.225749559082891*G0_0_1_8_1_1 + 0.722398589065255*G0_0_1_9_1_0 + 3.16049382716048*G0_0_1_9_1_1 - 0.722398589065255*G0_0_1_10_1_0 - 0.81269841269841*G0_0_1_10_1_1 - 3.25079365079364*G0_0_1_11_1_0 - 3.16049382716049*G0_0_1_11_1_1 - 0.0451499118165792*G0_1_0_0_0_0 - 0.0451499118165792*G0_1_0_0_0_1 + 1.6705467372134*G0_1_0_1_0_0 - 0.767548500881835*G0_1_0_2_0_1 + 0.180599647266309*G0_1_0_3_0_0 + 2.61869488536155*G0_1_0_3_0_1 - 0.180599647266309*G0_1_0_4_0_0 + 0.812698412698416*G0_1_0_4_0_1 - 1.62539682539682*G0_1_0_5_0_0 - 2.61869488536155*G0_1_0_5_0_1 - 0.0451499118165792*G0_1_0_6_1_0 - 0.0451499118165792*G0_1_0_6_1_1 + 1.6705467372134*G0_1_0_7_1_0 - 0.767548500881835*G0_1_0_8_1_1 + 0.180599647266309*G0_1_0_9_1_0 + 2.61869488536155*G0_1_0_9_1_1 - 0.180599647266309*G0_1_0_10_1_0 + 0.812698412698416*G0_1_0_10_1_1 - 1.62539682539682*G0_1_0_11_1_0 - 2.61869488536155*G0_1_0_11_1_1 + 0.361199294532627*G0_1_1_0_0_0 + 0.361199294532627*G0_1_1_0_0_1 + 0.361199294532628*G0_1_1_2_0_1 + 0.361199294532626*G0_1_1_3_0_0 - 0.361199294532626*G0_1_1_4_0_0 - 0.722398589065255*G0_1_1_4_0_1 - 0.361199294532624*G0_1_1_5_0_0 + 0.361199294532627*G0_1_1_6_1_0 + 0.361199294532627*G0_1_1_6_1_1 + 0.361199294532628*G0_1_1_8_1_1 + 0.361199294532626*G0_1_1_9_1_0 - 0.361199294532626*G0_1_1_10_1_0 - 0.722398589065255*G0_1_1_10_1_1 - 0.361199294532624*G0_1_1_11_1_0; + A[866] = A[401]; + A[836] = A[342] - 0.27089947089947*G0_0_1_0_0_0 - 0.27089947089947*G0_0_1_0_0_1 - 0.0902998236331571*G0_0_1_1_0_0 - 0.180599647266314*G0_0_1_2_0_1 - 0.180599647266316*G0_0_1_3_0_0 - 0.0902998236331589*G0_0_1_3_0_1 + 0.180599647266316*G0_0_1_4_0_0 + 0.451499118165784*G0_0_1_4_0_1 + 0.361199294532627*G0_0_1_5_0_0 + 0.0902998236331591*G0_0_1_5_0_1 - 0.27089947089947*G0_0_1_6_1_0 - 0.27089947089947*G0_0_1_6_1_1 - 0.0902998236331571*G0_0_1_7_1_0 - 0.180599647266314*G0_0_1_8_1_1 - 0.180599647266316*G0_0_1_9_1_0 - 0.0902998236331589*G0_0_1_9_1_1 + 0.180599647266316*G0_0_1_10_1_0 + 0.451499118165784*G0_0_1_10_1_1 + 0.361199294532627*G0_0_1_11_1_0 + 0.0902998236331591*G0_0_1_11_1_1 + 0.27089947089947*G0_1_0_0_0_0 + 0.27089947089947*G0_1_0_0_0_1 + 0.0902998236331571*G0_1_0_1_0_0 + 0.180599647266314*G0_1_0_2_0_1 + 0.180599647266316*G0_1_0_3_0_0 + 0.090299823633159*G0_1_0_3_0_1 - 0.180599647266316*G0_1_0_4_0_0 - 0.451499118165784*G0_1_0_4_0_1 - 0.361199294532626*G0_1_0_5_0_0 - 0.0902998236331591*G0_1_0_5_0_1 + 0.27089947089947*G0_1_0_6_1_0 + 0.27089947089947*G0_1_0_6_1_1 + 0.0902998236331571*G0_1_0_7_1_0 + 0.180599647266314*G0_1_0_8_1_1 + 0.180599647266316*G0_1_0_9_1_0 + 0.090299823633159*G0_1_0_9_1_1 - 0.180599647266316*G0_1_0_10_1_0 - 0.451499118165784*G0_1_0_10_1_1 - 0.361199294532626*G0_1_0_11_1_0 - 0.0902998236331591*G0_1_0_11_1_1; + A[363] = -A[836] - 1.30934744268077*G0_0_0_0_0_0 - 1.30934744268077*G0_0_0_0_0_1 - 1.03844797178131*G0_0_0_1_0_0 + 0.677248677248678*G0_0_0_2_0_1 + 1.62539682539682*G0_0_0_3_0_0 - 0.0902998236331611*G0_0_0_3_0_1 - 1.62539682539682*G0_0_0_4_0_0 + 0.632098765432095*G0_0_0_4_0_1 + 2.34779541446208*G0_0_0_5_0_0 + 0.0902998236331618*G0_0_0_5_0_1 - 1.30934744268077*G0_0_0_6_1_0 - 1.30934744268077*G0_0_0_6_1_1 - 1.03844797178131*G0_0_0_7_1_0 + 0.677248677248678*G0_0_0_8_1_1 + 1.62539682539682*G0_0_0_9_1_0 - 0.0902998236331611*G0_0_0_9_1_1 - 1.62539682539682*G0_0_0_10_1_0 + 0.632098765432095*G0_0_0_10_1_1 + 2.34779541446208*G0_0_0_11_1_0 + 0.0902998236331618*G0_0_0_11_1_1 + 0.451499118165783*G0_1_0_0_0_0 + 0.451499118165784*G0_1_0_0_0_1 + 0.451499118165785*G0_1_0_2_0_1 + 0.451499118165786*G0_1_0_3_0_0 - 0.451499118165786*G0_1_0_4_0_0 - 0.902998236331568*G0_1_0_4_0_1 - 0.451499118165783*G0_1_0_5_0_0 + 0.451499118165783*G0_1_0_6_1_0 + 0.451499118165784*G0_1_0_6_1_1 + 0.451499118165785*G0_1_0_8_1_1 + 0.451499118165786*G0_1_0_9_1_0 - 0.451499118165786*G0_1_0_10_1_0 - 0.902998236331568*G0_1_0_10_1_1 - 0.451499118165783*G0_1_0_11_1_0; + A[888] = A[363] - 1.08359788359788*G0_0_0_1_0_0 + 1.08359788359788*G0_0_0_2_0_1 + 1.08359788359788*G0_0_0_3_0_0 - 1.08359788359788*G0_0_0_3_0_1 - 1.08359788359788*G0_0_0_4_0_0 - 1.08359788359788*G0_0_0_4_0_1 + 1.08359788359788*G0_0_0_5_0_0 + 1.08359788359788*G0_0_0_5_0_1 - 1.08359788359788*G0_0_0_7_1_0 + 1.08359788359788*G0_0_0_8_1_1 + 1.08359788359788*G0_0_0_9_1_0 - 1.08359788359788*G0_0_0_9_1_1 - 1.08359788359788*G0_0_0_10_1_0 - 1.08359788359788*G0_0_0_10_1_1 + 1.08359788359788*G0_0_0_11_1_0 + 1.08359788359788*G0_0_0_11_1_1; + A[431] = A[836] + 1.08359788359788*G0_0_0_0_0_0 + 1.08359788359788*G0_0_0_0_0_1 + 1.08359788359788*G0_0_0_1_0_0 + 1.08359788359788*G0_0_0_3_0_1 - 1.08359788359788*G0_0_0_4_0_1 - 2.16719576719576*G0_0_0_5_0_0 - 1.08359788359788*G0_0_0_5_0_1 + 1.08359788359788*G0_0_0_6_1_0 + 1.08359788359788*G0_0_0_6_1_1 + 1.08359788359788*G0_0_0_7_1_0 + 1.08359788359788*G0_0_0_9_1_1 - 1.08359788359788*G0_0_0_10_1_1 - 2.16719576719576*G0_0_0_11_1_0 - 1.08359788359788*G0_0_0_11_1_1; + A[366] = A[192] - 0.451499118165778*G0_0_1_0_0_0 - 0.451499118165778*G0_0_1_0_0_1 + 0.36119929453263*G0_0_1_1_0_0 - 0.81269841269841*G0_0_1_2_0_1 - 0.812698412698412*G0_0_1_3_0_0 + 0.361199294532628*G0_0_1_3_0_1 + 0.812698412698412*G0_0_1_4_0_0 + 1.26419753086419*G0_0_1_4_0_1 + 0.0902998236331471*G0_0_1_5_0_0 - 0.361199294532628*G0_0_1_5_0_1 - 0.451499118165778*G0_0_1_6_1_0 - 0.451499118165778*G0_0_1_6_1_1 + 0.36119929453263*G0_0_1_7_1_0 - 0.81269841269841*G0_0_1_8_1_1 - 0.812698412698412*G0_0_1_9_1_0 + 0.361199294532628*G0_0_1_9_1_1 + 0.812698412698412*G0_0_1_10_1_0 + 1.26419753086419*G0_0_1_10_1_1 + 0.0902998236331471*G0_0_1_11_1_0 - 0.361199294532628*G0_0_1_11_1_1 + 0.451499118165778*G0_1_0_0_0_0 + 0.451499118165778*G0_1_0_0_0_1 - 0.36119929453263*G0_1_0_1_0_0 + 0.81269841269841*G0_1_0_2_0_1 + 0.812698412698412*G0_1_0_3_0_0 - 0.361199294532628*G0_1_0_3_0_1 - 0.812698412698412*G0_1_0_4_0_0 - 1.26419753086419*G0_1_0_4_0_1 - 0.090299823633147*G0_1_0_5_0_0 + 0.361199294532628*G0_1_0_5_0_1 + 0.451499118165778*G0_1_0_6_1_0 + 0.451499118165778*G0_1_0_6_1_1 - 0.36119929453263*G0_1_0_7_1_0 + 0.81269841269841*G0_1_0_8_1_1 + 0.812698412698412*G0_1_0_9_1_0 - 0.361199294532628*G0_1_0_9_1_1 - 0.812698412698412*G0_1_0_10_1_0 - 1.26419753086419*G0_1_0_10_1_1 - 0.090299823633147*G0_1_0_11_1_0 + 0.361199294532628*G0_1_0_11_1_1; + A[441] = 0.0; + A[329] = 0.0; + A[390] = A[855]; + A[346] = 0.0; + A[27] = 0.0; + A[728] = 0.0; + A[387] = 0.0; + A[831] = A[366]; + A[56] = 0.0; + A[755] = 0.0; + A[416] = 0.0; + A[862] = A[397]; + A[61] = -0.0361552028218697*G0_1_0_0_0_0 - 0.0361552028218697*G0_1_0_0_0_1 - 0.0463844797178135*G0_1_0_1_0_0 - 0.0463844797178129*G0_1_0_2_0_1 - 0.102998236331569*G0_1_0_3_0_0 - 0.10299823633157*G0_1_0_3_0_1 + 0.102998236331569*G0_1_0_4_0_0 + 0.0825396825396824*G0_1_0_4_0_1 + 0.0825396825396832*G0_1_0_5_0_0 + 0.10299823633157*G0_1_0_5_0_1 - 0.0361552028218697*G0_1_0_6_1_0 - 0.0361552028218697*G0_1_0_6_1_1 - 0.0463844797178135*G0_1_0_7_1_0 - 0.0463844797178129*G0_1_0_8_1_1 - 0.102998236331569*G0_1_0_9_1_0 - 0.10299823633157*G0_1_0_9_1_1 + 0.102998236331569*G0_1_0_10_1_0 + 0.0825396825396824*G0_1_0_10_1_1 + 0.0825396825396832*G0_1_0_11_1_0 + 0.10299823633157*G0_1_0_11_1_1; + A[466] = -A[61] - 0.0463844797178132*G0_0_0_0_0_0 - 0.0463844797178131*G0_0_0_0_0_1 + 0.0463844797178131*G0_0_0_1_0_0 - 0.0361552028218696*G0_0_0_2_0_1 + 0.020458553791887*G0_0_0_3_0_0 + 0.10299823633157*G0_0_0_3_0_1 - 0.020458553791887*G0_0_0_4_0_0 + 0.0825396825396828*G0_0_0_4_0_1 - 0.10299823633157*G0_0_0_5_0_1 - 0.0463844797178132*G0_0_0_6_1_0 - 0.0463844797178131*G0_0_0_6_1_1 + 0.0463844797178131*G0_0_0_7_1_0 - 0.0361552028218696*G0_0_0_8_1_1 + 0.020458553791887*G0_0_0_9_1_0 + 0.10299823633157*G0_0_0_9_1_1 - 0.020458553791887*G0_0_0_10_1_0 + 0.0825396825396828*G0_0_0_10_1_1 - 0.10299823633157*G0_0_0_11_1_1 - 0.0825396825396829*G0_1_0_0_0_0 - 0.0825396825396829*G0_1_0_0_0_1 - 0.0825396825396824*G0_1_0_2_0_1 - 0.0825396825396826*G0_1_0_3_0_0 + 0.0825396825396826*G0_1_0_4_0_0 + 0.165079365079365*G0_1_0_4_0_1 + 0.0825396825396835*G0_1_0_5_0_0 - 0.0825396825396829*G0_1_0_6_1_0 - 0.0825396825396829*G0_1_0_6_1_1 - 0.0825396825396824*G0_1_0_8_1_1 - 0.0825396825396826*G0_1_0_9_1_0 + 0.0825396825396826*G0_1_0_10_1_0 + 0.165079365079365*G0_1_0_10_1_1 + 0.0825396825396835*G0_1_0_11_1_0; + A[782] = 0.0; + A[893] = A[428]; + A[118] = 0.0; + A[821] = 0.0; + A[852] = 0.0; + A[212] = A[677]; + A[626] = A[161]; + A[490] = 0.0; + A[209] = 0.0; + A[657] = A[192]; + A[577] = 0.0; + A[521] = 0.0; + A[234] = 0.0; + A[676] = A[502] - 0.020458553791886*G0_0_1_0_0_0 - 0.020458553791886*G0_0_1_0_0_1 - 0.0204585537918872*G0_0_1_2_0_1 - 0.0204585537918866*G0_0_1_3_0_0 + 0.0204585537918866*G0_0_1_4_0_0 + 0.0409171075837732*G0_0_1_4_0_1 + 0.0204585537918842*G0_0_1_5_0_0 - 0.020458553791886*G0_0_1_6_1_0 - 0.020458553791886*G0_0_1_6_1_1 - 0.0204585537918872*G0_0_1_8_1_1 - 0.0204585537918866*G0_0_1_9_1_0 + 0.0204585537918866*G0_0_1_10_1_0 + 0.0409171075837732*G0_0_1_10_1_1 + 0.0204585537918842*G0_0_1_11_1_0 + 0.020458553791886*G0_1_0_0_0_0 + 0.020458553791886*G0_1_0_0_0_1 + 0.0204585537918872*G0_1_0_2_0_1 + 0.0204585537918866*G0_1_0_3_0_0 - 0.0204585537918866*G0_1_0_4_0_0 - 0.0409171075837732*G0_1_0_4_0_1 - 0.0204585537918842*G0_1_0_5_0_0 + 0.020458553791886*G0_1_0_6_1_0 + 0.020458553791886*G0_1_0_6_1_1 + 0.0204585537918872*G0_1_0_8_1_1 + 0.0204585537918866*G0_1_0_9_1_0 - 0.0204585537918866*G0_1_0_10_1_0 - 0.0409171075837732*G0_1_0_10_1_1 - 0.0204585537918842*G0_1_0_11_1_0; + A[600] = 0.0; + A[556] = A[91]; + A[711] = -A[621] - 0.406349206349206*G0_1_0_0_0_0 - 0.406349206349206*G0_1_0_0_0_1 - 0.496649029982362*G0_1_0_1_0_0 + 0.632098765432099*G0_1_0_2_0_1 + 1.17389770723104*G0_1_0_3_0_0 + 0.0451499118165802*G0_1_0_3_0_1 - 1.17389770723104*G0_1_0_4_0_0 - 0.225749559082892*G0_1_0_4_0_1 + 0.902998236331569*G0_1_0_5_0_0 - 0.0451499118165802*G0_1_0_5_0_1 - 0.406349206349206*G0_1_0_6_1_0 - 0.406349206349206*G0_1_0_6_1_1 - 0.496649029982362*G0_1_0_7_1_0 + 0.632098765432099*G0_1_0_8_1_1 + 1.17389770723104*G0_1_0_9_1_0 + 0.0451499118165802*G0_1_0_9_1_1 - 1.17389770723104*G0_1_0_10_1_0 - 0.225749559082892*G0_1_0_10_1_1 + 0.902998236331569*G0_1_0_11_1_0 - 0.0451499118165802*G0_1_0_11_1_1 - 1.24162257495591*G0_1_1_0_0_0 - 1.24162257495591*G0_1_1_0_0_1 - 0.609523809523809*G0_1_1_1_0_0 + 0.248324514991183*G0_1_1_2_0_1 + 1.12874779541446*G0_1_1_3_0_0 + 0.270899470899472*G0_1_1_3_0_1 - 1.12874779541446*G0_1_1_4_0_0 + 0.993298059964722*G0_1_1_4_0_1 + 1.85114638447971*G0_1_1_5_0_0 - 0.270899470899472*G0_1_1_5_0_1 - 1.24162257495591*G0_1_1_6_1_0 - 1.24162257495591*G0_1_1_6_1_1 - 0.609523809523809*G0_1_1_7_1_0 + 0.248324514991183*G0_1_1_8_1_1 + 1.12874779541446*G0_1_1_9_1_0 + 0.270899470899472*G0_1_1_9_1_1 - 1.12874779541446*G0_1_1_10_1_0 + 0.993298059964722*G0_1_1_10_1_1 + 1.85114638447971*G0_1_1_11_1_0 - 0.270899470899472*G0_1_1_11_1_1; + A[245] = -A[711] - 1.12874779541446*G0_0_0_0_0_0 - 1.12874779541446*G0_0_0_0_0_1 + 1.30934744268078*G0_0_0_1_0_0 - 4.1989417989418*G0_0_0_2_0_1 - 5.95978835978835*G0_0_0_3_0_0 - 0.451499118165782*G0_0_0_3_0_1 + 5.95978835978835*G0_0_0_4_0_0 + 5.32768959435626*G0_0_0_4_0_1 - 0.180599647266314*G0_0_0_5_0_0 + 0.451499118165783*G0_0_0_5_0_1 - 1.12874779541446*G0_0_0_6_1_0 - 1.12874779541446*G0_0_0_6_1_1 + 1.30934744268078*G0_0_0_7_1_0 - 4.1989417989418*G0_0_0_8_1_1 - 5.95978835978835*G0_0_0_9_1_0 - 0.451499118165782*G0_0_0_9_1_1 + 5.95978835978835*G0_0_0_10_1_0 + 5.32768959435626*G0_0_0_10_1_1 - 0.180599647266314*G0_0_0_11_1_0 + 0.451499118165783*G0_0_0_11_1_1 - 0.316049382716049*G0_0_1_0_0_0 - 0.316049382716049*G0_0_1_0_0_1 + 0.31604938271605*G0_0_1_1_0_0 - 1.44479717813051*G0_0_1_2_0_1 - 2.25749559082892*G0_0_1_3_0_0 - 0.496649029982361*G0_0_1_3_0_1 + 2.25749559082892*G0_0_1_4_0_0 + 1.76084656084656*G0_0_1_4_0_1 + 0.496649029982362*G0_0_1_5_0_1 - 0.316049382716049*G0_0_1_6_1_0 - 0.316049382716049*G0_0_1_6_1_1 + 0.31604938271605*G0_0_1_7_1_0 - 1.44479717813051*G0_0_1_8_1_1 - 2.25749559082892*G0_0_1_9_1_0 - 0.496649029982361*G0_0_1_9_1_1 + 2.25749559082892*G0_0_1_10_1_0 + 1.76084656084656*G0_0_1_10_1_1 + 0.496649029982362*G0_0_1_11_1_1 - 1.08359788359789*G0_1_0_0_0_0 - 1.08359788359788*G0_1_0_0_0_1 + 0.270899470899471*G0_1_0_1_0_0 - 1.62539682539683*G0_1_0_2_0_1 - 1.8962962962963*G0_1_0_3_0_0 + 1.8962962962963*G0_1_0_4_0_0 + 2.70899470899471*G0_1_0_4_0_1 + 0.812698412698414*G0_1_0_5_0_0 - 1.08359788359789*G0_1_0_6_1_0 - 1.08359788359788*G0_1_0_6_1_1 + 0.270899470899471*G0_1_0_7_1_0 - 1.62539682539683*G0_1_0_8_1_1 - 1.8962962962963*G0_1_0_9_1_0 + 1.8962962962963*G0_1_0_10_1_0 + 2.70899470899471*G0_1_0_10_1_1 + 0.812698412698414*G0_1_0_11_1_0 - 1.42222222222222*G0_1_1_0_0_0 - 1.42222222222222*G0_1_1_0_0_1 - 0.248324514991181*G0_1_1_1_0_0 - 0.293474426807759*G0_1_1_2_0_1 + 0.586948853615522*G0_1_1_3_0_0 + 0.6320987654321*G0_1_1_3_0_1 - 0.586948853615522*G0_1_1_4_0_0 + 1.71569664902998*G0_1_1_4_0_1 + 1.6705467372134*G0_1_1_5_0_0 - 0.6320987654321*G0_1_1_5_0_1 - 1.42222222222222*G0_1_1_6_1_0 - 1.42222222222222*G0_1_1_6_1_1 - 0.248324514991181*G0_1_1_7_1_0 - 0.293474426807759*G0_1_1_8_1_1 + 0.586948853615522*G0_1_1_9_1_0 + 0.6320987654321*G0_1_1_9_1_1 - 0.586948853615522*G0_1_1_10_1_0 + 1.71569664902998*G0_1_1_10_1_1 + 1.6705467372134*G0_1_1_11_1_0 - 0.6320987654321*G0_1_1_11_1_1; + A[101] = A[245] + 0.835273368606706*G0_0_0_0_0_0 + 0.835273368606704*G0_0_0_0_0_1 - 2.55097001763668*G0_0_0_1_0_0 + 5.35026455026454*G0_0_0_2_0_1 + 7.3142857142857*G0_0_0_3_0_0 - 0.586948853615517*G0_0_0_3_0_1 - 7.3142857142857*G0_0_0_4_0_0 - 6.18553791887125*G0_0_0_4_0_1 + 1.71569664902997*G0_0_0_5_0_0 + 0.586948853615516*G0_0_0_5_0_1 + 0.835273368606706*G0_0_0_6_1_0 + 0.835273368606704*G0_0_0_6_1_1 - 2.55097001763668*G0_0_0_7_1_0 + 5.35026455026454*G0_0_0_8_1_1 + 7.3142857142857*G0_0_0_9_1_0 - 0.586948853615517*G0_0_0_9_1_1 - 7.3142857142857*G0_0_0_10_1_0 - 6.18553791887125*G0_0_0_10_1_1 + 1.71569664902997*G0_0_0_11_1_0 + 0.586948853615516*G0_0_0_11_1_1 - 2.61869488536154*G0_0_1_1_0_0 + 2.61869488536155*G0_0_1_2_0_1 + 2.61869488536155*G0_0_1_3_0_0 - 2.61869488536154*G0_0_1_3_0_1 - 2.61869488536155*G0_0_1_4_0_0 - 2.61869488536155*G0_0_1_4_0_1 + 2.61869488536154*G0_0_1_5_0_0 + 2.61869488536154*G0_0_1_5_0_1 - 2.61869488536154*G0_0_1_7_1_0 + 2.61869488536155*G0_0_1_8_1_1 + 2.61869488536155*G0_0_1_9_1_0 - 2.61869488536154*G0_0_1_9_1_1 - 2.61869488536155*G0_0_1_10_1_0 - 2.61869488536155*G0_0_1_10_1_1 + 2.61869488536154*G0_0_1_11_1_0 + 2.61869488536154*G0_0_1_11_1_1 - 3.5668430335097*G0_1_0_1_0_0 + 3.5668430335097*G0_1_0_2_0_1 + 3.5668430335097*G0_1_0_3_0_0 - 3.5668430335097*G0_1_0_3_0_1 - 3.5668430335097*G0_1_0_4_0_0 - 3.5668430335097*G0_1_0_4_0_1 + 3.5668430335097*G0_1_0_5_0_0 + 3.5668430335097*G0_1_0_5_0_1 - 3.5668430335097*G0_1_0_7_1_0 + 3.5668430335097*G0_1_0_8_1_1 + 3.5668430335097*G0_1_0_9_1_0 - 3.5668430335097*G0_1_0_9_1_1 - 3.5668430335097*G0_1_0_10_1_0 - 3.5668430335097*G0_1_0_10_1_1 + 3.5668430335097*G0_1_0_11_1_0 + 3.5668430335097*G0_1_0_11_1_1 - 0.835273368606698*G0_1_1_0_0_0 - 0.8352733686067*G0_1_1_0_0_1 - 5.35026455026454*G0_1_1_1_0_0 + 2.55097001763668*G0_1_1_2_0_1 + 0.586948853615524*G0_1_1_3_0_0 - 7.3142857142857*G0_1_1_3_0_1 - 0.586948853615524*G0_1_1_4_0_0 - 1.71569664902999*G0_1_1_4_0_1 + 6.18553791887124*G0_1_1_5_0_0 + 7.3142857142857*G0_1_1_5_0_1 - 0.835273368606698*G0_1_1_6_1_0 - 0.8352733686067*G0_1_1_6_1_1 - 5.35026455026454*G0_1_1_7_1_0 + 2.55097001763668*G0_1_1_8_1_1 + 0.586948853615524*G0_1_1_9_1_0 - 7.3142857142857*G0_1_1_9_1_1 - 0.586948853615524*G0_1_1_10_1_0 - 1.71569664902999*G0_1_1_10_1_1 + 6.18553791887124*G0_1_1_11_1_0 + 7.3142857142857*G0_1_1_11_1_1; + A[710] = A[245]; + A[623] = A[245] - 0.31604938271605*G0_0_1_0_0_0 - 0.31604938271605*G0_0_1_0_0_1 + 0.316049382716049*G0_0_1_1_0_0 - 0.6320987654321*G0_0_1_2_0_1 - 0.6320987654321*G0_0_1_3_0_0 + 0.316049382716049*G0_0_1_3_0_1 + 0.6320987654321*G0_0_1_4_0_0 + 0.948148148148149*G0_0_1_4_0_1 - 0.316049382716049*G0_0_1_5_0_1 - 0.31604938271605*G0_0_1_6_1_0 - 0.31604938271605*G0_0_1_6_1_1 + 0.316049382716049*G0_0_1_7_1_0 - 0.6320987654321*G0_0_1_8_1_1 - 0.6320987654321*G0_0_1_9_1_0 + 0.316049382716049*G0_0_1_9_1_1 + 0.6320987654321*G0_0_1_10_1_0 + 0.948148148148149*G0_0_1_10_1_1 - 0.316049382716049*G0_0_1_11_1_1 + 0.31604938271605*G0_1_0_0_0_0 + 0.31604938271605*G0_1_0_0_0_1 - 0.316049382716049*G0_1_0_1_0_0 + 0.6320987654321*G0_1_0_2_0_1 + 0.6320987654321*G0_1_0_3_0_0 - 0.316049382716049*G0_1_0_3_0_1 - 0.6320987654321*G0_1_0_4_0_0 - 0.948148148148149*G0_1_0_4_0_1 + 0.316049382716049*G0_1_0_5_0_1 + 0.31604938271605*G0_1_0_6_1_0 + 0.31604938271605*G0_1_0_6_1_1 - 0.316049382716049*G0_1_0_7_1_0 + 0.6320987654321*G0_1_0_8_1_1 + 0.6320987654321*G0_1_0_9_1_0 - 0.316049382716049*G0_1_0_9_1_1 - 0.6320987654321*G0_1_0_10_1_0 - 0.948148148148149*G0_1_0_10_1_1 + 0.316049382716049*G0_1_0_11_1_1; + A[158] = A[623]; + A[333] = A[101] - 0.316049382716051*G0_0_1_0_0_0 - 0.316049382716052*G0_0_1_0_0_1 - 0.632098765432105*G0_0_1_1_0_0 + 0.316049382716051*G0_0_1_2_0_1 + 0.316049382716049*G0_0_1_3_0_0 - 0.632098765432107*G0_0_1_3_0_1 - 0.316049382716049*G0_0_1_4_0_0 + 0.948148148148157*G0_0_1_5_0_0 + 0.632098765432107*G0_0_1_5_0_1 - 0.316049382716051*G0_0_1_6_1_0 - 0.316049382716052*G0_0_1_6_1_1 - 0.632098765432105*G0_0_1_7_1_0 + 0.316049382716051*G0_0_1_8_1_1 + 0.316049382716049*G0_0_1_9_1_0 - 0.632098765432107*G0_0_1_9_1_1 - 0.316049382716049*G0_0_1_10_1_0 + 0.948148148148157*G0_0_1_11_1_0 + 0.632098765432107*G0_0_1_11_1_1 + 0.316049382716051*G0_1_0_0_0_0 + 0.316049382716051*G0_1_0_0_0_1 + 0.632098765432104*G0_1_0_1_0_0 - 0.316049382716051*G0_1_0_2_0_1 - 0.316049382716049*G0_1_0_3_0_0 + 0.632098765432107*G0_1_0_3_0_1 + 0.316049382716049*G0_1_0_4_0_0 - 0.948148148148156*G0_1_0_5_0_0 - 0.632098765432108*G0_1_0_5_0_1 + 0.316049382716051*G0_1_0_6_1_0 + 0.316049382716051*G0_1_0_6_1_1 + 0.632098765432104*G0_1_0_7_1_0 - 0.316049382716051*G0_1_0_8_1_1 - 0.316049382716049*G0_1_0_9_1_0 + 0.632098765432107*G0_1_0_9_1_1 + 0.316049382716049*G0_1_0_10_1_0 - 0.948148148148156*G0_1_0_11_1_0 - 0.632098765432108*G0_1_0_11_1_1; + A[806] = -A[101] - 0.609523809523807*G0_0_0_0_0_0 - 0.609523809523807*G0_0_0_0_0_1 + 1.78342151675486*G0_0_0_1_0_0 - 0.699823633156968*G0_0_0_2_0_1 + 0.993298059964723*G0_0_0_3_0_0 + 3.47654320987655*G0_0_0_3_0_1 - 0.993298059964723*G0_0_0_4_0_0 + 1.30934744268078*G0_0_0_4_0_1 - 1.17389770723105*G0_0_0_5_0_0 - 3.47654320987655*G0_0_0_5_0_1 - 0.609523809523807*G0_0_0_6_1_0 - 0.609523809523807*G0_0_0_6_1_1 + 1.78342151675486*G0_0_0_7_1_0 - 0.699823633156968*G0_0_0_8_1_1 + 0.993298059964723*G0_0_0_9_1_0 + 3.47654320987655*G0_0_0_9_1_1 - 0.993298059964723*G0_0_0_10_1_0 + 1.30934744268078*G0_0_0_10_1_1 - 1.17389770723105*G0_0_0_11_1_0 - 3.47654320987655*G0_0_0_11_1_1 + 0.316049382716051*G0_0_1_0_0_0 + 0.316049382716051*G0_0_1_0_0_1 + 0.632098765432103*G0_0_1_1_0_0 - 0.31604938271605*G0_0_1_2_0_1 - 0.316049382716049*G0_0_1_3_0_0 + 0.632098765432103*G0_0_1_3_0_1 + 0.316049382716049*G0_0_1_4_0_0 - 0.948148148148154*G0_0_1_5_0_0 - 0.632098765432104*G0_0_1_5_0_1 + 0.316049382716051*G0_0_1_6_1_0 + 0.316049382716051*G0_0_1_6_1_1 + 0.632098765432103*G0_0_1_7_1_0 - 0.31604938271605*G0_0_1_8_1_1 - 0.316049382716049*G0_0_1_9_1_0 + 0.632098765432103*G0_0_1_9_1_1 + 0.316049382716049*G0_0_1_10_1_0 - 0.948148148148154*G0_0_1_11_1_0 - 0.632098765432104*G0_0_1_11_1_1; + A[558] = -A[101] + 0.383774250440917*G0_0_0_0_0_0 + 0.383774250440917*G0_0_0_0_0_1 + 1.15132275132275*G0_0_0_1_0_0 + 0.925573192239857*G0_0_0_2_0_1 + 2.61869488536155*G0_0_0_3_0_0 + 2.84444444444444*G0_0_0_3_0_1 - 2.61869488536155*G0_0_0_4_0_0 - 1.30934744268077*G0_0_0_4_0_1 - 1.53509700176367*G0_0_0_5_0_0 - 2.84444444444444*G0_0_0_5_0_1 + 0.383774250440917*G0_0_0_6_1_0 + 0.383774250440917*G0_0_0_6_1_1 + 1.15132275132275*G0_0_0_7_1_0 + 0.925573192239857*G0_0_0_8_1_1 + 2.61869488536155*G0_0_0_9_1_0 + 2.84444444444444*G0_0_0_9_1_1 - 2.61869488536155*G0_0_0_10_1_0 - 1.30934744268077*G0_0_0_10_1_1 - 1.53509700176367*G0_0_0_11_1_0 - 2.84444444444444*G0_0_0_11_1_1 - 0.316049382716051*G0_1_0_0_0_0 - 0.316049382716051*G0_1_0_0_0_1 - 0.632098765432104*G0_1_0_1_0_0 + 0.316049382716051*G0_1_0_2_0_1 + 0.316049382716049*G0_1_0_3_0_0 - 0.632098765432106*G0_1_0_3_0_1 - 0.316049382716049*G0_1_0_4_0_0 + 0.948148148148155*G0_1_0_5_0_0 + 0.632098765432107*G0_1_0_5_0_1 - 0.316049382716051*G0_1_0_6_1_0 - 0.316049382716051*G0_1_0_6_1_1 - 0.632098765432104*G0_1_0_7_1_0 + 0.316049382716051*G0_1_0_8_1_1 + 0.316049382716049*G0_1_0_9_1_0 - 0.632098765432106*G0_1_0_9_1_1 - 0.316049382716049*G0_1_0_10_1_0 + 0.948148148148155*G0_1_0_11_1_0 + 0.632098765432107*G0_1_0_11_1_1; + A[93] = A[558]; + A[620] = -A[245] - 0.31604938271605*G0_1_0_0_0_0 - 0.31604938271605*G0_1_0_0_0_1 + 0.316049382716049*G0_1_0_1_0_0 - 0.632098765432099*G0_1_0_2_0_1 - 0.632098765432098*G0_1_0_3_0_0 + 0.316049382716049*G0_1_0_3_0_1 + 0.632098765432098*G0_1_0_4_0_0 + 0.948148148148148*G0_1_0_4_0_1 - 0.316049382716049*G0_1_0_5_0_1 - 0.31604938271605*G0_1_0_6_1_0 - 0.31604938271605*G0_1_0_6_1_1 + 0.316049382716049*G0_1_0_7_1_0 - 0.632098765432099*G0_1_0_8_1_1 - 0.632098765432098*G0_1_0_9_1_0 + 0.316049382716049*G0_1_0_9_1_1 + 0.632098765432098*G0_1_0_10_1_0 + 0.948148148148148*G0_1_0_10_1_1 - 0.316049382716049*G0_1_0_11_1_1 + 0.383774250440918*G0_1_1_0_0_0 + 0.383774250440918*G0_1_1_0_0_1 + 0.92557319223986*G0_1_1_1_0_0 + 1.15132275132275*G0_1_1_2_0_1 + 2.84444444444444*G0_1_1_3_0_0 + 2.61869488536155*G0_1_1_3_0_1 - 2.84444444444444*G0_1_1_4_0_0 - 1.53509700176367*G0_1_1_4_0_1 - 1.30934744268078*G0_1_1_5_0_0 - 2.61869488536155*G0_1_1_5_0_1 + 0.383774250440918*G0_1_1_6_1_0 + 0.383774250440918*G0_1_1_6_1_1 + 0.92557319223986*G0_1_1_7_1_0 + 1.15132275132275*G0_1_1_8_1_1 + 2.84444444444444*G0_1_1_9_1_0 + 2.61869488536155*G0_1_1_9_1_1 - 2.84444444444444*G0_1_1_10_1_0 - 1.53509700176367*G0_1_1_10_1_1 - 1.30934744268078*G0_1_1_11_1_0 - 2.61869488536155*G0_1_1_11_1_1; + A[403] = A[620] - 1.19647266313934*G0_0_0_0_0_0 - 1.19647266313934*G0_0_0_0_0_1 + 5.53086419753085*G0_0_0_1_0_0 - 3.13791887125221*G0_0_0_2_0_1 + 0.451499118165777*G0_0_0_3_0_0 + 9.12028218694883*G0_0_0_3_0_1 - 0.451499118165777*G0_0_0_4_0_0 + 4.33439153439154*G0_0_0_4_0_1 - 4.33439153439151*G0_0_0_5_0_0 - 9.12028218694883*G0_0_0_5_0_1 - 1.19647266313934*G0_0_0_6_1_0 - 1.19647266313934*G0_0_0_6_1_1 + 5.53086419753085*G0_0_0_7_1_0 - 3.13791887125221*G0_0_0_8_1_1 + 0.451499118165777*G0_0_0_9_1_0 + 9.12028218694883*G0_0_0_9_1_1 - 0.451499118165777*G0_0_0_10_1_0 + 4.33439153439154*G0_0_0_10_1_1 - 4.33439153439151*G0_0_0_11_1_0 - 9.12028218694883*G0_0_0_11_1_1 + 1.02716049382715*G0_0_1_0_0_0 + 1.02716049382715*G0_0_1_0_0_1 + 4.61657848324514*G0_0_1_1_0_0 - 1.794708994709*G0_0_1_2_0_1 + 6.41128747795413*G0_0_1_3_0_1 + 0.767548500881843*G0_0_1_4_0_1 - 5.64373897707229*G0_0_1_5_0_0 - 6.41128747795413*G0_0_1_5_0_1 + 1.02716049382715*G0_0_1_6_1_0 + 1.02716049382715*G0_0_1_6_1_1 + 4.61657848324514*G0_0_1_7_1_0 - 1.794708994709*G0_0_1_8_1_1 + 6.41128747795413*G0_0_1_9_1_1 + 0.767548500881843*G0_0_1_10_1_1 - 5.64373897707229*G0_0_1_11_1_0 - 6.41128747795413*G0_0_1_11_1_1 + 1.02716049382715*G0_1_0_0_0_0 + 1.02716049382715*G0_1_0_0_0_1 + 4.61657848324514*G0_1_0_1_0_0 - 1.794708994709*G0_1_0_2_0_1 + 6.41128747795413*G0_1_0_3_0_1 + 0.767548500881843*G0_1_0_4_0_1 - 5.64373897707229*G0_1_0_5_0_0 - 6.41128747795413*G0_1_0_5_0_1 + 1.02716049382715*G0_1_0_6_1_0 + 1.02716049382715*G0_1_0_6_1_1 + 4.61657848324514*G0_1_0_7_1_0 - 1.794708994709*G0_1_0_8_1_1 + 6.41128747795413*G0_1_0_9_1_1 + 0.767548500881843*G0_1_0_10_1_1 - 5.64373897707229*G0_1_0_11_1_0 - 6.41128747795413*G0_1_0_11_1_1 + 0.338624338624332*G0_1_1_0_0_0 + 0.338624338624333*G0_1_1_0_0_1 + 7.78835978835978*G0_1_1_1_0_0 - 3.58941798941799*G0_1_1_2_0_1 + 0.270899470899458*G0_1_1_3_0_0 + 11.6486772486772*G0_1_1_3_0_1 - 0.270899470899458*G0_1_1_4_0_0 + 3.25079365079366*G0_1_1_4_0_1 - 8.12698412698411*G0_1_1_5_0_0 - 11.6486772486772*G0_1_1_5_0_1 + 0.338624338624332*G0_1_1_6_1_0 + 0.338624338624333*G0_1_1_6_1_1 + 7.78835978835978*G0_1_1_7_1_0 - 3.58941798941799*G0_1_1_8_1_1 + 0.270899470899458*G0_1_1_9_1_0 + 11.6486772486772*G0_1_1_9_1_1 - 0.270899470899458*G0_1_1_10_1_0 + 3.25079365079366*G0_1_1_10_1_1 - 8.12698412698411*G0_1_1_11_1_0 - 11.6486772486772*G0_1_1_11_1_1; + A[373] = -A[403] + 1.62539682539682*G0_0_0_0_0_0 + 1.62539682539682*G0_0_0_0_0_1 + 2.7089947089947*G0_0_0_1_0_0 + 0.541798941798941*G0_0_0_2_0_1 + 2.16719576719576*G0_0_0_3_0_0 + 4.33439153439152*G0_0_0_3_0_1 - 2.16719576719576*G0_0_0_4_0_0 - 2.16719576719576*G0_0_0_4_0_1 - 4.33439153439152*G0_0_0_5_0_0 - 4.33439153439152*G0_0_0_5_0_1 + 1.62539682539682*G0_0_0_6_1_0 + 1.62539682539682*G0_0_0_6_1_1 + 2.7089947089947*G0_0_0_7_1_0 + 0.541798941798941*G0_0_0_8_1_1 + 2.16719576719576*G0_0_0_9_1_0 + 4.33439153439152*G0_0_0_9_1_1 - 2.16719576719576*G0_0_0_10_1_0 - 2.16719576719576*G0_0_0_10_1_1 - 4.33439153439152*G0_0_0_11_1_0 - 4.33439153439152*G0_0_0_11_1_1 + 1.35449735449735*G0_0_1_0_0_0 + 1.35449735449735*G0_0_1_0_0_1 + 1.89629629629629*G0_0_1_1_0_0 + 0.270899470899471*G0_0_1_2_0_1 + 1.08359788359788*G0_0_1_3_0_0 + 2.7089947089947*G0_0_1_3_0_1 - 1.08359788359788*G0_0_1_4_0_0 - 1.62539682539682*G0_0_1_4_0_1 - 3.25079365079364*G0_0_1_5_0_0 - 2.7089947089947*G0_0_1_5_0_1 + 1.35449735449735*G0_0_1_6_1_0 + 1.35449735449735*G0_0_1_6_1_1 + 1.89629629629629*G0_0_1_7_1_0 + 0.270899470899471*G0_0_1_8_1_1 + 1.08359788359788*G0_0_1_9_1_0 + 2.7089947089947*G0_0_1_9_1_1 - 1.08359788359788*G0_0_1_10_1_0 - 1.62539682539682*G0_0_1_10_1_1 - 3.25079365079364*G0_0_1_11_1_0 - 2.7089947089947*G0_0_1_11_1_1 + 0.812698412698407*G0_1_0_0_0_0 + 0.812698412698407*G0_1_0_0_0_1 + 2.43809523809523*G0_1_0_1_0_0 - 0.812698412698412*G0_1_0_2_0_1 + 3.25079365079364*G0_1_0_3_0_1 - 3.25079365079364*G0_1_0_5_0_0 - 3.25079365079364*G0_1_0_5_0_1 + 0.812698412698407*G0_1_0_6_1_0 + 0.812698412698407*G0_1_0_6_1_1 + 2.43809523809523*G0_1_0_7_1_0 - 0.812698412698412*G0_1_0_8_1_1 + 3.25079365079364*G0_1_0_9_1_1 - 3.25079365079364*G0_1_0_11_1_0 - 3.25079365079364*G0_1_0_11_1_1 + 7.04338624338624*G0_1_1_1_0_0 - 2.16719576719577*G0_1_1_2_0_1 + 2.7089947089947*G0_1_1_3_0_0 + 11.9195767195767*G0_1_1_3_0_1 - 2.7089947089947*G0_1_1_4_0_0 + 2.16719576719578*G0_1_1_4_0_1 - 7.04338624338623*G0_1_1_5_0_0 - 11.9195767195767*G0_1_1_5_0_1 + 7.04338624338624*G0_1_1_7_1_0 - 2.16719576719577*G0_1_1_8_1_1 + 2.7089947089947*G0_1_1_9_1_0 + 11.9195767195767*G0_1_1_9_1_1 - 2.7089947089947*G0_1_1_10_1_0 + 2.16719576719578*G0_1_1_10_1_1 - 7.04338624338623*G0_1_1_11_1_0 - 11.9195767195767*G0_1_1_11_1_1; + A[897] = A[373] - 2.70899470899471*G0_0_0_0_0_0 - 2.70899470899471*G0_0_0_0_0_1 + 0.541798941798933*G0_0_0_1_0_0 + 3.25079365079364*G0_0_0_3_0_0 + 3.79259259259258*G0_0_0_3_0_1 - 3.25079365079364*G0_0_0_4_0_0 + 2.70899470899472*G0_0_0_4_0_1 + 2.16719576719578*G0_0_0_5_0_0 - 3.79259259259258*G0_0_0_5_0_1 - 2.70899470899471*G0_0_0_6_1_0 - 2.70899470899471*G0_0_0_6_1_1 + 0.541798941798933*G0_0_0_7_1_0 + 3.25079365079364*G0_0_0_9_1_0 + 3.79259259259258*G0_0_0_9_1_1 - 3.25079365079364*G0_0_0_10_1_0 + 2.70899470899472*G0_0_0_10_1_1 + 2.16719576719578*G0_0_0_11_1_0 - 3.79259259259258*G0_0_0_11_1_1 + 2.16719576719576*G0_0_1_1_0_0 - 2.16719576719577*G0_0_1_2_0_1 - 2.16719576719578*G0_0_1_3_0_0 + 2.16719576719575*G0_0_1_3_0_1 + 2.16719576719578*G0_0_1_4_0_0 + 2.16719576719577*G0_0_1_4_0_1 - 2.16719576719576*G0_0_1_5_0_0 - 2.16719576719575*G0_0_1_5_0_1 + 2.16719576719576*G0_0_1_7_1_0 - 2.16719576719577*G0_0_1_8_1_1 - 2.16719576719578*G0_0_1_9_1_0 + 2.16719576719575*G0_0_1_9_1_1 + 2.16719576719578*G0_0_1_10_1_0 + 2.16719576719577*G0_0_1_10_1_1 - 2.16719576719576*G0_0_1_11_1_0 - 2.16719576719575*G0_0_1_11_1_1 + 0.54179894179894*G0_1_0_1_0_0 - 0.541798941798945*G0_1_0_2_0_1 - 0.541798941798946*G0_1_0_3_0_0 + 0.541798941798939*G0_1_0_3_0_1 + 0.541798941798946*G0_1_0_4_0_0 + 0.541798941798949*G0_1_0_4_0_1 - 0.541798941798937*G0_1_0_5_0_0 - 0.541798941798939*G0_1_0_5_0_1 + 0.54179894179894*G0_1_0_7_1_0 - 0.541798941798945*G0_1_0_8_1_1 - 0.541798941798946*G0_1_0_9_1_0 + 0.541798941798939*G0_1_0_9_1_1 + 0.541798941798946*G0_1_0_10_1_0 + 0.541798941798949*G0_1_0_10_1_1 - 0.541798941798937*G0_1_0_11_1_0 - 0.541798941798939*G0_1_0_11_1_1 + 2.70899470899471*G0_1_1_0_0_0 + 2.70899470899471*G0_1_1_0_0_1 - 0.541798941798942*G0_1_1_2_0_1 - 3.79259259259259*G0_1_1_3_0_0 - 3.25079365079366*G0_1_1_3_0_1 + 3.79259259259259*G0_1_1_4_0_0 - 2.16719576719577*G0_1_1_4_0_1 - 2.7089947089947*G0_1_1_5_0_0 + 3.25079365079366*G0_1_1_5_0_1 + 2.70899470899471*G0_1_1_6_1_0 + 2.70899470899471*G0_1_1_6_1_1 - 0.541798941798942*G0_1_1_8_1_1 - 3.79259259259259*G0_1_1_9_1_0 - 3.25079365079366*G0_1_1_9_1_1 + 3.79259259259259*G0_1_1_10_1_0 - 2.16719576719577*G0_1_1_10_1_1 - 2.7089947089947*G0_1_1_11_1_0 + 3.25079365079366*G0_1_1_11_1_1; + A[899] = -A[897] - 2.16719576719577*G0_0_0_1_0_0 + 7.04338624338624*G0_0_0_2_0_1 + 11.9195767195767*G0_0_0_3_0_0 + 2.70899470899471*G0_0_0_3_0_1 - 11.9195767195767*G0_0_0_4_0_0 - 7.04338624338624*G0_0_0_4_0_1 + 2.16719576719577*G0_0_0_5_0_0 - 2.70899470899471*G0_0_0_5_0_1 - 2.16719576719577*G0_0_0_7_1_0 + 7.04338624338624*G0_0_0_8_1_1 + 11.9195767195767*G0_0_0_9_1_0 + 2.70899470899471*G0_0_0_9_1_1 - 11.9195767195767*G0_0_0_10_1_0 - 7.04338624338624*G0_0_0_10_1_1 + 2.16719576719577*G0_0_0_11_1_0 - 2.70899470899471*G0_0_0_11_1_1 + 1.35449735449736*G0_0_1_0_0_0 + 1.35449735449736*G0_0_1_0_0_1 + 0.27089947089947*G0_0_1_1_0_0 + 1.8962962962963*G0_0_1_2_0_1 + 2.70899470899471*G0_0_1_3_0_0 + 1.08359788359788*G0_0_1_3_0_1 - 2.70899470899471*G0_0_1_4_0_0 - 3.25079365079366*G0_0_1_4_0_1 - 1.62539682539683*G0_0_1_5_0_0 - 1.08359788359788*G0_0_1_5_0_1 + 1.35449735449736*G0_0_1_6_1_0 + 1.35449735449736*G0_0_1_6_1_1 + 0.27089947089947*G0_0_1_7_1_0 + 1.8962962962963*G0_0_1_8_1_1 + 2.70899470899471*G0_0_1_9_1_0 + 1.08359788359788*G0_0_1_9_1_1 - 2.70899470899471*G0_0_1_10_1_0 - 3.25079365079366*G0_0_1_10_1_1 - 1.62539682539683*G0_0_1_11_1_0 - 1.08359788359788*G0_0_1_11_1_1 + 0.812698412698413*G0_1_0_0_0_0 + 0.812698412698413*G0_1_0_0_0_1 - 0.812698412698411*G0_1_0_1_0_0 + 2.43809523809524*G0_1_0_2_0_1 + 3.25079365079366*G0_1_0_3_0_0 - 3.25079365079366*G0_1_0_4_0_0 - 3.25079365079365*G0_1_0_4_0_1 + 0.812698412698413*G0_1_0_6_1_0 + 0.812698412698413*G0_1_0_6_1_1 - 0.812698412698411*G0_1_0_7_1_0 + 2.43809523809524*G0_1_0_8_1_1 + 3.25079365079366*G0_1_0_9_1_0 - 3.25079365079366*G0_1_0_10_1_0 - 3.25079365079365*G0_1_0_10_1_1 + 1.62539682539683*G0_1_1_0_0_0 + 1.62539682539683*G0_1_1_0_0_1 + 0.541798941798942*G0_1_1_1_0_0 + 2.70899470899471*G0_1_1_2_0_1 + 4.33439153439153*G0_1_1_3_0_0 + 2.16719576719577*G0_1_1_3_0_1 - 4.33439153439153*G0_1_1_4_0_0 - 4.33439153439154*G0_1_1_4_0_1 - 2.16719576719577*G0_1_1_5_0_0 - 2.16719576719577*G0_1_1_5_0_1 + 1.62539682539683*G0_1_1_6_1_0 + 1.62539682539683*G0_1_1_6_1_1 + 0.541798941798942*G0_1_1_7_1_0 + 2.70899470899471*G0_1_1_8_1_1 + 4.33439153439153*G0_1_1_9_1_0 + 2.16719576719577*G0_1_1_9_1_1 - 4.33439153439153*G0_1_1_10_1_0 - 4.33439153439154*G0_1_1_10_1_1 - 2.16719576719577*G0_1_1_11_1_0 - 2.16719576719577*G0_1_1_11_1_1; + A[434] = A[899]; + A[432] = A[897]; + A[869] = A[373] - 0.541798941798943*G0_0_0_0_0_0 - 0.541798941798942*G0_0_0_0_0_1 + 2.7089947089947*G0_0_0_1_0_0 + 3.25079365079364*G0_0_0_3_0_0 + 5.95978835978835*G0_0_0_3_0_1 - 3.25079365079364*G0_0_0_4_0_0 + 0.541798941798941*G0_0_0_4_0_1 - 2.16719576719576*G0_0_0_5_0_0 - 5.95978835978835*G0_0_0_5_0_1 - 0.541798941798943*G0_0_0_6_1_0 - 0.541798941798942*G0_0_0_6_1_1 + 2.7089947089947*G0_0_0_7_1_0 + 3.25079365079364*G0_0_0_9_1_0 + 5.95978835978835*G0_0_0_9_1_1 - 3.25079365079364*G0_0_0_10_1_0 + 0.541798941798941*G0_0_0_10_1_1 - 2.16719576719576*G0_0_0_11_1_0 - 5.95978835978835*G0_0_0_11_1_1 + 2.7089947089947*G0_0_1_1_0_0 + 0.541798941798942*G0_0_1_2_0_1 + 3.79259259259258*G0_0_1_3_0_0 + 5.95978835978834*G0_0_1_3_0_1 - 3.79259259259258*G0_0_1_4_0_0 - 0.541798941798941*G0_0_1_4_0_1 - 2.7089947089947*G0_0_1_5_0_0 - 5.95978835978835*G0_0_1_5_0_1 + 2.7089947089947*G0_0_1_7_1_0 + 0.541798941798942*G0_0_1_8_1_1 + 3.79259259259258*G0_0_1_9_1_0 + 5.95978835978834*G0_0_1_9_1_1 - 3.79259259259258*G0_0_1_10_1_0 - 0.541798941798941*G0_0_1_10_1_1 - 2.7089947089947*G0_0_1_11_1_0 - 5.95978835978835*G0_0_1_11_1_1 + 1.62539682539683*G0_1_0_0_0_0 + 1.62539682539683*G0_1_0_0_0_1 + 2.70899470899471*G0_1_0_1_0_0 + 2.16719576719576*G0_1_0_2_0_1 + 5.41798941798941*G0_1_0_3_0_0 + 5.95978835978835*G0_1_0_3_0_1 - 5.41798941798941*G0_1_0_4_0_0 - 3.79259259259259*G0_1_0_4_0_1 - 4.33439153439153*G0_1_0_5_0_0 - 5.95978835978835*G0_1_0_5_0_1 + 1.62539682539683*G0_1_0_6_1_0 + 1.62539682539683*G0_1_0_6_1_1 + 2.70899470899471*G0_1_0_7_1_0 + 2.16719576719576*G0_1_0_8_1_1 + 5.41798941798941*G0_1_0_9_1_0 + 5.95978835978835*G0_1_0_9_1_1 - 5.41798941798941*G0_1_0_10_1_0 - 3.79259259259259*G0_1_0_10_1_1 - 4.33439153439153*G0_1_0_11_1_0 - 5.95978835978835*G0_1_0_11_1_1 + 2.16719576719577*G0_1_1_0_0_0 + 2.16719576719577*G0_1_1_0_0_1 + 2.16719576719577*G0_1_1_2_0_1 + 2.16719576719577*G0_1_1_3_0_0 - 2.16719576719577*G0_1_1_4_0_0 - 4.33439153439154*G0_1_1_4_0_1 - 2.16719576719576*G0_1_1_5_0_0 + 2.16719576719577*G0_1_1_6_1_0 + 2.16719576719577*G0_1_1_6_1_1 + 2.16719576719577*G0_1_1_8_1_1 + 2.16719576719577*G0_1_1_9_1_0 - 2.16719576719577*G0_1_1_10_1_0 - 4.33439153439154*G0_1_1_10_1_1 - 2.16719576719576*G0_1_1_11_1_0; + A[404] = A[869]; + A[838] = A[373]; + A[635] = 0.0; + A[246] = A[711]; + A[670] = 0.0; + A[277] = A[219] + 0.361199294532627*G0_0_1_0_0_0 + 0.361199294532627*G0_0_1_0_0_1 + 0.237037037037037*G0_0_1_1_0_0 + 0.124162257495591*G0_0_1_2_0_1 + 0.124162257495592*G0_0_1_3_0_0 + 0.237037037037038*G0_0_1_3_0_1 - 0.124162257495592*G0_0_1_4_0_0 - 0.485361552028218*G0_0_1_4_0_1 - 0.598236331569663*G0_0_1_5_0_0 - 0.237037037037038*G0_0_1_5_0_1 + 0.361199294532627*G0_0_1_6_1_0 + 0.361199294532627*G0_0_1_6_1_1 + 0.237037037037037*G0_0_1_7_1_0 + 0.124162257495591*G0_0_1_8_1_1 + 0.124162257495592*G0_0_1_9_1_0 + 0.237037037037038*G0_0_1_9_1_1 - 0.124162257495592*G0_0_1_10_1_0 - 0.485361552028218*G0_0_1_10_1_1 - 0.598236331569663*G0_0_1_11_1_0 - 0.237037037037038*G0_0_1_11_1_1 - 0.361199294532627*G0_1_0_0_0_0 - 0.361199294532626*G0_1_0_0_0_1 - 0.237037037037037*G0_1_0_1_0_0 - 0.124162257495591*G0_1_0_2_0_1 - 0.124162257495592*G0_1_0_3_0_0 - 0.237037037037038*G0_1_0_3_0_1 + 0.124162257495592*G0_1_0_4_0_0 + 0.485361552028217*G0_1_0_4_0_1 + 0.598236331569663*G0_1_0_5_0_0 + 0.237037037037038*G0_1_0_5_0_1 - 0.361199294532627*G0_1_0_6_1_0 - 0.361199294532626*G0_1_0_6_1_1 - 0.237037037037037*G0_1_0_7_1_0 - 0.124162257495591*G0_1_0_8_1_1 - 0.124162257495592*G0_1_0_9_1_0 - 0.237037037037038*G0_1_0_9_1_1 + 0.124162257495592*G0_1_0_10_1_0 + 0.485361552028217*G0_1_0_10_1_1 + 0.598236331569663*G0_1_0_11_1_0 + 0.237037037037038*G0_1_0_11_1_1; + A[306] = A[277] - 0.530511463844795*G0_0_0_0_0_0 - 0.530511463844795*G0_0_0_0_0_1 - 0.598236331569664*G0_0_0_1_0_0 + 0.237037037037037*G0_0_0_2_0_1 + 0.406349206349206*G0_0_0_3_0_0 - 0.428924162257496*G0_0_0_3_0_1 - 0.406349206349206*G0_0_0_4_0_0 + 0.293474426807758*G0_0_0_4_0_1 + 1.12874779541446*G0_0_0_5_0_0 + 0.428924162257496*G0_0_0_5_0_1 - 0.530511463844795*G0_0_0_6_1_0 - 0.530511463844795*G0_0_0_6_1_1 - 0.598236331569664*G0_0_0_7_1_0 + 0.237037037037037*G0_0_0_8_1_1 + 0.406349206349206*G0_0_0_9_1_0 - 0.428924162257496*G0_0_0_9_1_1 - 0.406349206349206*G0_0_0_10_1_0 + 0.293474426807758*G0_0_0_10_1_1 + 1.12874779541446*G0_0_0_11_1_0 + 0.428924162257496*G0_0_0_11_1_1 - 0.24832451499118*G0_0_1_1_0_0 + 0.248324514991182*G0_0_1_2_0_1 + 0.248324514991182*G0_0_1_3_0_0 - 0.248324514991181*G0_0_1_3_0_1 - 0.248324514991182*G0_0_1_4_0_0 - 0.248324514991185*G0_0_1_4_0_1 + 0.248324514991178*G0_0_1_5_0_0 + 0.248324514991181*G0_0_1_5_0_1 - 0.24832451499118*G0_0_1_7_1_0 + 0.248324514991182*G0_0_1_8_1_1 + 0.248324514991182*G0_0_1_9_1_0 - 0.248324514991181*G0_0_1_9_1_1 - 0.248324514991182*G0_0_1_10_1_0 - 0.248324514991185*G0_0_1_10_1_1 + 0.248324514991178*G0_0_1_11_1_0 + 0.248324514991181*G0_0_1_11_1_1 - 0.135449735449736*G0_1_0_1_0_0 + 0.135449735449736*G0_1_0_2_0_1 + 0.135449735449736*G0_1_0_3_0_0 - 0.135449735449736*G0_1_0_3_0_1 - 0.135449735449736*G0_1_0_4_0_0 - 0.135449735449736*G0_1_0_4_0_1 + 0.135449735449736*G0_1_0_5_0_0 + 0.135449735449736*G0_1_0_5_0_1 - 0.135449735449736*G0_1_0_7_1_0 + 0.135449735449736*G0_1_0_8_1_1 + 0.135449735449736*G0_1_0_9_1_0 - 0.135449735449736*G0_1_0_9_1_1 - 0.135449735449736*G0_1_0_10_1_0 - 0.135449735449736*G0_1_0_10_1_1 + 0.135449735449736*G0_1_0_11_1_0 + 0.135449735449736*G0_1_0_11_1_1 + 0.530511463844798*G0_1_1_0_0_0 + 0.530511463844798*G0_1_1_0_0_1 - 0.237037037037036*G0_1_1_1_0_0 + 0.598236331569666*G0_1_1_2_0_1 + 0.428924162257497*G0_1_1_3_0_0 - 0.406349206349204*G0_1_1_3_0_1 - 0.428924162257497*G0_1_1_4_0_0 - 1.12874779541446*G0_1_1_4_0_1 - 0.293474426807762*G0_1_1_5_0_0 + 0.406349206349205*G0_1_1_5_0_1 + 0.530511463844798*G0_1_1_6_1_0 + 0.530511463844798*G0_1_1_6_1_1 - 0.237037037037036*G0_1_1_7_1_0 + 0.598236331569666*G0_1_1_8_1_1 + 0.428924162257497*G0_1_1_9_1_0 - 0.406349206349204*G0_1_1_9_1_1 - 0.428924162257497*G0_1_1_10_1_0 - 1.12874779541446*G0_1_1_10_1_1 - 0.293474426807762*G0_1_1_11_1_0 + 0.406349206349205*G0_1_1_11_1_1; + A[448] = 0.0; + A[304] = A[769]; + A[475] = A[765] + 1.04338624338624*G0_0_1_0_0_0 + 1.04338624338624*G0_0_1_0_0_1 + 0.32310405643739*G0_0_1_1_0_0 + 0.294885361552028*G0_0_1_2_0_1 - 0.130511463844796*G0_0_1_3_0_0 - 0.102292768959435*G0_0_1_3_0_1 + 0.130511463844796*G0_0_1_4_0_0 - 1.33827160493827*G0_0_1_4_0_1 - 1.36649029982363*G0_0_1_5_0_0 + 0.102292768959435*G0_0_1_5_0_1 + 1.04338624338624*G0_0_1_6_1_0 + 1.04338624338624*G0_0_1_6_1_1 + 0.32310405643739*G0_0_1_7_1_0 + 0.294885361552028*G0_0_1_8_1_1 - 0.130511463844796*G0_0_1_9_1_0 - 0.102292768959435*G0_0_1_9_1_1 + 0.130511463844796*G0_0_1_10_1_0 - 1.33827160493827*G0_0_1_10_1_1 - 1.36649029982363*G0_0_1_11_1_0 + 0.102292768959435*G0_0_1_11_1_1 - 1.04338624338624*G0_1_0_0_0_0 - 1.04338624338624*G0_1_0_0_0_1 - 0.32310405643739*G0_1_0_1_0_0 - 0.294885361552028*G0_1_0_2_0_1 + 0.130511463844796*G0_1_0_3_0_0 + 0.102292768959435*G0_1_0_3_0_1 - 0.130511463844796*G0_1_0_4_0_0 + 1.33827160493827*G0_1_0_4_0_1 + 1.36649029982363*G0_1_0_5_0_0 - 0.102292768959435*G0_1_0_5_0_1 - 1.04338624338624*G0_1_0_6_1_0 - 1.04338624338624*G0_1_0_6_1_1 - 0.32310405643739*G0_1_0_7_1_0 - 0.294885361552028*G0_1_0_8_1_1 + 0.130511463844796*G0_1_0_9_1_0 + 0.102292768959435*G0_1_0_9_1_1 - 0.130511463844796*G0_1_0_10_1_0 + 1.33827160493827*G0_1_0_10_1_1 + 1.36649029982363*G0_1_0_11_1_0 - 0.102292768959435*G0_1_0_11_1_1; + A[18] = 0.0; + A[735] = A[270]; + A[426] = A[194] + 0.0902998236331607*G0_0_1_0_0_0 + 0.0902998236331607*G0_0_1_0_0_1 - 0.180599647266313*G0_0_1_1_0_0 + 0.270899470899473*G0_0_1_2_0_1 + 0.270899470899473*G0_0_1_3_0_0 - 0.180599647266312*G0_0_1_3_0_1 - 0.270899470899473*G0_0_1_4_0_0 - 0.361199294532634*G0_0_1_4_0_1 + 0.0902998236331518*G0_0_1_5_0_0 + 0.180599647266313*G0_0_1_5_0_1 + 0.0902998236331607*G0_0_1_6_1_0 + 0.0902998236331607*G0_0_1_6_1_1 - 0.180599647266313*G0_0_1_7_1_0 + 0.270899470899473*G0_0_1_8_1_1 + 0.270899470899473*G0_0_1_9_1_0 - 0.180599647266312*G0_0_1_9_1_1 - 0.270899470899473*G0_0_1_10_1_0 - 0.361199294532634*G0_0_1_10_1_1 + 0.0902998236331518*G0_0_1_11_1_0 + 0.180599647266313*G0_0_1_11_1_1 - 0.0902998236331607*G0_1_0_0_0_0 - 0.0902998236331607*G0_1_0_0_0_1 + 0.180599647266313*G0_1_0_1_0_0 - 0.270899470899473*G0_1_0_2_0_1 - 0.270899470899473*G0_1_0_3_0_0 + 0.180599647266313*G0_1_0_3_0_1 + 0.270899470899473*G0_1_0_4_0_0 + 0.361199294532634*G0_1_0_4_0_1 - 0.0902998236331523*G0_1_0_5_0_0 - 0.180599647266313*G0_1_0_5_0_1 - 0.0902998236331607*G0_1_0_6_1_0 - 0.0902998236331607*G0_1_0_6_1_1 + 0.180599647266313*G0_1_0_7_1_0 - 0.270899470899473*G0_1_0_8_1_1 - 0.270899470899473*G0_1_0_9_1_0 + 0.180599647266313*G0_1_0_9_1_1 + 0.270899470899473*G0_1_0_10_1_0 + 0.361199294532634*G0_1_0_10_1_1 - 0.0902998236331523*G0_1_0_11_1_0 - 0.180599647266313*G0_1_0_11_1_1; + A[378] = 0.0; + A[49] = 0.0; + A[764] = 0.0; + A[457] = 0.0; + A[409] = 0.0; + A[84] = 0.0; + A[793] = 0.0; + A[8] = -A[5] + 0.411992945326278*G0_0_1_0_0_0 + 0.411992945326278*G0_0_1_0_0_1 + 0.163668430335097*G0_0_1_1_0_0 + 0.0451499118165779*G0_0_1_2_0_1 - 0.158024691358025*G0_0_1_3_0_0 - 0.0395061728395061*G0_0_1_3_0_1 + 0.158024691358025*G0_0_1_4_0_0 - 0.457142857142856*G0_0_1_4_0_1 - 0.575661375661375*G0_0_1_5_0_0 + 0.0395061728395061*G0_0_1_5_0_1 + 0.411992945326278*G0_0_1_6_1_0 + 0.411992945326278*G0_0_1_6_1_1 + 0.163668430335097*G0_0_1_7_1_0 + 0.0451499118165779*G0_0_1_8_1_1 - 0.158024691358025*G0_0_1_9_1_0 - 0.0395061728395061*G0_0_1_9_1_1 + 0.158024691358025*G0_0_1_10_1_0 - 0.457142857142856*G0_0_1_10_1_1 - 0.575661375661375*G0_0_1_11_1_0 + 0.0395061728395061*G0_0_1_11_1_1 + 0.411992945326278*G0_1_1_0_0_0 + 0.411992945326278*G0_1_1_0_0_1 + 0.163668430335097*G0_1_1_1_0_0 + 0.0451499118165774*G0_1_1_2_0_1 - 0.158024691358026*G0_1_1_3_0_0 - 0.0395061728395062*G0_1_1_3_0_1 + 0.158024691358026*G0_1_1_4_0_0 - 0.457142857142855*G0_1_1_4_0_1 - 0.575661375661375*G0_1_1_5_0_0 + 0.0395061728395063*G0_1_1_5_0_1 + 0.411992945326278*G0_1_1_6_1_0 + 0.411992945326278*G0_1_1_6_1_1 + 0.163668430335097*G0_1_1_7_1_0 + 0.0451499118165774*G0_1_1_8_1_1 - 0.158024691358026*G0_1_1_9_1_0 - 0.0395061728395062*G0_1_1_9_1_1 + 0.158024691358026*G0_1_1_10_1_0 - 0.457142857142855*G0_1_1_10_1_1 - 0.575661375661375*G0_1_1_11_1_0 + 0.0395061728395063*G0_1_1_11_1_1; + A[886] = A[421]; + A[95] = A[560]; + A[810] = 0.0; + A[126] = A[213] - 0.406349206349206*G0_0_0_0_0_0 - 0.406349206349207*G0_0_0_0_0_1 - 0.406349206349206*G0_0_0_1_0_0 - 0.406349206349208*G0_0_0_3_0_1 + 0.40634920634921*G0_0_0_4_0_1 + 0.812698412698413*G0_0_0_5_0_0 + 0.406349206349209*G0_0_0_5_0_1 - 0.406349206349206*G0_0_0_6_1_0 - 0.406349206349207*G0_0_0_6_1_1 - 0.406349206349206*G0_0_0_7_1_0 - 0.406349206349208*G0_0_0_9_1_1 + 0.40634920634921*G0_0_0_10_1_1 + 0.812698412698413*G0_0_0_11_1_0 + 0.406349206349209*G0_0_0_11_1_1 - 0.237037037037037*G0_0_1_0_0_0 - 0.237037037037037*G0_0_1_0_0_1 - 0.169312169312167*G0_0_1_1_0_0 - 0.135449735449736*G0_0_1_2_0_1 - 0.203174603174602*G0_0_1_3_0_0 - 0.237037037037033*G0_0_1_3_0_1 + 0.203174603174602*G0_0_1_4_0_0 + 0.372486772486773*G0_0_1_4_0_1 + 0.406349206349204*G0_0_1_5_0_0 + 0.237037037037033*G0_0_1_5_0_1 - 0.237037037037037*G0_0_1_6_1_0 - 0.237037037037037*G0_0_1_6_1_1 - 0.169312169312167*G0_0_1_7_1_0 - 0.135449735449736*G0_0_1_8_1_1 - 0.203174603174602*G0_0_1_9_1_0 - 0.237037037037033*G0_0_1_9_1_1 + 0.203174603174602*G0_0_1_10_1_0 + 0.372486772486773*G0_0_1_10_1_1 + 0.406349206349204*G0_0_1_11_1_0 + 0.237037037037033*G0_0_1_11_1_1 - 0.169312169312172*G0_1_0_0_0_0 - 0.169312169312172*G0_1_0_0_0_1 - 0.237037037037038*G0_1_0_1_0_0 - 0.0677248677248692*G0_1_0_3_0_0 - 0.304761904761906*G0_1_0_3_0_1 + 0.0677248677248692*G0_1_0_4_0_0 + 0.169312169312173*G0_1_0_4_0_1 + 0.40634920634921*G0_1_0_5_0_0 + 0.304761904761906*G0_1_0_5_0_1 - 0.169312169312172*G0_1_0_6_1_0 - 0.169312169312172*G0_1_0_6_1_1 - 0.237037037037038*G0_1_0_7_1_0 - 0.0677248677248692*G0_1_0_9_1_0 - 0.304761904761906*G0_1_0_9_1_1 + 0.0677248677248692*G0_1_0_10_1_0 + 0.169312169312173*G0_1_0_10_1_1 + 0.40634920634921*G0_1_0_11_1_0 + 0.304761904761906*G0_1_0_11_1_1 - 0.203174603174605*G0_1_1_0_0_0 - 0.203174603174605*G0_1_1_0_0_1 - 0.2031746031746*G0_1_1_1_0_0 - 0.067724867724869*G0_1_1_2_0_1 - 0.135449735449734*G0_1_1_3_0_0 - 0.270899470899465*G0_1_1_3_0_1 + 0.135449735449734*G0_1_1_4_0_0 + 0.270899470899474*G0_1_1_4_0_1 + 0.406349206349205*G0_1_1_5_0_0 + 0.270899470899465*G0_1_1_5_0_1 - 0.203174603174605*G0_1_1_6_1_0 - 0.203174603174605*G0_1_1_6_1_1 - 0.2031746031746*G0_1_1_7_1_0 - 0.067724867724869*G0_1_1_8_1_1 - 0.135449735449734*G0_1_1_9_1_0 - 0.270899470899465*G0_1_1_9_1_1 + 0.135449735449734*G0_1_1_10_1_0 + 0.270899470899474*G0_1_1_10_1_1 + 0.406349206349205*G0_1_1_11_1_0 + 0.270899470899465*G0_1_1_11_1_1; + A[851] = 0.0; + A[157] = -A[247] + 0.112874779541445*G0_1_0_0_0_0 + 0.112874779541445*G0_1_0_0_0_1 + 1.06102292768959*G0_1_0_1_0_0 - 2.06560846560847*G0_1_0_2_0_1 - 3.18306878306879*G0_1_0_3_0_0 - 0.0564373897707249*G0_1_0_3_0_1 + 3.18306878306879*G0_1_0_4_0_0 + 1.95273368606702*G0_1_0_4_0_1 - 1.17389770723104*G0_1_0_5_0_0 + 0.056437389770725*G0_1_0_5_0_1 + 0.112874779541445*G0_1_0_6_1_0 + 0.112874779541445*G0_1_0_6_1_1 + 1.06102292768959*G0_1_0_7_1_0 - 2.06560846560847*G0_1_0_8_1_1 - 3.18306878306879*G0_1_0_9_1_0 - 0.0564373897707249*G0_1_0_9_1_1 + 3.18306878306879*G0_1_0_10_1_0 + 1.95273368606702*G0_1_0_10_1_1 - 1.17389770723104*G0_1_0_11_1_0 + 0.056437389770725*G0_1_0_11_1_1 + 1.48430335097001*G0_1_1_0_0_0 + 1.48430335097001*G0_1_1_0_0_1 + 1.1005291005291*G0_1_1_1_0_0 - 1.46172839506173*G0_1_1_2_0_1 - 3.30723104056438*G0_1_1_3_0_0 - 0.744973544973545*G0_1_1_3_0_1 + 3.30723104056438*G0_1_1_4_0_0 - 0.0225749559082828*G0_1_1_4_0_1 - 2.58483245149911*G0_1_1_5_0_0 + 0.744973544973546*G0_1_1_5_0_1 + 1.48430335097001*G0_1_1_6_1_0 + 1.48430335097001*G0_1_1_6_1_1 + 1.1005291005291*G0_1_1_7_1_0 - 1.46172839506173*G0_1_1_8_1_1 - 3.30723104056438*G0_1_1_9_1_0 - 0.744973544973545*G0_1_1_9_1_1 + 3.30723104056438*G0_1_1_10_1_0 - 0.0225749559082828*G0_1_1_10_1_1 - 2.58483245149911*G0_1_1_11_1_0 + 0.744973544973546*G0_1_1_11_1_1; + A[880] = 0.0; + A[481] = 0.0; + A[200] = 0.0; + A[582] = 0.0; + A[522] = 0.0; + A[227] = 0.0; + A[615] = A[5] - 0.0310405643738982*G0_0_1_1_0_0 + 0.0310405643738992*G0_0_1_2_0_1 + 0.0310405643738997*G0_0_1_3_0_0 - 0.0310405643738977*G0_0_1_3_0_1 - 0.0310405643738997*G0_0_1_4_0_0 - 0.0310405643738996*G0_0_1_4_0_1 + 0.0310405643738978*G0_0_1_5_0_0 + 0.0310405643738977*G0_0_1_5_0_1 - 0.0310405643738982*G0_0_1_7_1_0 + 0.0310405643738992*G0_0_1_8_1_1 + 0.0310405643738997*G0_0_1_9_1_0 - 0.0310405643738977*G0_0_1_9_1_1 - 0.0310405643738997*G0_0_1_10_1_0 - 0.0310405643738996*G0_0_1_10_1_1 + 0.0310405643738978*G0_0_1_11_1_0 + 0.0310405643738977*G0_0_1_11_1_1 + 0.0310405643738982*G0_1_0_1_0_0 - 0.0310405643738992*G0_1_0_2_0_1 - 0.0310405643738997*G0_1_0_3_0_0 + 0.0310405643738977*G0_1_0_3_0_1 + 0.0310405643738997*G0_1_0_4_0_0 + 0.0310405643738995*G0_1_0_4_0_1 - 0.0310405643738978*G0_1_0_5_0_0 - 0.0310405643738977*G0_1_0_5_0_1 + 0.0310405643738982*G0_1_0_7_1_0 - 0.0310405643738992*G0_1_0_8_1_1 - 0.0310405643738997*G0_1_0_9_1_0 + 0.0310405643738977*G0_1_0_9_1_1 + 0.0310405643738997*G0_1_0_10_1_0 + 0.0310405643738995*G0_1_0_10_1_1 - 0.0310405643738978*G0_1_0_11_1_0 - 0.0310405643738977*G0_1_0_11_1_1; + A[240] = -A[615] + 0.411992945326278*G0_1_0_0_0_0 + 0.411992945326278*G0_1_0_0_0_1 + 0.163668430335097*G0_1_0_1_0_0 + 0.0451499118165779*G0_1_0_2_0_1 - 0.158024691358025*G0_1_0_3_0_0 - 0.0395061728395061*G0_1_0_3_0_1 + 0.158024691358025*G0_1_0_4_0_0 - 0.457142857142856*G0_1_0_4_0_1 - 0.575661375661375*G0_1_0_5_0_0 + 0.0395061728395061*G0_1_0_5_0_1 + 0.411992945326278*G0_1_0_6_1_0 + 0.411992945326278*G0_1_0_6_1_1 + 0.163668430335097*G0_1_0_7_1_0 + 0.0451499118165779*G0_1_0_8_1_1 - 0.158024691358025*G0_1_0_9_1_0 - 0.0395061728395061*G0_1_0_9_1_1 + 0.158024691358025*G0_1_0_10_1_0 - 0.457142857142856*G0_1_0_10_1_1 - 0.575661375661375*G0_1_0_11_1_0 + 0.0395061728395061*G0_1_0_11_1_1 + 0.411992945326278*G0_1_1_0_0_0 + 0.411992945326278*G0_1_1_0_0_1 + 0.163668430335097*G0_1_1_1_0_0 + 0.0451499118165773*G0_1_1_2_0_1 - 0.158024691358026*G0_1_1_3_0_0 - 0.0395061728395062*G0_1_1_3_0_1 + 0.158024691358026*G0_1_1_4_0_0 - 0.457142857142855*G0_1_1_4_0_1 - 0.575661375661375*G0_1_1_5_0_0 + 0.0395061728395063*G0_1_1_5_0_1 + 0.411992945326278*G0_1_1_6_1_0 + 0.411992945326278*G0_1_1_6_1_1 + 0.163668430335097*G0_1_1_7_1_0 + 0.0451499118165773*G0_1_1_8_1_1 - 0.158024691358026*G0_1_1_9_1_0 - 0.0395061728395062*G0_1_1_9_1_1 + 0.158024691358026*G0_1_1_10_1_0 - 0.457142857142855*G0_1_1_10_1_1 - 0.575661375661375*G0_1_1_11_1_0 + 0.0395061728395063*G0_1_1_11_1_1; + A[551] = 0.0; + A[708] = -A[716] - 0.112874779541446*G0_0_0_0_0_0 - 0.112874779541446*G0_0_0_0_0_1 + 0.383774250440916*G0_0_0_1_0_0 - 0.8352733686067*G0_0_0_2_0_1 - 1.17389770723104*G0_0_0_3_0_0 + 0.0451499118165793*G0_0_0_3_0_1 + 1.17389770723104*G0_0_0_4_0_0 + 0.948148148148145*G0_0_0_4_0_1 - 0.27089947089947*G0_0_0_5_0_0 - 0.045149911816579*G0_0_0_5_0_1 - 0.112874779541446*G0_0_0_6_1_0 - 0.112874779541446*G0_0_0_6_1_1 + 0.383774250440916*G0_0_0_7_1_0 - 0.8352733686067*G0_0_0_8_1_1 - 1.17389770723104*G0_0_0_9_1_0 + 0.0451499118165793*G0_0_0_9_1_1 + 1.17389770723104*G0_0_0_10_1_0 + 0.948148148148145*G0_0_0_10_1_1 - 0.27089947089947*G0_0_0_11_1_0 - 0.045149911816579*G0_0_0_11_1_1 - 0.225749559082894*G0_1_0_0_0_0 - 0.225749559082894*G0_1_0_0_0_1 - 0.225749559082892*G0_1_0_2_0_1 - 0.225749559082893*G0_1_0_3_0_0 + 0.225749559082893*G0_1_0_4_0_0 + 0.451499118165786*G0_1_0_4_0_1 + 0.225749559082895*G0_1_0_5_0_0 - 0.225749559082894*G0_1_0_6_1_0 - 0.225749559082894*G0_1_0_6_1_1 - 0.225749559082892*G0_1_0_8_1_1 - 0.225749559082893*G0_1_0_9_1_0 + 0.225749559082893*G0_1_0_10_1_0 + 0.451499118165786*G0_1_0_10_1_1 + 0.225749559082895*G0_1_0_11_1_0; + A[644] = 0.0; + A[253] = A[718]; + A[673] = 0.0; + A[278] = A[743]; + A[698] = 0.0; + A[315] = 0.0; + A[259] = 0.0; + A[344] = A[342] + 1.08359788359788*G0_0_0_0_0_0 + 1.08359788359788*G0_0_0_0_0_1 + 1.08359788359788*G0_0_0_1_0_0 + 1.08359788359788*G0_0_0_3_0_1 - 1.08359788359788*G0_0_0_4_0_1 - 2.16719576719576*G0_0_0_5_0_0 - 1.08359788359788*G0_0_0_5_0_1 + 1.08359788359788*G0_0_0_6_1_0 + 1.08359788359788*G0_0_0_6_1_1 + 1.08359788359788*G0_0_0_7_1_0 + 1.08359788359788*G0_0_0_9_1_1 - 1.08359788359788*G0_0_0_10_1_1 - 2.16719576719576*G0_0_0_11_1_0 - 1.08359788359788*G0_0_0_11_1_1; + A[288] = 0.0; + A[742] = A[277]; + A[429] = A[830] + 0.406349206349204*G0_0_0_0_0_0 + 0.406349206349204*G0_0_0_0_0_1 + 0.135449735449736*G0_0_0_1_0_0 + 0.406349206349201*G0_0_0_2_0_1 + 0.541798941798934*G0_0_0_3_0_0 + 0.270899470899469*G0_0_0_3_0_1 - 0.541798941798934*G0_0_0_4_0_0 - 0.812698412698405*G0_0_0_4_0_1 - 0.54179894179894*G0_0_0_5_0_0 - 0.270899470899469*G0_0_0_5_0_1 + 0.406349206349204*G0_0_0_6_1_0 + 0.406349206349204*G0_0_0_6_1_1 + 0.135449735449736*G0_0_0_7_1_0 + 0.406349206349201*G0_0_0_8_1_1 + 0.541798941798934*G0_0_0_9_1_0 + 0.270899470899469*G0_0_0_9_1_1 - 0.541798941798934*G0_0_0_10_1_0 - 0.812698412698405*G0_0_0_10_1_1 - 0.54179894179894*G0_0_0_11_1_0 - 0.270899470899469*G0_0_0_11_1_1 - 0.406349206349208*G0_0_1_0_0_0 - 0.406349206349208*G0_0_1_0_0_1 - 0.135449735449735*G0_0_1_1_0_0 - 0.135449735449737*G0_0_1_2_0_1 + 0.541798941798945*G0_0_1_4_0_1 + 0.541798941798943*G0_0_1_5_0_0 - 0.406349206349208*G0_0_1_6_1_0 - 0.406349206349208*G0_0_1_6_1_1 - 0.135449735449735*G0_0_1_7_1_0 - 0.135449735449737*G0_0_1_8_1_1 + 0.541798941798945*G0_0_1_10_1_1 + 0.541798941798943*G0_0_1_11_1_0 - 0.135449735449735*G0_1_0_0_0_0 - 0.135449735449735*G0_1_0_0_0_1 + 0.406349206349208*G0_1_0_1_0_0 - 0.406349206349211*G0_1_0_2_0_1 - 0.270899470899478*G0_1_0_3_0_0 + 0.54179894179894*G0_1_0_3_0_1 + 0.270899470899478*G0_1_0_4_0_0 + 0.541798941798946*G0_1_0_4_0_1 - 0.270899470899472*G0_1_0_5_0_0 - 0.54179894179894*G0_1_0_5_0_1 - 0.135449735449735*G0_1_0_6_1_0 - 0.135449735449735*G0_1_0_6_1_1 + 0.406349206349208*G0_1_0_7_1_0 - 0.406349206349211*G0_1_0_8_1_1 - 0.270899470899478*G0_1_0_9_1_0 + 0.54179894179894*G0_1_0_9_1_1 + 0.270899470899478*G0_1_0_10_1_0 + 0.541798941798946*G0_1_0_10_1_1 - 0.270899470899472*G0_1_0_11_1_0 - 0.54179894179894*G0_1_0_11_1_1 - 0.541798941798945*G0_1_1_0_0_0 - 0.541798941798945*G0_1_1_0_0_1 - 0.541798941798944*G0_1_1_2_0_1 - 0.541798941798943*G0_1_1_3_0_0 + 0.541798941798943*G0_1_1_4_0_0 + 1.08359788359789*G0_1_1_4_0_1 + 0.541798941798945*G0_1_1_5_0_0 - 0.541798941798945*G0_1_1_6_1_0 - 0.541798941798945*G0_1_1_6_1_1 - 0.541798941798944*G0_1_1_8_1_1 - 0.541798941798943*G0_1_1_9_1_0 + 0.541798941798943*G0_1_1_10_1_0 + 1.08359788359789*G0_1_1_10_1_1 + 0.541798941798945*G0_1_1_11_1_0; + A[834] = A[429] - 2.70899470899471*G0_0_0_0_0_0 - 2.70899470899471*G0_0_0_0_0_1 - 1.62539682539682*G0_0_0_1_0_0 - 1.08359788359788*G0_0_0_2_0_1 - 1.08359788359788*G0_0_0_3_0_0 - 1.62539682539682*G0_0_0_3_0_1 + 1.08359788359788*G0_0_0_4_0_0 + 3.79259259259259*G0_0_0_4_0_1 + 4.33439153439153*G0_0_0_5_0_0 + 1.62539682539682*G0_0_0_5_0_1 - 2.70899470899471*G0_0_0_6_1_0 - 2.70899470899471*G0_0_0_6_1_1 - 1.62539682539682*G0_0_0_7_1_0 - 1.08359788359788*G0_0_0_8_1_1 - 1.08359788359788*G0_0_0_9_1_0 - 1.62539682539682*G0_0_0_9_1_1 + 1.08359788359788*G0_0_0_10_1_0 + 3.79259259259259*G0_0_0_10_1_1 + 4.33439153439153*G0_0_0_11_1_0 + 1.62539682539682*G0_0_0_11_1_1 + 0.541798941798942*G0_0_1_0_0_0 + 0.541798941798941*G0_0_1_0_0_1 - 0.541798941798942*G0_0_1_1_0_0 - 0.541798941798944*G0_0_1_2_0_1 - 2.16719576719577*G0_0_1_3_0_0 - 2.16719576719577*G0_0_1_3_0_1 + 2.16719576719577*G0_0_1_4_0_0 + 2.16719576719577*G0_0_1_5_0_1 + 0.541798941798942*G0_0_1_6_1_0 + 0.541798941798941*G0_0_1_6_1_1 - 0.541798941798942*G0_0_1_7_1_0 - 0.541798941798944*G0_0_1_8_1_1 - 2.16719576719577*G0_0_1_9_1_0 - 2.16719576719577*G0_0_1_9_1_1 + 2.16719576719577*G0_0_1_10_1_0 + 2.16719576719577*G0_0_1_11_1_1 - 1.62539682539683*G0_1_0_1_0_0 - 1.62539682539682*G0_1_0_3_0_0 - 3.25079365079365*G0_1_0_3_0_1 + 1.62539682539682*G0_1_0_4_0_0 + 1.62539682539683*G0_1_0_5_0_0 + 3.25079365079365*G0_1_0_5_0_1 - 1.62539682539683*G0_1_0_7_1_0 - 1.62539682539682*G0_1_0_9_1_0 - 3.25079365079365*G0_1_0_9_1_1 + 1.62539682539682*G0_1_0_10_1_0 + 1.62539682539683*G0_1_0_11_1_0 + 3.25079365079365*G0_1_0_11_1_1 + 3.25079365079365*G0_1_1_0_0_0 + 3.25079365079365*G0_1_1_0_0_1 - 1.08359788359788*G0_1_1_1_0_0 + 1.08359788359788*G0_1_1_2_0_1 - 2.16719576719577*G0_1_1_3_0_0 - 4.33439153439153*G0_1_1_3_0_1 + 2.16719576719577*G0_1_1_4_0_0 - 4.33439153439153*G0_1_1_4_0_1 - 2.16719576719576*G0_1_1_5_0_0 + 4.33439153439153*G0_1_1_5_0_1 + 3.25079365079365*G0_1_1_6_1_0 + 3.25079365079365*G0_1_1_6_1_1 - 1.08359788359788*G0_1_1_7_1_0 + 1.08359788359788*G0_1_1_8_1_1 - 2.16719576719577*G0_1_1_9_1_0 - 4.33439153439153*G0_1_1_9_1_1 + 2.16719576719577*G0_1_1_10_1_0 - 4.33439153439153*G0_1_1_10_1_1 - 2.16719576719576*G0_1_1_11_1_0 + 4.33439153439153*G0_1_1_11_1_1; + A[747] = A[834] - 0.451499118165783*G0_0_1_0_0_0 - 0.451499118165782*G0_0_1_0_0_1 - 0.812698412698412*G0_0_1_1_0_0 + 0.361199294532629*G0_0_1_2_0_1 + 0.36119929453263*G0_0_1_3_0_0 - 0.81269841269841*G0_0_1_3_0_1 - 0.36119929453263*G0_0_1_4_0_0 + 0.0902998236331524*G0_0_1_4_0_1 + 1.26419753086419*G0_0_1_5_0_0 + 0.812698412698411*G0_0_1_5_0_1 - 0.451499118165783*G0_0_1_6_1_0 - 0.451499118165782*G0_0_1_6_1_1 - 0.812698412698412*G0_0_1_7_1_0 + 0.361199294532629*G0_0_1_8_1_1 + 0.36119929453263*G0_0_1_9_1_0 - 0.81269841269841*G0_0_1_9_1_1 - 0.36119929453263*G0_0_1_10_1_0 + 0.0902998236331524*G0_0_1_10_1_1 + 1.26419753086419*G0_0_1_11_1_0 + 0.812698412698411*G0_0_1_11_1_1 + 0.451499118165783*G0_1_0_0_0_0 + 0.451499118165782*G0_1_0_0_0_1 + 0.812698412698412*G0_1_0_1_0_0 - 0.361199294532629*G0_1_0_2_0_1 - 0.36119929453263*G0_1_0_3_0_0 + 0.81269841269841*G0_1_0_3_0_1 + 0.36119929453263*G0_1_0_4_0_0 - 0.0902998236331525*G0_1_0_4_0_1 - 1.26419753086419*G0_1_0_5_0_0 - 0.81269841269841*G0_1_0_5_0_1 + 0.451499118165783*G0_1_0_6_1_0 + 0.451499118165782*G0_1_0_6_1_1 + 0.812698412698412*G0_1_0_7_1_0 - 0.361199294532629*G0_1_0_8_1_1 - 0.36119929453263*G0_1_0_9_1_0 + 0.81269841269841*G0_1_0_9_1_1 + 0.36119929453263*G0_1_0_10_1_0 - 0.0902998236331525*G0_1_0_10_1_1 - 1.26419753086419*G0_1_0_11_1_0 - 0.81269841269841*G0_1_0_11_1_1; + A[369] = A[834]; + A[50] = 0.0; + A[773] = A[308]; + A[462] = 0.0; + A[402] = A[373] - 0.541798941798942*G0_0_1_0_0_0 - 0.541798941798942*G0_0_1_0_0_1 + 0.54179894179894*G0_0_1_1_0_0 - 1.08359788359788*G0_0_1_2_0_1 - 1.08359788359789*G0_0_1_3_0_0 + 0.541798941798938*G0_0_1_3_0_1 + 1.08359788359789*G0_0_1_4_0_0 + 1.62539682539682*G0_0_1_4_0_1 - 0.541798941798939*G0_0_1_5_0_1 - 0.541798941798942*G0_0_1_6_1_0 - 0.541798941798942*G0_0_1_6_1_1 + 0.54179894179894*G0_0_1_7_1_0 - 1.08359788359788*G0_0_1_8_1_1 - 1.08359788359789*G0_0_1_9_1_0 + 0.541798941798938*G0_0_1_9_1_1 + 1.08359788359789*G0_0_1_10_1_0 + 1.62539682539682*G0_0_1_10_1_1 - 0.541798941798939*G0_0_1_11_1_1 + 0.541798941798942*G0_1_0_0_0_0 + 0.541798941798942*G0_1_0_0_0_1 - 0.54179894179894*G0_1_0_1_0_0 + 1.08359788359788*G0_1_0_2_0_1 + 1.08359788359789*G0_1_0_3_0_0 - 0.541798941798938*G0_1_0_3_0_1 - 1.08359788359789*G0_1_0_4_0_0 - 1.62539682539682*G0_1_0_4_0_1 + 0.541798941798939*G0_1_0_5_0_1 + 0.541798941798942*G0_1_0_6_1_0 + 0.541798941798942*G0_1_0_6_1_1 - 0.54179894179894*G0_1_0_7_1_0 + 1.08359788359788*G0_1_0_8_1_1 + 1.08359788359789*G0_1_0_9_1_0 - 0.541798941798938*G0_1_0_9_1_1 - 1.08359788359789*G0_1_0_10_1_0 - 1.62539682539682*G0_1_0_10_1_1 + 0.541798941798939*G0_1_0_11_1_1; + A[79] = 0.0; + A[800] = A[335]; + A[15] = 0.0; + A[100] = A[565]; + A[835] = A[370]; + A[44] = A[509]; + A[133] = A[394] + 0.541798941798941*G0_0_1_0_0_0 + 0.541798941798941*G0_0_1_0_0_1 + 0.744973544973543*G0_0_1_1_0_0 - 0.203174603174602*G0_0_1_2_0_1 - 0.203174603174601*G0_0_1_3_0_0 + 0.744973544973544*G0_0_1_3_0_1 + 0.203174603174601*G0_0_1_4_0_0 - 0.338624338624339*G0_0_1_4_0_1 - 1.28677248677248*G0_0_1_5_0_0 - 0.744973544973544*G0_0_1_5_0_1 + 0.541798941798941*G0_0_1_6_1_0 + 0.541798941798941*G0_0_1_6_1_1 + 0.744973544973543*G0_0_1_7_1_0 - 0.203174603174602*G0_0_1_8_1_1 - 0.203174603174601*G0_0_1_9_1_0 + 0.744973544973544*G0_0_1_9_1_1 + 0.203174603174601*G0_0_1_10_1_0 - 0.338624338624339*G0_0_1_10_1_1 - 1.28677248677248*G0_0_1_11_1_0 - 0.744973544973544*G0_0_1_11_1_1 - 0.541798941798941*G0_1_0_0_0_0 - 0.541798941798941*G0_1_0_0_0_1 - 0.744973544973543*G0_1_0_1_0_0 + 0.203174603174602*G0_1_0_2_0_1 + 0.203174603174601*G0_1_0_3_0_0 - 0.744973544973544*G0_1_0_3_0_1 - 0.203174603174601*G0_1_0_4_0_0 + 0.338624338624339*G0_1_0_4_0_1 + 1.28677248677248*G0_1_0_5_0_0 + 0.744973544973544*G0_1_0_5_0_1 - 0.541798941798941*G0_1_0_6_1_0 - 0.541798941798941*G0_1_0_6_1_1 - 0.744973544973543*G0_1_0_7_1_0 + 0.203174603174602*G0_1_0_8_1_1 + 0.203174603174601*G0_1_0_9_1_0 - 0.744973544973544*G0_1_0_9_1_1 - 0.203174603174601*G0_1_0_10_1_0 + 0.338624338624339*G0_1_0_10_1_1 + 1.28677248677248*G0_1_0_11_1_0 + 0.744973544973544*G0_1_0_11_1_1; + A[842] = 0.0; + A[73] = A[538]; + A[150] = A[615]; + A[873] = 0.0; + A[106] = 0.0; + A[195] = 0.0; + A[591] = A[126]; + A[515] = 0.0; + A[224] = A[892] + 0.203174603174607*G0_0_1_0_0_0 + 0.203174603174607*G0_0_1_0_0_1 - 0.541798941798943*G0_0_1_1_0_0 + 0.74497354497355*G0_0_1_2_0_1 + 0.74497354497355*G0_0_1_3_0_0 - 0.541798941798941*G0_0_1_3_0_1 - 0.74497354497355*G0_0_1_4_0_0 - 0.948148148148157*G0_0_1_4_0_1 + 0.338624338624335*G0_0_1_5_0_0 + 0.541798941798941*G0_0_1_5_0_1 + 0.203174603174607*G0_0_1_6_1_0 + 0.203174603174607*G0_0_1_6_1_1 - 0.541798941798943*G0_0_1_7_1_0 + 0.74497354497355*G0_0_1_8_1_1 + 0.74497354497355*G0_0_1_9_1_0 - 0.541798941798941*G0_0_1_9_1_1 - 0.74497354497355*G0_0_1_10_1_0 - 0.948148148148157*G0_0_1_10_1_1 + 0.338624338624335*G0_0_1_11_1_0 + 0.541798941798941*G0_0_1_11_1_1 - 0.203174603174607*G0_1_0_0_0_0 - 0.203174603174607*G0_1_0_0_0_1 + 0.541798941798943*G0_1_0_1_0_0 - 0.74497354497355*G0_1_0_2_0_1 - 0.744973544973551*G0_1_0_3_0_0 + 0.541798941798941*G0_1_0_3_0_1 + 0.744973544973551*G0_1_0_4_0_0 + 0.948148148148157*G0_1_0_4_0_1 - 0.338624338624335*G0_1_0_5_0_0 - 0.541798941798941*G0_1_0_5_0_1 - 0.203174603174607*G0_1_0_6_1_0 - 0.203174603174607*G0_1_0_6_1_1 + 0.541798941798943*G0_1_0_7_1_0 - 0.74497354497355*G0_1_0_8_1_1 - 0.744973544973551*G0_1_0_9_1_0 + 0.541798941798941*G0_1_0_9_1_1 + 0.744973544973551*G0_1_0_10_1_0 + 0.948148148148157*G0_1_0_10_1_1 - 0.338624338624335*G0_1_0_11_1_0 - 0.541798941798941*G0_1_0_11_1_1; + A[622] = A[157]; + A[542] = 0.0; + A[653] = A[711] - 0.451499118165786*G0_0_1_0_0_0 - 0.451499118165786*G0_0_1_0_0_1 - 0.361199294532628*G0_0_1_1_0_0 + 0.451499118165783*G0_0_1_2_0_1 + 0.993298059964725*G0_0_1_3_0_0 + 0.180599647266314*G0_0_1_3_0_1 - 0.993298059964725*G0_0_1_4_0_0 + 0.812698412698413*G0_0_1_5_0_0 - 0.180599647266314*G0_0_1_5_0_1 - 0.451499118165786*G0_0_1_6_1_0 - 0.451499118165786*G0_0_1_6_1_1 - 0.361199294532628*G0_0_1_7_1_0 + 0.451499118165783*G0_0_1_8_1_1 + 0.993298059964725*G0_0_1_9_1_0 + 0.180599647266314*G0_0_1_9_1_1 - 0.993298059964725*G0_0_1_10_1_0 + 0.812698412698413*G0_0_1_11_1_0 - 0.180599647266314*G0_0_1_11_1_1 + 0.451499118165786*G0_1_0_0_0_0 + 0.451499118165786*G0_1_0_0_0_1 + 0.361199294532628*G0_1_0_1_0_0 - 0.451499118165783*G0_1_0_2_0_1 - 0.993298059964725*G0_1_0_3_0_0 - 0.180599647266314*G0_1_0_3_0_1 + 0.993298059964725*G0_1_0_4_0_0 - 0.812698412698413*G0_1_0_5_0_0 + 0.180599647266314*G0_1_0_5_0_1 + 0.451499118165786*G0_1_0_6_1_0 + 0.451499118165786*G0_1_0_6_1_1 + 0.361199294532628*G0_1_0_7_1_0 - 0.451499118165783*G0_1_0_8_1_1 - 0.993298059964725*G0_1_0_9_1_0 - 0.180599647266314*G0_1_0_9_1_1 + 0.993298059964725*G0_1_0_10_1_0 - 0.812698412698413*G0_1_0_11_1_0 + 0.180599647266314*G0_1_0_11_1_1; + A[664] = 0.0; + A[691] = 0.0; + A[266] = 0.0; + A[337] = A[802]; + A[297] = 0.0; + A[749] = A[429] + 0.0902998236331607*G0_0_1_0_0_0 + 0.0902998236331606*G0_0_1_0_0_1 + 0.270899470899472*G0_0_1_1_0_0 - 0.180599647266315*G0_0_1_2_0_1 - 0.180599647266319*G0_0_1_3_0_0 + 0.270899470899467*G0_0_1_3_0_1 + 0.180599647266319*G0_0_1_4_0_0 + 0.0902998236331542*G0_0_1_4_0_1 - 0.361199294532632*G0_0_1_5_0_0 - 0.270899470899467*G0_0_1_5_0_1 + 0.0902998236331607*G0_0_1_6_1_0 + 0.0902998236331606*G0_0_1_6_1_1 + 0.270899470899472*G0_0_1_7_1_0 - 0.180599647266315*G0_0_1_8_1_1 - 0.180599647266319*G0_0_1_9_1_0 + 0.270899470899467*G0_0_1_9_1_1 + 0.180599647266319*G0_0_1_10_1_0 + 0.0902998236331542*G0_0_1_10_1_1 - 0.361199294532632*G0_0_1_11_1_0 - 0.270899470899467*G0_0_1_11_1_1 - 0.0902998236331606*G0_1_0_0_0_0 - 0.0902998236331607*G0_1_0_0_0_1 - 0.270899470899472*G0_1_0_1_0_0 + 0.180599647266315*G0_1_0_2_0_1 + 0.180599647266318*G0_1_0_3_0_0 - 0.270899470899467*G0_1_0_3_0_1 - 0.180599647266318*G0_1_0_4_0_0 - 0.0902998236331543*G0_1_0_4_0_1 + 0.361199294532632*G0_1_0_5_0_0 + 0.270899470899468*G0_1_0_5_0_1 - 0.0902998236331606*G0_1_0_6_1_0 - 0.0902998236331607*G0_1_0_6_1_1 - 0.270899470899472*G0_1_0_7_1_0 + 0.180599647266315*G0_1_0_8_1_1 + 0.180599647266318*G0_1_0_9_1_0 - 0.270899470899467*G0_1_0_9_1_1 - 0.180599647266318*G0_1_0_10_1_0 - 0.0902998236331543*G0_1_0_10_1_1 + 0.361199294532632*G0_1_0_11_1_0 + 0.270899470899468*G0_1_0_11_1_1; + A[748] = A[749] + 1.08359788359788*G0_0_0_0_0_0 + 1.08359788359788*G0_0_0_0_0_1 + 1.08359788359788*G0_0_0_1_0_0 + 1.08359788359788*G0_0_0_3_0_1 - 1.08359788359788*G0_0_0_4_0_1 - 2.16719576719576*G0_0_0_5_0_0 - 1.08359788359788*G0_0_0_5_0_1 + 1.08359788359788*G0_0_0_6_1_0 + 1.08359788359788*G0_0_0_6_1_1 + 1.08359788359788*G0_0_0_7_1_0 + 1.08359788359788*G0_0_0_9_1_1 - 1.08359788359788*G0_0_0_10_1_1 - 2.16719576719576*G0_0_0_11_1_0 - 1.08359788359788*G0_0_0_11_1_1 + 1.08359788359788*G0_0_1_0_0_0 + 1.08359788359788*G0_0_1_0_0_1 + 1.08359788359788*G0_0_1_1_0_0 + 1.08359788359788*G0_0_1_3_0_1 - 1.08359788359787*G0_0_1_4_0_1 - 2.16719576719575*G0_0_1_5_0_0 - 1.08359788359788*G0_0_1_5_0_1 + 1.08359788359788*G0_0_1_6_1_0 + 1.08359788359788*G0_0_1_6_1_1 + 1.08359788359788*G0_0_1_7_1_0 + 1.08359788359788*G0_0_1_9_1_1 - 1.08359788359787*G0_0_1_10_1_1 - 2.16719576719575*G0_0_1_11_1_0 - 1.08359788359788*G0_0_1_11_1_1 + 1.08359788359788*G0_1_0_0_0_0 + 1.08359788359788*G0_1_0_0_0_1 + 1.08359788359788*G0_1_0_1_0_0 + 1.08359788359788*G0_1_0_3_0_1 - 1.08359788359788*G0_1_0_4_0_1 - 2.16719576719576*G0_1_0_5_0_0 - 1.08359788359788*G0_1_0_5_0_1 + 1.08359788359788*G0_1_0_6_1_0 + 1.08359788359788*G0_1_0_6_1_1 + 1.08359788359788*G0_1_0_7_1_0 + 1.08359788359788*G0_1_0_9_1_1 - 1.08359788359788*G0_1_0_10_1_1 - 2.16719576719576*G0_1_0_11_1_0 - 1.08359788359788*G0_1_0_11_1_1 + 1.08359788359789*G0_1_1_0_0_0 + 1.08359788359789*G0_1_1_0_0_1 + 1.08359788359788*G0_1_1_1_0_0 + 1.08359788359788*G0_1_1_3_0_1 - 1.08359788359789*G0_1_1_4_0_1 - 2.16719576719577*G0_1_1_5_0_0 - 1.08359788359788*G0_1_1_5_0_1 + 1.08359788359789*G0_1_1_6_1_0 + 1.08359788359789*G0_1_1_6_1_1 + 1.08359788359788*G0_1_1_7_1_0 + 1.08359788359788*G0_1_1_9_1_1 - 1.08359788359789*G0_1_1_10_1_1 - 2.16719576719577*G0_1_1_11_1_0 - 1.08359788359788*G0_1_1_11_1_1; + A[864] = A[748] - 0.0902998236331543*G0_0_1_0_0_0 - 0.0902998236331543*G0_0_1_0_0_1 - 0.270899470899469*G0_0_1_1_0_0 + 0.180599647266315*G0_0_1_2_0_1 + 0.180599647266316*G0_0_1_3_0_0 - 0.270899470899469*G0_0_1_3_0_1 - 0.180599647266316*G0_0_1_4_0_0 - 0.0902998236331614*G0_0_1_4_0_1 + 0.361199294532623*G0_0_1_5_0_0 + 0.270899470899469*G0_0_1_5_0_1 - 0.0902998236331543*G0_0_1_6_1_0 - 0.0902998236331543*G0_0_1_6_1_1 - 0.270899470899469*G0_0_1_7_1_0 + 0.180599647266315*G0_0_1_8_1_1 + 0.180599647266316*G0_0_1_9_1_0 - 0.270899470899469*G0_0_1_9_1_1 - 0.180599647266316*G0_0_1_10_1_0 - 0.0902998236331614*G0_0_1_10_1_1 + 0.361199294532623*G0_0_1_11_1_0 + 0.270899470899469*G0_0_1_11_1_1 + 0.0902998236331543*G0_1_0_0_0_0 + 0.0902998236331543*G0_1_0_0_0_1 + 0.270899470899469*G0_1_0_1_0_0 - 0.180599647266315*G0_1_0_2_0_1 - 0.180599647266316*G0_1_0_3_0_0 + 0.270899470899468*G0_1_0_3_0_1 + 0.180599647266316*G0_1_0_4_0_0 + 0.0902998236331614*G0_1_0_4_0_1 - 0.361199294532623*G0_1_0_5_0_0 - 0.270899470899469*G0_1_0_5_0_1 + 0.0902998236331543*G0_1_0_6_1_0 + 0.0902998236331543*G0_1_0_6_1_1 + 0.270899470899469*G0_1_0_7_1_0 - 0.180599647266315*G0_1_0_8_1_1 - 0.180599647266316*G0_1_0_9_1_0 + 0.270899470899468*G0_1_0_9_1_1 + 0.180599647266316*G0_1_0_10_1_0 + 0.0902998236331614*G0_1_0_10_1_1 - 0.361199294532623*G0_1_0_11_1_0 - 0.270899470899469*G0_1_0_11_1_1; + A[283] = A[748]; + A[399] = A[864]; + A[436] = 0.0; + A[360] = -A[594] + 0.744973544973543*G0_0_0_0_0_0 + 0.744973544973543*G0_0_0_0_0_1 + 0.372486772486772*G0_0_0_1_0_0 + 0.22010582010582*G0_0_0_2_0_1 + 0.0677248677248683*G0_0_0_3_0_0 + 0.22010582010582*G0_0_0_3_0_1 - 0.0677248677248683*G0_0_0_4_0_0 - 0.965079365079362*G0_0_0_4_0_1 - 1.11746031746031*G0_0_0_5_0_0 - 0.22010582010582*G0_0_0_5_0_1 + 0.744973544973543*G0_0_0_6_1_0 + 0.744973544973543*G0_0_0_6_1_1 + 0.372486772486772*G0_0_0_7_1_0 + 0.22010582010582*G0_0_0_8_1_1 + 0.0677248677248683*G0_0_0_9_1_0 + 0.22010582010582*G0_0_0_9_1_1 - 0.0677248677248683*G0_0_0_10_1_0 - 0.965079365079362*G0_0_0_10_1_1 - 1.11746031746031*G0_0_0_11_1_0 - 0.22010582010582*G0_0_0_11_1_1 + 0.74779541446208*G0_0_1_0_0_0 + 0.74779541446208*G0_0_1_0_0_1 + 0.35837742504409*G0_0_1_1_0_0 + 0.194708994708994*G0_0_1_2_0_1 + 0.163668430335094*G0_0_1_3_0_1 - 0.942504409171074*G0_0_1_4_0_1 - 1.10617283950617*G0_0_1_5_0_0 - 0.163668430335094*G0_0_1_5_0_1 + 0.74779541446208*G0_0_1_6_1_0 + 0.74779541446208*G0_0_1_6_1_1 + 0.35837742504409*G0_0_1_7_1_0 + 0.194708994708994*G0_0_1_8_1_1 + 0.163668430335094*G0_0_1_9_1_1 - 0.942504409171074*G0_0_1_10_1_1 - 1.10617283950617*G0_0_1_11_1_0 - 0.163668430335094*G0_0_1_11_1_1 + 0.736507936507936*G0_1_0_0_0_0 + 0.736507936507936*G0_1_0_0_0_1 + 0.262433862433863*G0_1_0_1_0_0 + 0.279365079365079*G0_1_0_2_0_1 + 0.0846560846560857*G0_1_0_3_0_0 + 0.0677248677248697*G0_1_0_3_0_1 - 0.0846560846560857*G0_1_0_4_0_0 - 1.01587301587302*G0_1_0_4_0_1 - 0.998941798941799*G0_1_0_5_0_0 - 0.06772486772487*G0_1_0_5_0_1 + 0.736507936507936*G0_1_0_6_1_0 + 0.736507936507936*G0_1_0_6_1_1 + 0.262433862433863*G0_1_0_7_1_0 + 0.279365079365079*G0_1_0_8_1_1 + 0.0846560846560857*G0_1_0_9_1_0 + 0.0677248677248697*G0_1_0_9_1_1 - 0.0846560846560857*G0_1_0_10_1_0 - 1.01587301587302*G0_1_0_10_1_1 - 0.998941798941799*G0_1_0_11_1_0 - 0.06772486772487*G0_1_0_11_1_1 + 0.739329805996472*G0_1_1_0_0_0 + 0.739329805996472*G0_1_1_0_0_1 + 0.237037037037036*G0_1_1_1_0_0 + 0.265255731922399*G0_1_1_2_0_1 + 0.0282186948853614*G0_1_1_3_0_0 - 0.0282186948853614*G0_1_1_4_0_0 - 1.00458553791887*G0_1_1_4_0_1 - 0.976366843033507*G0_1_1_5_0_0 + 0.739329805996472*G0_1_1_6_1_0 + 0.739329805996472*G0_1_1_6_1_1 + 0.237037037037036*G0_1_1_7_1_0 + 0.265255731922399*G0_1_1_8_1_1 + 0.0282186948853614*G0_1_1_9_1_0 - 0.0282186948853614*G0_1_1_10_1_0 - 1.00458553791887*G0_1_1_10_1_1 - 0.976366843033507*G0_1_1_11_1_0; + A[316] = 0.0; + A[774] = A[309]; + A[471] = A[645] + 1.96966490299823*G0_0_1_0_0_0 + 1.96966490299823*G0_0_1_0_0_1 + 0.595414462081128*G0_0_1_1_0_0 + 0.595414462081128*G0_0_1_2_0_1 - 0.183421516754848*G0_0_1_3_0_0 - 0.183421516754849*G0_0_1_3_0_1 + 0.183421516754848*G0_0_1_4_0_0 - 2.56507936507936*G0_0_1_4_0_1 - 2.56507936507936*G0_0_1_5_0_0 + 0.18342151675485*G0_0_1_5_0_1 + 1.96966490299823*G0_0_1_6_1_0 + 1.96966490299823*G0_0_1_6_1_1 + 0.595414462081128*G0_0_1_7_1_0 + 0.595414462081128*G0_0_1_8_1_1 - 0.183421516754848*G0_0_1_9_1_0 - 0.183421516754849*G0_0_1_9_1_1 + 0.183421516754848*G0_0_1_10_1_0 - 2.56507936507936*G0_0_1_10_1_1 - 2.56507936507936*G0_0_1_11_1_0 + 0.18342151675485*G0_0_1_11_1_1 - 1.96966490299823*G0_1_0_0_0_0 - 1.96966490299823*G0_1_0_0_0_1 - 0.595414462081128*G0_1_0_1_0_0 - 0.595414462081128*G0_1_0_2_0_1 + 0.183421516754848*G0_1_0_3_0_0 + 0.183421516754849*G0_1_0_3_0_1 - 0.183421516754848*G0_1_0_4_0_0 + 2.56507936507936*G0_1_0_4_0_1 + 2.56507936507936*G0_1_0_5_0_0 - 0.18342151675485*G0_1_0_5_0_1 - 1.96966490299823*G0_1_0_6_1_0 - 1.96966490299823*G0_1_0_6_1_1 - 0.595414462081128*G0_1_0_7_1_0 - 0.595414462081128*G0_1_0_8_1_1 + 0.183421516754848*G0_1_0_9_1_0 + 0.183421516754849*G0_1_0_9_1_1 - 0.183421516754848*G0_1_0_10_1_0 + 2.56507936507936*G0_1_0_10_1_1 + 2.56507936507936*G0_1_0_11_1_0 - 0.18342151675485*G0_1_0_11_1_1; + A[395] = A[860]; + A[359] = 0.0; + A[6] = A[471]; + A[723] = 0.0; + A[37] = A[502]; + A[752] = 0.0; + A[865] = A[224] - 2.20105820105819*G0_0_0_0_0_0 - 2.20105820105819*G0_0_0_0_0_1 - 3.62328042328042*G0_0_0_1_0_0 + 4.16507936507937*G0_0_0_2_0_1 + 6.90793650793651*G0_0_0_3_0_0 - 0.880423280423274*G0_0_0_3_0_1 - 6.90793650793651*G0_0_0_4_0_0 - 1.96402116402118*G0_0_0_4_0_1 + 5.82433862433861*G0_0_0_5_0_0 + 0.880423280423274*G0_0_0_5_0_1 - 2.20105820105819*G0_0_0_6_1_0 - 2.20105820105819*G0_0_0_6_1_1 - 3.62328042328042*G0_0_0_7_1_0 + 4.16507936507937*G0_0_0_8_1_1 + 6.90793650793651*G0_0_0_9_1_0 - 0.880423280423274*G0_0_0_9_1_1 - 6.90793650793651*G0_0_0_10_1_0 - 1.96402116402118*G0_0_0_10_1_1 + 5.82433862433861*G0_0_0_11_1_0 + 0.880423280423274*G0_0_0_11_1_1 - 2.77671957671957*G0_0_1_1_0_0 + 2.77671957671958*G0_0_1_2_0_1 + 2.77671957671958*G0_0_1_3_0_0 - 2.77671957671957*G0_0_1_3_0_1 - 2.77671957671958*G0_0_1_4_0_0 - 2.77671957671958*G0_0_1_4_0_1 + 2.77671957671956*G0_0_1_5_0_0 + 2.77671957671957*G0_0_1_5_0_1 - 2.77671957671957*G0_0_1_7_1_0 + 2.77671957671958*G0_0_1_8_1_1 + 2.77671957671958*G0_0_1_9_1_0 - 2.77671957671957*G0_0_1_9_1_1 - 2.77671957671958*G0_0_1_10_1_0 - 2.77671957671958*G0_0_1_10_1_1 + 2.77671957671956*G0_0_1_11_1_0 + 2.77671957671957*G0_0_1_11_1_1 - 4.06349206349206*G0_1_0_1_0_0 + 4.06349206349207*G0_1_0_2_0_1 + 4.06349206349207*G0_1_0_3_0_0 - 4.06349206349206*G0_1_0_3_0_1 - 4.06349206349207*G0_1_0_4_0_0 - 4.06349206349208*G0_1_0_4_0_1 + 4.06349206349205*G0_1_0_5_0_0 + 4.06349206349206*G0_1_0_5_0_1 - 4.06349206349206*G0_1_0_7_1_0 + 4.06349206349207*G0_1_0_8_1_1 + 4.06349206349207*G0_1_0_9_1_0 - 4.06349206349206*G0_1_0_9_1_1 - 4.06349206349207*G0_1_0_10_1_0 - 4.06349206349208*G0_1_0_10_1_1 + 4.06349206349205*G0_1_0_11_1_0 + 4.06349206349206*G0_1_0_11_1_1 + 2.20105820105821*G0_1_1_0_0_0 + 2.2010582010582*G0_1_1_0_0_1 - 4.16507936507936*G0_1_1_1_0_0 + 3.62328042328042*G0_1_1_2_0_1 + 0.880423280423289*G0_1_1_3_0_0 - 6.90793650793649*G0_1_1_3_0_1 - 0.880423280423289*G0_1_1_4_0_0 - 5.82433862433863*G0_1_1_4_0_1 + 1.96402116402115*G0_1_1_5_0_0 + 6.9079365079365*G0_1_1_5_0_1 + 2.20105820105821*G0_1_1_6_1_0 + 2.2010582010582*G0_1_1_6_1_1 - 4.16507936507936*G0_1_1_7_1_0 + 3.62328042328042*G0_1_1_8_1_1 + 0.880423280423289*G0_1_1_9_1_0 - 6.90793650793649*G0_1_1_9_1_1 - 0.880423280423289*G0_1_1_10_1_0 - 5.82433862433863*G0_1_1_10_1_1 + 1.96402116402115*G0_1_1_11_1_0 + 6.9079365079365*G0_1_1_11_1_1; + A[64] = -A[67] + 0.0282186948853627*G0_1_0_0_0_0 + 0.0282186948853627*G0_1_0_0_0_1 + 0.0282186948853613*G0_1_0_1_0_0 + 0.0282186948853625*G0_1_0_3_0_1 - 0.0282186948853653*G0_1_0_4_0_1 - 0.0564373897707239*G0_1_0_5_0_0 - 0.0282186948853625*G0_1_0_5_0_1 + 0.0282186948853627*G0_1_0_6_1_0 + 0.0282186948853627*G0_1_0_6_1_1 + 0.0282186948853613*G0_1_0_7_1_0 + 0.0282186948853625*G0_1_0_9_1_1 - 0.0282186948853653*G0_1_0_10_1_1 - 0.0564373897707239*G0_1_0_11_1_0 - 0.0282186948853625*G0_1_0_11_1_1 - 0.0331569664902979*G0_1_1_0_0_0 - 0.0331569664902979*G0_1_1_0_0_1 + 0.0613756613756621*G0_1_1_1_0_0 + 0.415520282186951*G0_1_1_2_0_1 + 0.92557319223986*G0_1_1_3_0_0 + 0.571428571428572*G0_1_1_3_0_1 - 0.92557319223986*G0_1_1_4_0_0 - 0.382363315696652*G0_1_1_4_0_1 - 0.028218694885364*G0_1_1_5_0_0 - 0.571428571428573*G0_1_1_5_0_1 - 0.0331569664902979*G0_1_1_6_1_0 - 0.0331569664902979*G0_1_1_6_1_1 + 0.0613756613756621*G0_1_1_7_1_0 + 0.415520282186951*G0_1_1_8_1_1 + 0.92557319223986*G0_1_1_9_1_0 + 0.571428571428572*G0_1_1_9_1_1 - 0.92557319223986*G0_1_1_10_1_0 - 0.382363315696652*G0_1_1_10_1_1 - 0.028218694885364*G0_1_1_11_1_0 - 0.571428571428573*G0_1_1_11_1_1; + A[159] = A[624]; + A[898] = A[869] + 1.08359788359788*G0_0_1_0_0_0 + 1.08359788359788*G0_0_1_0_0_1 + 0.541798941798944*G0_0_1_1_0_0 + 0.541798941798939*G0_0_1_2_0_1 + 0.541798941798938*G0_0_1_3_0_0 + 0.541798941798944*G0_0_1_3_0_1 - 0.541798941798938*G0_0_1_4_0_0 - 1.62539682539682*G0_0_1_4_0_1 - 1.62539682539683*G0_0_1_5_0_0 - 0.541798941798944*G0_0_1_5_0_1 + 1.08359788359788*G0_0_1_6_1_0 + 1.08359788359788*G0_0_1_6_1_1 + 0.541798941798944*G0_0_1_7_1_0 + 0.541798941798939*G0_0_1_8_1_1 + 0.541798941798938*G0_0_1_9_1_0 + 0.541798941798944*G0_0_1_9_1_1 - 0.541798941798938*G0_0_1_10_1_0 - 1.62539682539682*G0_0_1_10_1_1 - 1.62539682539683*G0_0_1_11_1_0 - 0.541798941798944*G0_0_1_11_1_1 - 1.08359788359788*G0_1_0_0_0_0 - 1.08359788359788*G0_1_0_0_0_1 - 0.541798941798944*G0_1_0_1_0_0 - 0.541798941798939*G0_1_0_2_0_1 - 0.541798941798938*G0_1_0_3_0_0 - 0.541798941798944*G0_1_0_3_0_1 + 0.541798941798938*G0_1_0_4_0_0 + 1.62539682539682*G0_1_0_4_0_1 + 1.62539682539683*G0_1_0_5_0_0 + 0.541798941798944*G0_1_0_5_0_1 - 1.08359788359788*G0_1_0_6_1_0 - 1.08359788359788*G0_1_0_6_1_1 - 0.541798941798944*G0_1_0_7_1_0 - 0.541798941798939*G0_1_0_8_1_1 - 0.541798941798938*G0_1_0_9_1_0 - 0.541798941798944*G0_1_0_9_1_1 + 0.541798941798938*G0_1_0_10_1_0 + 1.62539682539682*G0_1_0_10_1_1 + 1.62539682539683*G0_1_0_11_1_0 + 0.541798941798944*G0_1_0_11_1_1; + A[115] = 0.0; + A[186] = A[711] - 2.57354497354497*G0_0_0_0_0_0 - 2.57354497354497*G0_0_0_0_0_1 - 0.857848324514991*G0_0_0_1_0_0 - 0.22574955908289*G0_0_0_2_0_1 + 1.2641975308642*G0_0_0_3_0_0 + 0.632098765432098*G0_0_0_3_0_1 - 1.2641975308642*G0_0_0_4_0_0 + 2.79929453262786*G0_0_0_4_0_1 + 3.43139329805996*G0_0_0_5_0_0 - 0.632098765432098*G0_0_0_5_0_1 - 2.57354497354497*G0_0_0_6_1_0 - 2.57354497354497*G0_0_0_6_1_1 - 0.857848324514991*G0_0_0_7_1_0 - 0.22574955908289*G0_0_0_8_1_1 + 1.2641975308642*G0_0_0_9_1_0 + 0.632098765432098*G0_0_0_9_1_1 - 1.2641975308642*G0_0_0_10_1_0 + 2.79929453262786*G0_0_0_10_1_1 + 3.43139329805996*G0_0_0_11_1_0 - 0.632098765432098*G0_0_0_11_1_1 - 0.451499118165788*G0_0_1_0_0_0 - 0.451499118165788*G0_0_1_0_0_1 - 0.180599647266315*G0_0_1_1_0_0 + 0.270899470899469*G0_0_1_2_0_1 + 0.812698412698411*G0_0_1_3_0_0 + 0.361199294532628*G0_0_1_3_0_1 - 0.812698412698411*G0_0_1_4_0_0 + 0.180599647266319*G0_0_1_4_0_1 + 0.632098765432103*G0_0_1_5_0_0 - 0.361199294532628*G0_0_1_5_0_1 - 0.451499118165788*G0_0_1_6_1_0 - 0.451499118165788*G0_0_1_6_1_1 - 0.180599647266315*G0_0_1_7_1_0 + 0.270899470899469*G0_0_1_8_1_1 + 0.812698412698411*G0_0_1_9_1_0 + 0.361199294532628*G0_0_1_9_1_1 - 0.812698412698411*G0_0_1_10_1_0 + 0.180599647266319*G0_0_1_10_1_1 + 0.632098765432103*G0_0_1_11_1_0 - 0.361199294532628*G0_0_1_11_1_1 + 0.180599647266313*G0_1_0_1_0_0 - 0.180599647266314*G0_1_0_2_0_1 - 0.180599647266314*G0_1_0_3_0_0 + 0.180599647266314*G0_1_0_3_0_1 + 0.180599647266314*G0_1_0_4_0_0 + 0.180599647266317*G0_1_0_4_0_1 - 0.18059964726631*G0_1_0_5_0_0 - 0.180599647266313*G0_1_0_5_0_1 + 0.180599647266313*G0_1_0_7_1_0 - 0.180599647266314*G0_1_0_8_1_1 - 0.180599647266314*G0_1_0_9_1_0 + 0.180599647266314*G0_1_0_9_1_1 + 0.180599647266314*G0_1_0_10_1_0 + 0.180599647266317*G0_1_0_10_1_1 - 0.18059964726631*G0_1_0_11_1_0 - 0.180599647266313*G0_1_0_11_1_1 - 2.07689594356261*G0_1_1_0_0_0 - 2.07689594356261*G0_1_1_0_0_1 - 0.451499118165784*G0_1_1_1_0_0 - 0.812698412698414*G0_1_1_2_0_1 + 0.361199294532627*G0_1_1_3_0_1 + 2.88959435626102*G0_1_1_4_0_1 + 2.52839506172839*G0_1_1_5_0_0 - 0.361199294532627*G0_1_1_5_0_1 - 2.07689594356261*G0_1_1_6_1_0 - 2.07689594356261*G0_1_1_6_1_1 - 0.451499118165784*G0_1_1_7_1_0 - 0.812698412698414*G0_1_1_8_1_1 + 0.361199294532627*G0_1_1_9_1_1 + 2.88959435626102*G0_1_1_10_1_1 + 2.52839506172839*G0_1_1_11_1_0 - 0.361199294532627*G0_1_1_11_1_1; + A[138] = 0.0; + A[596] = A[131]; + A[217] = A[775] + 2.25185185185185*G0_0_0_0_0_0 + 2.25185185185185*G0_0_0_0_0_1 - 3.74179894179894*G0_0_0_1_0_0 + 5.48571428571428*G0_0_0_2_0_1 + 4.97777777777778*G0_0_0_3_0_0 - 4.24973544973545*G0_0_0_3_0_1 - 4.97777777777778*G0_0_0_4_0_0 - 7.73756613756614*G0_0_0_4_0_1 + 1.48994708994709*G0_0_0_5_0_0 + 4.24973544973545*G0_0_0_5_0_1 + 2.25185185185185*G0_0_0_6_1_0 + 2.25185185185185*G0_0_0_6_1_1 - 3.74179894179894*G0_0_0_7_1_0 + 5.48571428571428*G0_0_0_8_1_1 + 4.97777777777778*G0_0_0_9_1_0 - 4.24973544973545*G0_0_0_9_1_1 - 4.97777777777778*G0_0_0_10_1_0 - 7.73756613756614*G0_0_0_10_1_1 + 1.48994708994709*G0_0_0_11_1_0 + 4.24973544973545*G0_0_0_11_1_1 - 3.86878306878307*G0_0_1_1_0_0 + 3.86878306878307*G0_0_1_2_0_1 + 3.86878306878307*G0_0_1_3_0_0 - 3.86878306878307*G0_0_1_3_0_1 - 3.86878306878307*G0_0_1_4_0_0 - 3.86878306878307*G0_0_1_4_0_1 + 3.86878306878307*G0_0_1_5_0_0 + 3.86878306878307*G0_0_1_5_0_1 - 3.86878306878307*G0_0_1_7_1_0 + 3.86878306878307*G0_0_1_8_1_1 + 3.86878306878307*G0_0_1_9_1_0 - 3.86878306878307*G0_0_1_9_1_1 - 3.86878306878307*G0_0_1_10_1_0 - 3.86878306878307*G0_0_1_10_1_1 + 3.86878306878307*G0_0_1_11_1_0 + 3.86878306878307*G0_0_1_11_1_1 - 3.86878306878307*G0_1_0_1_0_0 + 3.86878306878307*G0_1_0_2_0_1 + 3.86878306878307*G0_1_0_3_0_0 - 3.86878306878306*G0_1_0_3_0_1 - 3.86878306878307*G0_1_0_4_0_0 - 3.86878306878307*G0_1_0_4_0_1 + 3.86878306878306*G0_1_0_5_0_0 + 3.86878306878307*G0_1_0_5_0_1 - 3.86878306878307*G0_1_0_7_1_0 + 3.86878306878307*G0_1_0_8_1_1 + 3.86878306878307*G0_1_0_9_1_0 - 3.86878306878306*G0_1_0_9_1_1 - 3.86878306878307*G0_1_0_10_1_0 - 3.86878306878307*G0_1_0_10_1_1 + 3.86878306878306*G0_1_0_11_1_0 + 3.86878306878307*G0_1_0_11_1_1 - 2.25185185185184*G0_1_1_0_0_0 - 2.25185185185185*G0_1_1_0_0_1 - 5.48571428571428*G0_1_1_1_0_0 + 3.74179894179894*G0_1_1_2_0_1 + 4.24973544973545*G0_1_1_3_0_0 - 4.97777777777777*G0_1_1_3_0_1 - 4.24973544973545*G0_1_1_4_0_0 - 1.4899470899471*G0_1_1_4_0_1 + 7.73756613756613*G0_1_1_5_0_0 + 4.97777777777777*G0_1_1_5_0_1 - 2.25185185185184*G0_1_1_6_1_0 - 2.25185185185185*G0_1_1_6_1_1 - 5.48571428571428*G0_1_1_7_1_0 + 3.74179894179894*G0_1_1_8_1_1 + 4.24973544973545*G0_1_1_9_1_0 - 4.97777777777777*G0_1_1_9_1_1 - 4.24973544973545*G0_1_1_10_1_0 - 1.4899470899471*G0_1_1_10_1_1 + 7.73756613756613*G0_1_1_11_1_0 + 4.97777777777777*G0_1_1_11_1_1; + A[169] = 0.0; + A[629] = -A[254] - 1.17389770723104*G0_1_0_0_0_0 - 1.17389770723104*G0_1_0_0_0_1 - 1.17389770723104*G0_1_0_1_0_0 - 1.17389770723104*G0_1_0_3_0_1 + 1.17389770723103*G0_1_0_4_0_1 + 2.34779541446208*G0_1_0_5_0_0 + 1.17389770723104*G0_1_0_5_0_1 - 1.17389770723104*G0_1_0_6_1_0 - 1.17389770723104*G0_1_0_6_1_1 - 1.17389770723104*G0_1_0_7_1_0 - 1.17389770723104*G0_1_0_9_1_1 + 1.17389770723103*G0_1_0_10_1_1 + 2.34779541446208*G0_1_0_11_1_0 + 1.17389770723104*G0_1_0_11_1_1 + 0.31604938271605*G0_1_1_0_0_0 + 0.31604938271605*G0_1_1_0_0_1 - 1.48994708994709*G0_1_1_1_0_0 - 0.496649029982362*G0_1_1_2_0_1 - 2.79929453262786*G0_1_1_3_0_0 - 3.79259259259259*G0_1_1_3_0_1 + 2.79929453262786*G0_1_1_4_0_0 + 0.180599647266312*G0_1_1_4_0_1 + 1.17389770723104*G0_1_1_5_0_0 + 3.79259259259259*G0_1_1_5_0_1 + 0.31604938271605*G0_1_1_6_1_0 + 0.31604938271605*G0_1_1_6_1_1 - 1.48994708994709*G0_1_1_7_1_0 - 0.496649029982362*G0_1_1_8_1_1 - 2.79929453262786*G0_1_1_9_1_0 - 3.79259259259259*G0_1_1_9_1_1 + 2.79929453262786*G0_1_1_10_1_0 + 0.180599647266312*G0_1_1_10_1_1 + 1.17389770723104*G0_1_1_11_1_0 + 3.79259259259259*G0_1_1_11_1_1; + A[501] = A[36]; + A[204] = 0.0; + A[646] = A[181]; + A[570] = 0.0; + A[526] = A[61]; + A[239] = 0.0; + A[563] = A[98]; + A[241] = A[706]; + A[298] = 0.0; + A[447] = 0.0; + A[327] = 0.0; + A[468] = A[555] + 0.0310405643738989*G0_0_1_1_0_0 - 0.0310405643738979*G0_0_1_2_0_1 - 0.031040564373898*G0_0_1_3_0_0 + 0.0310405643738988*G0_0_1_3_0_1 + 0.031040564373898*G0_0_1_4_0_0 + 0.031040564373897*G0_0_1_4_0_1 - 0.0310405643738998*G0_0_1_5_0_0 - 0.0310405643738988*G0_0_1_5_0_1 + 0.0310405643738989*G0_0_1_7_1_0 - 0.0310405643738979*G0_0_1_8_1_1 - 0.031040564373898*G0_0_1_9_1_0 + 0.0310405643738988*G0_0_1_9_1_1 + 0.031040564373898*G0_0_1_10_1_0 + 0.031040564373897*G0_0_1_10_1_1 - 0.0310405643738998*G0_0_1_11_1_0 - 0.0310405643738988*G0_0_1_11_1_1 - 0.0310405643738989*G0_1_0_1_0_0 + 0.0310405643738979*G0_1_0_2_0_1 + 0.031040564373898*G0_1_0_3_0_0 - 0.0310405643738988*G0_1_0_3_0_1 - 0.031040564373898*G0_1_0_4_0_0 - 0.031040564373897*G0_1_0_4_0_1 + 0.0310405643738998*G0_1_0_5_0_0 + 0.0310405643738988*G0_1_0_5_0_1 - 0.0310405643738989*G0_1_0_7_1_0 + 0.0310405643738979*G0_1_0_8_1_1 + 0.031040564373898*G0_1_0_9_1_0 - 0.0310405643738988*G0_1_0_9_1_1 - 0.031040564373898*G0_1_0_10_1_0 - 0.031040564373897*G0_1_0_10_1_1 + 0.0310405643738998*G0_1_0_11_1_0 + 0.0310405643738988*G0_1_0_11_1_1; + A[476] = -A[468] + 0.411992945326279*G0_0_0_0_0_0 + 0.411992945326279*G0_0_0_0_0_1 + 0.0451499118165776*G0_0_0_1_0_0 + 0.163668430335097*G0_0_0_2_0_1 - 0.0395061728395059*G0_0_0_3_0_0 - 0.158024691358026*G0_0_0_3_0_1 + 0.0395061728395059*G0_0_0_4_0_0 - 0.575661375661376*G0_0_0_4_0_1 - 0.457142857142856*G0_0_0_5_0_0 + 0.158024691358026*G0_0_0_5_0_1 + 0.411992945326279*G0_0_0_6_1_0 + 0.411992945326279*G0_0_0_6_1_1 + 0.0451499118165776*G0_0_0_7_1_0 + 0.163668430335097*G0_0_0_8_1_1 - 0.0395061728395059*G0_0_0_9_1_0 - 0.158024691358026*G0_0_0_9_1_1 + 0.0395061728395059*G0_0_0_10_1_0 - 0.575661375661376*G0_0_0_10_1_1 - 0.457142857142856*G0_0_0_11_1_0 + 0.158024691358026*G0_0_0_11_1_1 + 0.411992945326279*G0_1_0_0_0_0 + 0.411992945326279*G0_1_0_0_0_1 + 0.0451499118165778*G0_1_0_1_0_0 + 0.163668430335097*G0_1_0_2_0_1 - 0.0395061728395056*G0_1_0_3_0_0 - 0.158024691358025*G0_1_0_3_0_1 + 0.0395061728395056*G0_1_0_4_0_0 - 0.575661375661376*G0_1_0_4_0_1 - 0.457142857142857*G0_1_0_5_0_0 + 0.158024691358026*G0_1_0_5_0_1 + 0.411992945326279*G0_1_0_6_1_0 + 0.411992945326279*G0_1_0_6_1_1 + 0.0451499118165778*G0_1_0_7_1_0 + 0.163668430335097*G0_1_0_8_1_1 - 0.0395061728395056*G0_1_0_9_1_0 - 0.158024691358025*G0_1_0_9_1_1 + 0.0395061728395056*G0_1_0_10_1_0 - 0.575661375661376*G0_1_0_10_1_1 - 0.457142857142857*G0_1_0_11_1_0 + 0.158024691358026*G0_1_0_11_1_1; + A[11] = A[476]; + A[348] = 0.0; + A[29] = 0.0; + A[730] = 0.0; + A[381] = 0.0; + A[833] = A[368]; + A[54] = 0.0; + A[761] = 0.0; + A[414] = 0.0; + A[856] = A[421] - 0.541798941798941*G0_0_0_0_0_0 - 0.541798941798941*G0_0_0_0_0_1 - 1.35449735449735*G0_0_0_1_0_0 + 0.812698412698411*G0_0_0_2_0_1 + 0.812698412698411*G0_0_0_3_0_0 - 1.35449735449735*G0_0_0_3_0_1 - 0.812698412698411*G0_0_0_4_0_0 - 0.27089947089947*G0_0_0_4_0_1 + 1.89629629629629*G0_0_0_5_0_0 + 1.35449735449735*G0_0_0_5_0_1 - 0.541798941798941*G0_0_0_6_1_0 - 0.541798941798941*G0_0_0_6_1_1 - 1.35449735449735*G0_0_0_7_1_0 + 0.812698412698411*G0_0_0_8_1_1 + 0.812698412698411*G0_0_0_9_1_0 - 1.35449735449735*G0_0_0_9_1_1 - 0.812698412698411*G0_0_0_10_1_0 - 0.27089947089947*G0_0_0_10_1_1 + 1.89629629629629*G0_0_0_11_1_0 + 1.35449735449735*G0_0_0_11_1_1; + A[780] = 0.0; + A[891] = A[426]; + A[823] = 0.0; + A[145] = 0.0; + A[854] = 0.0; + A[178] = 0.0; + A[885] = A[420]; + A[492] = 0.0; + A[199] = 0.0; + A[655] = A[306] - 0.361199294532629*G0_0_1_0_0_0 - 0.36119929453263*G0_0_1_0_0_1 - 0.124162257495592*G0_0_1_1_0_0 - 0.237037037037037*G0_0_1_2_0_1 - 0.237037037037038*G0_0_1_3_0_0 - 0.124162257495593*G0_0_1_3_0_1 + 0.237037037037038*G0_0_1_4_0_0 + 0.598236331569666*G0_0_1_4_0_1 + 0.485361552028222*G0_0_1_5_0_0 + 0.124162257495593*G0_0_1_5_0_1 - 0.361199294532629*G0_0_1_6_1_0 - 0.36119929453263*G0_0_1_6_1_1 - 0.124162257495592*G0_0_1_7_1_0 - 0.237037037037037*G0_0_1_8_1_1 - 0.237037037037038*G0_0_1_9_1_0 - 0.124162257495593*G0_0_1_9_1_1 + 0.237037037037038*G0_0_1_10_1_0 + 0.598236331569666*G0_0_1_10_1_1 + 0.485361552028222*G0_0_1_11_1_0 + 0.124162257495593*G0_0_1_11_1_1 + 0.361199294532629*G0_1_0_0_0_0 + 0.361199294532629*G0_1_0_0_0_1 + 0.124162257495592*G0_1_0_1_0_0 + 0.237037037037037*G0_1_0_2_0_1 + 0.237037037037038*G0_1_0_3_0_0 + 0.124162257495593*G0_1_0_3_0_1 - 0.237037037037038*G0_1_0_4_0_0 - 0.598236331569666*G0_1_0_4_0_1 - 0.485361552028222*G0_1_0_5_0_0 - 0.124162257495593*G0_1_0_5_0_1 + 0.361199294532629*G0_1_0_6_1_0 + 0.361199294532629*G0_1_0_6_1_1 + 0.124162257495592*G0_1_0_7_1_0 + 0.237037037037037*G0_1_0_8_1_1 + 0.237037037037038*G0_1_0_9_1_0 + 0.124162257495593*G0_1_0_9_1_1 - 0.237037037037038*G0_1_0_10_1_0 - 0.598236331569666*G0_1_0_10_1_1 - 0.485361552028222*G0_1_0_11_1_0 - 0.124162257495593*G0_1_0_11_1_1; + A[579] = 0.0; + A[519] = 0.0; + A[236] = 0.0; + A[682] = A[217]; + A[602] = 0.0; + A[554] = 0.0; + A[713] = -A[245] + 0.31604938271605*G0_0_1_0_0_0 + 0.31604938271605*G0_0_1_0_0_1 - 0.316049382716049*G0_0_1_1_0_0 + 0.632098765432098*G0_0_1_2_0_1 + 0.632098765432097*G0_0_1_3_0_0 - 0.316049382716049*G0_0_1_3_0_1 - 0.632098765432097*G0_0_1_4_0_0 - 0.948148148148147*G0_0_1_4_0_1 + 0.316049382716049*G0_0_1_5_0_1 + 0.31604938271605*G0_0_1_6_1_0 + 0.31604938271605*G0_0_1_6_1_1 - 0.316049382716049*G0_0_1_7_1_0 + 0.632098765432098*G0_0_1_8_1_1 + 0.632098765432097*G0_0_1_9_1_0 - 0.316049382716049*G0_0_1_9_1_1 - 0.632098765432097*G0_0_1_10_1_0 - 0.948148148148147*G0_0_1_10_1_1 + 0.316049382716049*G0_0_1_11_1_1 - 0.609523809523808*G0_1_1_0_0_0 - 0.609523809523808*G0_1_1_0_0_1 - 0.699823633156967*G0_1_1_1_0_0 + 1.78342151675485*G0_1_1_2_0_1 + 3.47654320987654*G0_1_1_3_0_0 + 0.993298059964726*G0_1_1_3_0_1 - 3.47654320987654*G0_1_1_4_0_0 - 1.17389770723104*G0_1_1_4_0_1 + 1.30934744268078*G0_1_1_5_0_0 - 0.993298059964727*G0_1_1_5_0_1 - 0.609523809523808*G0_1_1_6_1_0 - 0.609523809523808*G0_1_1_6_1_1 - 0.699823633156967*G0_1_1_7_1_0 + 1.78342151675485*G0_1_1_8_1_1 + 3.47654320987654*G0_1_1_9_1_0 + 0.993298059964726*G0_1_1_9_1_1 - 3.47654320987654*G0_1_1_10_1_0 - 1.17389770723104*G0_1_1_10_1_1 + 1.30934744268078*G0_1_1_11_1_0 - 0.993298059964727*G0_1_1_11_1_1; + A[633] = 0.0; + A[248] = A[713]; + A[668] = 0.0; + A[275] = A[740]; + A[703] = 0.0; + A[302] = A[767]; + A[477] = A[360] - 0.0282186948853607*G0_0_1_1_0_0 + 0.0282186948853618*G0_0_1_2_0_1 + 0.0282186948853614*G0_0_1_3_0_0 - 0.0282186948853611*G0_0_1_3_0_1 - 0.0282186948853614*G0_0_1_4_0_0 - 0.0282186948853635*G0_0_1_4_0_1 + 0.0282186948853593*G0_0_1_5_0_0 + 0.0282186948853611*G0_0_1_5_0_1 - 0.0282186948853607*G0_0_1_7_1_0 + 0.0282186948853618*G0_0_1_8_1_1 + 0.0282186948853614*G0_0_1_9_1_0 - 0.0282186948853611*G0_0_1_9_1_1 - 0.0282186948853614*G0_0_1_10_1_0 - 0.0282186948853635*G0_0_1_10_1_1 + 0.0282186948853593*G0_0_1_11_1_0 + 0.0282186948853611*G0_0_1_11_1_1 + 0.0282186948853606*G0_1_0_1_0_0 - 0.0282186948853619*G0_1_0_2_0_1 - 0.0282186948853614*G0_1_0_3_0_0 + 0.0282186948853611*G0_1_0_3_0_1 + 0.0282186948853614*G0_1_0_4_0_0 + 0.0282186948853638*G0_1_0_4_0_1 - 0.0282186948853593*G0_1_0_5_0_0 - 0.0282186948853611*G0_1_0_5_0_1 + 0.0282186948853606*G0_1_0_7_1_0 - 0.0282186948853619*G0_1_0_8_1_1 - 0.0282186948853614*G0_1_0_9_1_0 + 0.0282186948853611*G0_1_0_9_1_1 + 0.0282186948853614*G0_1_0_10_1_0 + 0.0282186948853638*G0_1_0_10_1_1 - 0.0282186948853593*G0_1_0_11_1_0 - 0.0282186948853611*G0_1_0_11_1_1; + A[341] = A[806]; + A[20] = 0.0; + A[424] = A[134] + 0.541798941798942*G0_0_1_0_0_0 + 0.541798941798942*G0_0_1_0_0_1 - 0.203174603174603*G0_0_1_1_0_0 + 0.744973544973545*G0_0_1_2_0_1 + 0.744973544973547*G0_0_1_3_0_0 - 0.203174603174602*G0_0_1_3_0_1 - 0.744973544973547*G0_0_1_4_0_0 - 1.28677248677249*G0_0_1_4_0_1 - 0.338624338624339*G0_0_1_5_0_0 + 0.203174603174602*G0_0_1_5_0_1 + 0.541798941798942*G0_0_1_6_1_0 + 0.541798941798942*G0_0_1_6_1_1 - 0.203174603174603*G0_0_1_7_1_0 + 0.744973544973545*G0_0_1_8_1_1 + 0.744973544973547*G0_0_1_9_1_0 - 0.203174603174602*G0_0_1_9_1_1 - 0.744973544973547*G0_0_1_10_1_0 - 1.28677248677249*G0_0_1_10_1_1 - 0.338624338624339*G0_0_1_11_1_0 + 0.203174603174602*G0_0_1_11_1_1 - 0.541798941798942*G0_1_0_0_0_0 - 0.541798941798942*G0_1_0_0_0_1 + 0.203174603174603*G0_1_0_1_0_0 - 0.744973544973545*G0_1_0_2_0_1 - 0.744973544973547*G0_1_0_3_0_0 + 0.203174603174602*G0_1_0_3_0_1 + 0.744973544973547*G0_1_0_4_0_0 + 1.28677248677249*G0_1_0_4_0_1 + 0.338624338624339*G0_1_0_5_0_0 - 0.203174603174602*G0_1_0_5_0_1 - 0.541798941798942*G0_1_0_6_1_0 - 0.541798941798942*G0_1_0_6_1_1 + 0.203174603174603*G0_1_0_7_1_0 - 0.744973544973545*G0_1_0_8_1_1 - 0.744973544973547*G0_1_0_9_1_0 + 0.203174603174602*G0_1_0_9_1_1 + 0.744973544973547*G0_1_0_10_1_0 + 1.28677248677249*G0_1_0_10_1_1 + 0.338624338624339*G0_1_0_11_1_0 - 0.203174603174602*G0_1_0_11_1_1; + A[372] = -A[373] - 2.7089947089947*G0_0_0_0_0_0 - 2.7089947089947*G0_0_0_0_0_1 - 1.62539682539682*G0_0_0_1_0_0 + 0.541798941798943*G0_0_0_2_0_1 + 2.16719576719577*G0_0_0_3_0_0 - 2.16719576719577*G0_0_0_4_0_0 + 2.16719576719576*G0_0_0_4_0_1 + 4.33439153439152*G0_0_0_5_0_0 - 2.7089947089947*G0_0_0_6_1_0 - 2.7089947089947*G0_0_0_6_1_1 - 1.62539682539682*G0_0_0_7_1_0 + 0.541798941798943*G0_0_0_8_1_1 + 2.16719576719577*G0_0_0_9_1_0 - 2.16719576719577*G0_0_0_10_1_0 + 2.16719576719576*G0_0_0_10_1_1 + 4.33439153439152*G0_0_0_11_1_0 - 0.270899470899466*G0_0_1_0_0_0 - 0.270899470899467*G0_0_1_0_0_1 - 0.812698412698409*G0_0_1_1_0_0 + 1.35449735449736*G0_0_1_2_0_1 + 2.16719576719577*G0_0_1_3_0_0 - 2.16719576719577*G0_0_1_4_0_0 - 1.08359788359789*G0_0_1_4_0_1 + 1.08359788359788*G0_0_1_5_0_0 - 0.270899470899466*G0_0_1_6_1_0 - 0.270899470899467*G0_0_1_6_1_1 - 0.812698412698409*G0_0_1_7_1_0 + 1.35449735449736*G0_0_1_8_1_1 + 2.16719576719577*G0_0_1_9_1_0 - 2.16719576719577*G0_0_1_10_1_0 - 1.08359788359789*G0_0_1_10_1_1 + 1.08359788359788*G0_0_1_11_1_0 - 0.812698412698409*G0_1_0_0_0_0 - 0.812698412698409*G0_1_0_0_0_1 - 0.27089947089947*G0_1_0_1_0_0 + 0.270899470899473*G0_1_0_2_0_1 + 1.08359788359788*G0_1_0_3_0_0 + 0.541798941798942*G0_1_0_3_0_1 - 1.08359788359788*G0_1_0_4_0_0 + 0.541798941798936*G0_1_0_4_0_1 + 1.08359788359788*G0_1_0_5_0_0 - 0.541798941798942*G0_1_0_5_0_1 - 0.812698412698409*G0_1_0_6_1_0 - 0.812698412698409*G0_1_0_6_1_1 - 0.27089947089947*G0_1_0_7_1_0 + 0.270899470899473*G0_1_0_8_1_1 + 1.08359788359788*G0_1_0_9_1_0 + 0.541798941798942*G0_1_0_9_1_1 - 1.08359788359788*G0_1_0_10_1_0 + 0.541798941798936*G0_1_0_10_1_1 + 1.08359788359788*G0_1_0_11_1_0 - 0.541798941798942*G0_1_0_11_1_1 - 5.41798941798942*G0_1_1_0_0_0 - 5.41798941798942*G0_1_1_0_0_1 + 0.541798941798947*G0_1_1_1_0_0 - 1.08359788359788*G0_1_1_2_0_1 + 3.79259259259259*G0_1_1_3_0_0 + 5.41798941798942*G0_1_1_3_0_1 - 3.79259259259259*G0_1_1_4_0_0 + 6.5015873015873*G0_1_1_4_0_1 + 4.87619047619047*G0_1_1_5_0_0 - 5.41798941798942*G0_1_1_5_0_1 - 5.41798941798942*G0_1_1_6_1_0 - 5.41798941798942*G0_1_1_6_1_1 + 0.541798941798947*G0_1_1_7_1_0 - 1.08359788359788*G0_1_1_8_1_1 + 3.79259259259259*G0_1_1_9_1_0 + 5.41798941798942*G0_1_1_9_1_1 - 3.79259259259259*G0_1_1_10_1_0 + 6.5015873015873*G0_1_1_10_1_1 + 4.87619047619047*G0_1_1_11_1_0 - 5.41798941798942*G0_1_1_11_1_1; + A[47] = 0.0; + A[762] = 0.0; + A[451] = 0.0; + A[407] = 0.0; + A[82] = 0.0; + A[791] = 0.0; + A[10] = A[475]; + A[97] = A[562]; + A[812] = 0.0; + A[41] = A[506]; + A[120] = A[585]; + A[845] = 0.0; + A[155] = A[620]; + A[878] = 0.0; + A[483] = 0.0; + A[190] = A[655]; + A[584] = 0.0; + A[512] = 0.0; + A[229] = 0.0; + A[609] = 0.0; + A[549] = 0.0; + A[505] = A[40]; + A[642] = 0.0; + A[255] = 0.0; + A[663] = 0.0; + A[284] = A[749]; + A[700] = 0.0; + A[313] = A[865] - 0.203174603174604*G0_0_1_0_0_0 - 0.203174603174603*G0_0_1_0_0_1 - 0.744973544973549*G0_0_1_1_0_0 + 0.541798941798943*G0_0_1_2_0_1 + 0.541798941798943*G0_0_1_3_0_0 - 0.74497354497355*G0_0_1_3_0_1 - 0.541798941798943*G0_0_1_4_0_0 - 0.338624338624341*G0_0_1_4_0_1 + 0.948148148148153*G0_0_1_5_0_0 + 0.74497354497355*G0_0_1_5_0_1 - 0.203174603174604*G0_0_1_6_1_0 - 0.203174603174603*G0_0_1_6_1_1 - 0.744973544973549*G0_0_1_7_1_0 + 0.541798941798943*G0_0_1_8_1_1 + 0.541798941798943*G0_0_1_9_1_0 - 0.74497354497355*G0_0_1_9_1_1 - 0.541798941798943*G0_0_1_10_1_0 - 0.338624338624341*G0_0_1_10_1_1 + 0.948148148148153*G0_0_1_11_1_0 + 0.74497354497355*G0_0_1_11_1_1 + 0.203174603174604*G0_1_0_0_0_0 + 0.203174603174603*G0_1_0_0_0_1 + 0.744973544973549*G0_1_0_1_0_0 - 0.541798941798943*G0_1_0_2_0_1 - 0.541798941798943*G0_1_0_3_0_0 + 0.744973544973551*G0_1_0_3_0_1 + 0.541798941798943*G0_1_0_4_0_0 + 0.33862433862434*G0_1_0_4_0_1 - 0.948148148148153*G0_1_0_5_0_0 - 0.744973544973551*G0_1_0_5_0_1 + 0.203174603174604*G0_1_0_6_1_0 + 0.203174603174603*G0_1_0_6_1_1 + 0.744973544973549*G0_1_0_7_1_0 - 0.541798941798943*G0_1_0_8_1_1 - 0.541798941798943*G0_1_0_9_1_0 + 0.744973544973551*G0_1_0_9_1_1 + 0.541798941798943*G0_1_0_10_1_0 + 0.33862433862434*G0_1_0_10_1_1 - 0.948148148148153*G0_1_0_11_1_0 - 0.744973544973551*G0_1_0_11_1_1; + A[261] = 0.0; + A[330] = A[795]; + A[286] = 0.0; + A[435] = 0.0; + A[371] = A[836]; + A[323] = 0.0; + A[771] = A[306]; + A[464] = 0.0; + A[400] = A[865]; + A[77] = 0.0; + A[798] = A[333]; + A[1] = A[466]; + A[102] = A[567]; + A[837] = A[372]; + A[42] = A[509] + 0.27089947089947*G0_0_0_0_0_0 + 0.27089947089947*G0_0_0_0_0_1 + 0.270899470899469*G0_0_0_2_0_1 + 0.27089947089947*G0_0_0_3_0_0 - 0.27089947089947*G0_0_0_4_0_0 - 0.541798941798939*G0_0_0_4_0_1 - 0.270899470899471*G0_0_0_5_0_0 + 0.27089947089947*G0_0_0_6_1_0 + 0.27089947089947*G0_0_0_6_1_1 + 0.270899470899469*G0_0_0_8_1_1 + 0.27089947089947*G0_0_0_9_1_0 - 0.27089947089947*G0_0_0_10_1_0 - 0.541798941798939*G0_0_0_10_1_1 - 0.270899470899471*G0_0_0_11_1_0; + A[135] = 0.0; + A[868] = A[403]; + A[71] = A[534] + 0.14673721340388*G0_1_1_0_0_0 + 0.14673721340388*G0_1_1_0_0_1 + 0.146737213403881*G0_1_1_1_0_0 + 0.146737213403882*G0_1_1_3_0_1 - 0.14673721340388*G0_1_1_4_0_1 - 0.293474426807762*G0_1_1_5_0_0 - 0.146737213403882*G0_1_1_5_0_1 + 0.14673721340388*G0_1_1_6_1_0 + 0.14673721340388*G0_1_1_6_1_1 + 0.146737213403881*G0_1_1_7_1_0 + 0.146737213403882*G0_1_1_9_1_1 - 0.14673721340388*G0_1_1_10_1_1 - 0.293474426807762*G0_1_1_11_1_0 - 0.146737213403882*G0_1_1_11_1_1; + A[63] = -A[71] + 0.163668430335097*G0_1_0_0_0_0 + 0.163668430335097*G0_1_0_0_0_1 - 0.045149911816578*G0_1_0_1_0_0 + 0.411992945326278*G0_1_0_2_0_1 + 0.61516754850088*G0_1_0_3_0_0 + 0.158024691358025*G0_1_0_3_0_1 - 0.61516754850088*G0_1_0_4_0_0 - 0.575661375661375*G0_1_0_4_0_1 - 0.118518518518519*G0_1_0_5_0_0 - 0.158024691358025*G0_1_0_5_0_1 + 0.163668430335097*G0_1_0_6_1_0 + 0.163668430335097*G0_1_0_6_1_1 - 0.045149911816578*G0_1_0_7_1_0 + 0.411992945326278*G0_1_0_8_1_1 + 0.61516754850088*G0_1_0_9_1_0 + 0.158024691358025*G0_1_0_9_1_1 - 0.61516754850088*G0_1_0_10_1_0 - 0.575661375661375*G0_1_0_10_1_1 - 0.118518518518519*G0_1_0_11_1_0 - 0.158024691358025*G0_1_0_11_1_1; + A[531] = -A[63] + 0.0564373897707228*G0_1_0_0_0_0 + 0.0564373897707227*G0_1_0_0_0_1 + 0.0564373897707224*G0_1_0_1_0_0 + 0.0564373897707224*G0_1_0_3_0_1 - 0.056437389770723*G0_1_0_4_0_1 - 0.112874779541445*G0_1_0_5_0_0 - 0.0564373897707225*G0_1_0_5_0_1 + 0.0564373897707228*G0_1_0_6_1_0 + 0.0564373897707227*G0_1_0_6_1_1 + 0.0564373897707224*G0_1_0_7_1_0 + 0.0564373897707224*G0_1_0_9_1_1 - 0.056437389770723*G0_1_0_10_1_1 - 0.112874779541445*G0_1_0_11_1_0 - 0.0564373897707225*G0_1_0_11_1_1 + 0.0790123456790112*G0_1_1_0_0_0 + 0.0790123456790111*G0_1_1_0_0_1 - 0.0225749559082903*G0_1_1_1_0_0 - 0.186243386243387*G0_1_1_2_0_1 - 0.474074074074075*G0_1_1_3_0_0 - 0.310405643738979*G0_1_1_3_0_1 + 0.474074074074075*G0_1_1_4_0_0 + 0.107231040564376*G0_1_1_4_0_1 - 0.0564373897707209*G0_1_1_5_0_0 + 0.310405643738979*G0_1_1_5_0_1 + 0.0790123456790112*G0_1_1_6_1_0 + 0.0790123456790111*G0_1_1_6_1_1 - 0.0225749559082903*G0_1_1_7_1_0 - 0.186243386243387*G0_1_1_8_1_1 - 0.474074074074075*G0_1_1_9_1_0 - 0.310405643738979*G0_1_1_9_1_1 + 0.474074074074075*G0_1_1_10_1_0 + 0.107231040564376*G0_1_1_10_1_1 - 0.0564373897707209*G0_1_1_11_1_0 + 0.310405643738979*G0_1_1_11_1_1; + A[797] = A[71] + 0.031040564373898*G0_0_1_0_0_0 + 0.031040564373898*G0_0_1_0_0_1 + 0.0310405643738983*G0_0_1_1_0_0 + 0.0310405643738983*G0_0_1_3_0_1 - 0.0310405643738978*G0_0_1_4_0_1 - 0.0620811287477963*G0_0_1_5_0_0 - 0.0310405643738984*G0_0_1_5_0_1 + 0.031040564373898*G0_0_1_6_1_0 + 0.031040564373898*G0_0_1_6_1_1 + 0.0310405643738983*G0_0_1_7_1_0 + 0.0310405643738983*G0_0_1_9_1_1 - 0.0310405643738978*G0_0_1_10_1_1 - 0.0620811287477963*G0_0_1_11_1_0 - 0.0310405643738984*G0_0_1_11_1_1 - 0.031040564373898*G0_1_0_0_0_0 - 0.031040564373898*G0_1_0_0_0_1 - 0.0310405643738983*G0_1_0_1_0_0 - 0.0310405643738983*G0_1_0_3_0_1 + 0.0310405643738978*G0_1_0_4_0_1 + 0.0620811287477963*G0_1_0_5_0_0 + 0.0310405643738984*G0_1_0_5_0_1 - 0.031040564373898*G0_1_0_6_1_0 - 0.031040564373898*G0_1_0_6_1_1 - 0.0310405643738983*G0_1_0_7_1_0 - 0.0310405643738983*G0_1_0_9_1_1 + 0.0310405643738978*G0_1_0_10_1_1 + 0.0620811287477963*G0_1_0_11_1_0 + 0.0310405643738984*G0_1_0_11_1_1; + A[92] = -A[797] + 0.163668430335097*G0_0_1_0_0_0 + 0.163668430335097*G0_0_1_0_0_1 - 0.045149911816578*G0_0_1_1_0_0 + 0.411992945326278*G0_0_1_2_0_1 + 0.61516754850088*G0_0_1_3_0_0 + 0.158024691358025*G0_0_1_3_0_1 - 0.61516754850088*G0_0_1_4_0_0 - 0.575661375661375*G0_0_1_4_0_1 - 0.118518518518519*G0_0_1_5_0_0 - 0.158024691358025*G0_0_1_5_0_1 + 0.163668430335097*G0_0_1_6_1_0 + 0.163668430335097*G0_0_1_6_1_1 - 0.045149911816578*G0_0_1_7_1_0 + 0.411992945326278*G0_0_1_8_1_1 + 0.61516754850088*G0_0_1_9_1_0 + 0.158024691358025*G0_0_1_9_1_1 - 0.61516754850088*G0_0_1_10_1_0 - 0.575661375661375*G0_0_1_10_1_1 - 0.118518518518519*G0_0_1_11_1_0 - 0.158024691358025*G0_0_1_11_1_1; + A[647] = -A[92] + 0.0564373897707227*G0_0_1_0_0_0 + 0.0564373897707227*G0_0_1_0_0_1 + 0.0564373897707224*G0_0_1_1_0_0 + 0.0564373897707225*G0_0_1_3_0_1 - 0.056437389770723*G0_0_1_4_0_1 - 0.112874779541445*G0_0_1_5_0_0 - 0.0564373897707225*G0_0_1_5_0_1 + 0.0564373897707227*G0_0_1_6_1_0 + 0.0564373897707227*G0_0_1_6_1_1 + 0.0564373897707224*G0_0_1_7_1_0 + 0.0564373897707225*G0_0_1_9_1_1 - 0.056437389770723*G0_0_1_10_1_1 - 0.112874779541445*G0_0_1_11_1_0 - 0.0564373897707225*G0_0_1_11_1_1 + 0.0790123456790112*G0_1_1_0_0_0 + 0.0790123456790111*G0_1_1_0_0_1 - 0.0225749559082903*G0_1_1_1_0_0 - 0.186243386243387*G0_1_1_2_0_1 - 0.474074074074075*G0_1_1_3_0_0 - 0.310405643738979*G0_1_1_3_0_1 + 0.474074074074075*G0_1_1_4_0_0 + 0.107231040564376*G0_1_1_4_0_1 - 0.0564373897707209*G0_1_1_5_0_0 + 0.310405643738979*G0_1_1_5_0_1 + 0.0790123456790112*G0_1_1_6_1_0 + 0.0790123456790111*G0_1_1_6_1_1 - 0.0225749559082903*G0_1_1_7_1_0 - 0.186243386243387*G0_1_1_8_1_1 - 0.474074074074075*G0_1_1_9_1_0 - 0.310405643738979*G0_1_1_9_1_1 + 0.474074074074075*G0_1_1_10_1_0 + 0.107231040564376*G0_1_1_10_1_1 - 0.0564373897707209*G0_1_1_11_1_0 + 0.310405643738979*G0_1_1_11_1_1; + A[557] = A[92]; + A[182] = A[647]; + A[66] = A[531]; + A[528] = A[63]; + A[737] = A[797] - 0.14673721340388*G0_1_1_0_0_0 - 0.14673721340388*G0_1_1_0_0_1 - 0.146737213403881*G0_1_1_1_0_0 - 0.146737213403882*G0_1_1_3_0_1 + 0.14673721340388*G0_1_1_4_0_1 + 0.293474426807762*G0_1_1_5_0_0 + 0.146737213403882*G0_1_1_5_0_1 - 0.14673721340388*G0_1_1_6_1_0 - 0.14673721340388*G0_1_1_6_1_1 - 0.146737213403881*G0_1_1_7_1_0 - 0.146737213403882*G0_1_1_9_1_1 + 0.14673721340388*G0_1_1_10_1_1 + 0.293474426807762*G0_1_1_11_1_0 + 0.146737213403882*G0_1_1_11_1_1; + A[164] = A[629]; + A[871] = 0.0; + A[108] = 0.0; + A[193] = A[658]; + A[141] = 0.0; + A[593] = A[128]; + A[218] = A[683]; + A[616] = A[151]; + A[540] = 0.0; + A[496] = A[31]; + A[651] = A[186]; + A[539] = A[72] - 0.812698412698414*G0_1_1_0_0_0 - 0.812698412698414*G0_1_1_0_0_1 + 0.541798941798942*G0_1_1_1_0_0 - 1.35449735449736*G0_1_1_2_0_1 - 1.35449735449736*G0_1_1_3_0_0 + 0.54179894179894*G0_1_1_3_0_1 + 1.35449735449736*G0_1_1_4_0_0 + 2.16719576719577*G0_1_1_4_0_1 + 0.270899470899472*G0_1_1_5_0_0 - 0.54179894179894*G0_1_1_5_0_1 - 0.812698412698414*G0_1_1_6_1_0 - 0.812698412698414*G0_1_1_6_1_1 + 0.541798941798942*G0_1_1_7_1_0 - 1.35449735449736*G0_1_1_8_1_1 - 1.35449735449736*G0_1_1_9_1_0 + 0.54179894179894*G0_1_1_9_1_1 + 1.35449735449736*G0_1_1_10_1_0 + 2.16719576719577*G0_1_1_10_1_1 + 0.270899470899472*G0_1_1_11_1_0 - 0.54179894179894*G0_1_1_11_1_1; + A[686] = A[221]; + A[566] = A[101]; + A[693] = 0.0; + A[268] = 0.0; + A[295] = 0.0; + A[442] = 0.0; + A[362] = A[827]; + A[473] = A[8]; + A[393] = -A[401] + 0.316049382716049*G0_0_0_0_0_0 + 0.316049382716049*G0_0_0_0_0_1 - 0.49664902998236*G0_0_0_1_0_0 - 1.48994708994709*G0_0_0_2_0_1 - 3.79259259259259*G0_0_0_3_0_0 - 2.79929453262786*G0_0_0_3_0_1 + 3.79259259259259*G0_0_0_4_0_0 + 1.17389770723104*G0_0_0_4_0_1 + 0.180599647266311*G0_0_0_5_0_0 + 2.79929453262786*G0_0_0_5_0_1 + 0.316049382716049*G0_0_0_6_1_0 + 0.316049382716049*G0_0_0_6_1_1 - 0.49664902998236*G0_0_0_7_1_0 - 1.48994708994709*G0_0_0_8_1_1 - 3.79259259259259*G0_0_0_9_1_0 - 2.79929453262786*G0_0_0_9_1_1 + 3.79259259259259*G0_0_0_10_1_0 + 1.17389770723104*G0_0_0_10_1_1 + 0.180599647266311*G0_0_0_11_1_0 + 2.79929453262786*G0_0_0_11_1_1 - 1.17389770723104*G0_1_0_0_0_0 - 1.17389770723104*G0_1_0_0_0_1 - 1.17389770723104*G0_1_0_2_0_1 - 1.17389770723104*G0_1_0_3_0_0 + 1.17389770723104*G0_1_0_4_0_0 + 2.34779541446208*G0_1_0_4_0_1 + 1.17389770723103*G0_1_0_5_0_0 - 1.17389770723104*G0_1_0_6_1_0 - 1.17389770723104*G0_1_0_6_1_1 - 1.17389770723104*G0_1_0_8_1_1 - 1.17389770723104*G0_1_0_9_1_0 + 1.17389770723104*G0_1_0_10_1_0 + 2.34779541446208*G0_1_0_10_1_1 + 1.17389770723103*G0_1_0_11_1_0; + A[103] = A[393] - 0.361199294532628*G0_0_1_0_0_0 - 0.361199294532628*G0_0_1_0_0_1 + 0.451499118165785*G0_0_1_1_0_0 - 0.812698412698412*G0_0_1_2_0_1 - 0.812698412698414*G0_0_1_3_0_0 + 0.451499118165782*G0_0_1_3_0_1 + 0.812698412698414*G0_0_1_4_0_0 + 1.17389770723104*G0_0_1_4_0_1 - 0.0902998236331563*G0_0_1_5_0_0 - 0.451499118165784*G0_0_1_5_0_1 - 0.361199294532628*G0_0_1_6_1_0 - 0.361199294532628*G0_0_1_6_1_1 + 0.451499118165785*G0_0_1_7_1_0 - 0.812698412698412*G0_0_1_8_1_1 - 0.812698412698414*G0_0_1_9_1_0 + 0.451499118165782*G0_0_1_9_1_1 + 0.812698412698414*G0_0_1_10_1_0 + 1.17389770723104*G0_0_1_10_1_1 - 0.0902998236331563*G0_0_1_11_1_0 - 0.451499118165784*G0_0_1_11_1_1 + 0.361199294532628*G0_1_0_0_0_0 + 0.361199294532628*G0_1_0_0_0_1 - 0.451499118165785*G0_1_0_1_0_0 + 0.812698412698412*G0_1_0_2_0_1 + 0.812698412698414*G0_1_0_3_0_0 - 0.451499118165783*G0_1_0_3_0_1 - 0.812698412698414*G0_1_0_4_0_0 - 1.17389770723104*G0_1_0_4_0_1 + 0.0902998236331567*G0_1_0_5_0_0 + 0.451499118165785*G0_1_0_5_0_1 + 0.361199294532628*G0_1_0_6_1_0 + 0.361199294532628*G0_1_0_6_1_1 - 0.451499118165785*G0_1_0_7_1_0 + 0.812698412698412*G0_1_0_8_1_1 + 0.812698412698414*G0_1_0_9_1_0 - 0.451499118165783*G0_1_0_9_1_1 - 0.812698412698414*G0_1_0_10_1_0 - 1.17389770723104*G0_1_0_10_1_1 + 0.0902998236331567*G0_1_0_11_1_0 + 0.451499118165785*G0_1_0_11_1_1; + A[808] = -A[103] + 0.31604938271605*G0_0_0_0_0_0 + 0.316049382716049*G0_0_0_0_0_1 - 0.496649029982359*G0_0_0_1_0_0 - 1.48994708994709*G0_0_0_2_0_1 - 3.79259259259259*G0_0_0_3_0_0 - 2.79929453262786*G0_0_0_3_0_1 + 3.79259259259259*G0_0_0_4_0_0 + 1.17389770723104*G0_0_0_4_0_1 + 0.18059964726631*G0_0_0_5_0_0 + 2.79929453262786*G0_0_0_5_0_1 + 0.31604938271605*G0_0_0_6_1_0 + 0.316049382716049*G0_0_0_6_1_1 - 0.496649029982359*G0_0_0_7_1_0 - 1.48994708994709*G0_0_0_8_1_1 - 3.79259259259259*G0_0_0_9_1_0 - 2.79929453262786*G0_0_0_9_1_1 + 3.79259259259259*G0_0_0_10_1_0 + 1.17389770723104*G0_0_0_10_1_1 + 0.18059964726631*G0_0_0_11_1_0 + 2.79929453262786*G0_0_0_11_1_1 - 1.17389770723104*G0_0_1_0_0_0 - 1.17389770723104*G0_0_1_0_0_1 - 1.17389770723104*G0_0_1_2_0_1 - 1.17389770723104*G0_0_1_3_0_0 + 1.17389770723104*G0_0_1_4_0_0 + 2.34779541446208*G0_0_1_4_0_1 + 1.17389770723104*G0_0_1_5_0_0 - 1.17389770723104*G0_0_1_6_1_0 - 1.17389770723104*G0_0_1_6_1_1 - 1.17389770723104*G0_0_1_8_1_1 - 1.17389770723104*G0_0_1_9_1_0 + 1.17389770723104*G0_0_1_10_1_0 + 2.34779541446208*G0_0_1_10_1_1 + 1.17389770723104*G0_0_1_11_1_0; + A[568] = A[103]; + A[809] = A[344]; + A[24] = 0.0; + A[725] = 0.0; + A[384] = 0.0; + A[826] = A[361]; + A[35] = A[500]; + A[750] = 0.0; + A[419] = 0.0; + A[867] = A[402]; + A[62] = A[527]; + A[787] = 0.0; + A[896] = A[431]; + A[117] = 0.0; + A[184] = A[126] + 0.0112874779541438*G0_0_1_0_0_0 + 0.0112874779541438*G0_0_1_0_0_1 - 0.0564373897707251*G0_0_1_1_0_0 + 0.0677248677248676*G0_0_1_2_0_1 + 0.0677248677248664*G0_0_1_3_0_0 - 0.0564373897707264*G0_0_1_3_0_1 - 0.0677248677248664*G0_0_1_4_0_0 - 0.0790123456790115*G0_0_1_4_0_1 + 0.0451499118165812*G0_0_1_5_0_0 + 0.0564373897707263*G0_0_1_5_0_1 + 0.0112874779541438*G0_0_1_6_1_0 + 0.0112874779541438*G0_0_1_6_1_1 - 0.0564373897707251*G0_0_1_7_1_0 + 0.0677248677248676*G0_0_1_8_1_1 + 0.0677248677248664*G0_0_1_9_1_0 - 0.0564373897707264*G0_0_1_9_1_1 - 0.0677248677248664*G0_0_1_10_1_0 - 0.0790123456790115*G0_0_1_10_1_1 + 0.0451499118165812*G0_0_1_11_1_0 + 0.0564373897707263*G0_0_1_11_1_1 - 0.0112874779541438*G0_1_0_0_0_0 - 0.0112874779541438*G0_1_0_0_0_1 + 0.056437389770725*G0_1_0_1_0_0 - 0.0677248677248677*G0_1_0_2_0_1 - 0.0677248677248666*G0_1_0_3_0_0 + 0.0564373897707263*G0_1_0_3_0_1 + 0.0677248677248666*G0_1_0_4_0_0 + 0.0790123456790116*G0_1_0_4_0_1 - 0.0451499118165812*G0_1_0_5_0_0 - 0.0564373897707263*G0_1_0_5_0_1 - 0.0112874779541438*G0_1_0_6_1_0 - 0.0112874779541438*G0_1_0_6_1_1 + 0.056437389770725*G0_1_0_7_1_0 - 0.0677248677248677*G0_1_0_8_1_1 - 0.0677248677248666*G0_1_0_9_1_0 + 0.0564373897707263*G0_1_0_9_1_1 + 0.0677248677248666*G0_1_0_10_1_0 + 0.0790123456790116*G0_1_0_10_1_1 - 0.0451499118165812*G0_1_0_11_1_0 - 0.0564373897707263*G0_1_0_11_1_1; + A[148] = 0.0; + A[598] = A[133]; + A[211] = A[676]; + A[167] = 0.0; + A[503] = A[38]; + A[572] = 0.0; + A[532] = A[67]; + A[689] = A[224]; + A[605] = 0.0; + A[561] = A[96]; + A[714] = A[249]; + A[243] = A[708]; + A[272] = A[737]; + A[445] = 0.0; + A[325] = 0.0; + A[478] = A[13]; + A[350] = 0.0; + A[732] = 0.0; + A[423] = A[888]; + A[383] = 0.0; + A[759] = 0.0; + A[412] = 0.0; + A[858] = A[393]; + A[89] = 0.0; + A[794] = 0.0; + A[889] = A[424]; + A[90] = A[555]; + A[825] = A[360]; + A[147] = 0.0; + A[848] = 0.0; + A[176] = 0.0; + A[883] = 0.0; + A[494] = 0.0; + A[197] = 0.0; + A[581] = 0.0; + A[525] = -A[61] - 0.0825396825396826*G0_1_0_0_0_0 - 0.0825396825396826*G0_1_0_0_0_1 - 0.0825396825396831*G0_1_0_1_0_0 - 0.0825396825396831*G0_1_0_3_0_1 + 0.0825396825396822*G0_1_0_4_0_1 + 0.165079365079366*G0_1_0_5_0_0 + 0.0825396825396831*G0_1_0_5_0_1 - 0.0825396825396826*G0_1_0_6_1_0 - 0.0825396825396826*G0_1_0_6_1_1 - 0.0825396825396831*G0_1_0_7_1_0 - 0.0825396825396831*G0_1_0_9_1_1 + 0.0825396825396822*G0_1_0_10_1_1 + 0.165079365079366*G0_1_0_11_1_0 + 0.0825396825396831*G0_1_0_11_1_1 - 0.0463844797178128*G0_1_1_0_0_0 - 0.0463844797178128*G0_1_1_0_0_1 - 0.0361552028218698*G0_1_1_1_0_0 + 0.0463844797178138*G0_1_1_2_0_1 + 0.102998236331571*G0_1_1_3_0_0 + 0.0204585537918871*G0_1_1_3_0_1 - 0.102998236331571*G0_1_1_4_0_0 + 0.0825396825396825*G0_1_1_5_0_0 - 0.0204585537918872*G0_1_1_5_0_1 - 0.0463844797178128*G0_1_1_6_1_0 - 0.0463844797178128*G0_1_1_6_1_1 - 0.0361552028218698*G0_1_1_7_1_0 + 0.0463844797178138*G0_1_1_8_1_1 + 0.102998236331571*G0_1_1_9_1_0 + 0.0204585537918871*G0_1_1_9_1_1 - 0.102998236331571*G0_1_1_10_1_0 + 0.0825396825396825*G0_1_1_11_1_0 - 0.0204585537918872*G0_1_1_11_1_1; + A[230] = 0.0; + A[680] = A[215]; + A[612] = 0.0; + A[552] = 0.0; + A[707] = A[242]; + A[631] = 0.0; + A[250] = A[715]; + A[674] = 0.0; + A[281] = -A[273] - 1.24162257495591*G0_0_0_0_0_0 - 1.24162257495591*G0_0_0_0_0_1 + 0.248324514991184*G0_0_0_1_0_0 - 0.60952380952381*G0_0_0_2_0_1 + 0.27089947089947*G0_0_0_3_0_0 + 1.12874779541446*G0_0_0_3_0_1 - 0.27089947089947*G0_0_0_4_0_0 + 1.85114638447972*G0_0_0_4_0_1 + 0.993298059964725*G0_0_0_5_0_0 - 1.12874779541446*G0_0_0_5_0_1 - 1.24162257495591*G0_0_0_6_1_0 - 1.24162257495591*G0_0_0_6_1_1 + 0.248324514991184*G0_0_0_7_1_0 - 0.60952380952381*G0_0_0_8_1_1 + 0.27089947089947*G0_0_0_9_1_0 + 1.12874779541446*G0_0_0_9_1_1 - 0.27089947089947*G0_0_0_10_1_0 + 1.85114638447972*G0_0_0_10_1_1 + 0.993298059964725*G0_0_0_11_1_0 - 1.12874779541446*G0_0_0_11_1_1 - 0.406349206349206*G0_1_0_0_0_0 - 0.406349206349206*G0_1_0_0_0_1 + 0.632098765432099*G0_1_0_1_0_0 - 0.496649029982363*G0_1_0_2_0_1 + 0.0451499118165778*G0_1_0_3_0_0 + 1.17389770723104*G0_1_0_3_0_1 - 0.0451499118165778*G0_1_0_4_0_0 + 0.902998236331569*G0_1_0_4_0_1 - 0.225749559082892*G0_1_0_5_0_0 - 1.17389770723104*G0_1_0_5_0_1 - 0.406349206349206*G0_1_0_6_1_0 - 0.406349206349206*G0_1_0_6_1_1 + 0.632098765432099*G0_1_0_7_1_0 - 0.496649029982363*G0_1_0_8_1_1 + 0.0451499118165778*G0_1_0_9_1_0 + 1.17389770723104*G0_1_0_9_1_1 - 0.0451499118165778*G0_1_0_10_1_0 + 0.902998236331569*G0_1_0_10_1_1 - 0.225749559082892*G0_1_0_11_1_0 - 1.17389770723104*G0_1_0_11_1_1; + A[279] = A[281] - 2.07689594356261*G0_0_0_0_0_0 - 2.07689594356261*G0_0_0_0_0_1 - 0.812698412698413*G0_0_0_1_0_0 - 0.451499118165784*G0_0_0_2_0_1 + 0.361199294532627*G0_0_0_3_0_0 - 0.361199294532627*G0_0_0_4_0_0 + 2.52839506172839*G0_0_0_4_0_1 + 2.88959435626102*G0_0_0_5_0_0 - 2.07689594356261*G0_0_0_6_1_0 - 2.07689594356261*G0_0_0_6_1_1 - 0.812698412698413*G0_0_0_7_1_0 - 0.451499118165784*G0_0_0_8_1_1 + 0.361199294532627*G0_0_0_9_1_0 - 0.361199294532627*G0_0_0_10_1_0 + 2.52839506172839*G0_0_0_10_1_1 + 2.88959435626102*G0_0_0_11_1_0 - 0.451499118165786*G0_0_1_0_0_0 - 0.451499118165786*G0_0_1_0_0_1 + 0.270899470899471*G0_0_1_1_0_0 - 0.180599647266314*G0_0_1_2_0_1 + 0.361199294532628*G0_0_1_3_0_0 + 0.812698412698413*G0_0_1_3_0_1 - 0.361199294532628*G0_0_1_4_0_0 + 0.6320987654321*G0_0_1_4_0_1 + 0.180599647266315*G0_0_1_5_0_0 - 0.812698412698413*G0_0_1_5_0_1 - 0.451499118165786*G0_0_1_6_1_0 - 0.451499118165786*G0_0_1_6_1_1 + 0.270899470899471*G0_0_1_7_1_0 - 0.180599647266314*G0_0_1_8_1_1 + 0.361199294532628*G0_0_1_9_1_0 + 0.812698412698413*G0_0_1_9_1_1 - 0.361199294532628*G0_0_1_10_1_0 + 0.6320987654321*G0_0_1_10_1_1 + 0.180599647266315*G0_0_1_11_1_0 - 0.812698412698413*G0_0_1_11_1_1 - 0.180599647266313*G0_1_0_1_0_0 + 0.180599647266313*G0_1_0_2_0_1 + 0.180599647266314*G0_1_0_3_0_0 - 0.180599647266312*G0_1_0_3_0_1 - 0.180599647266314*G0_1_0_4_0_0 - 0.180599647266313*G0_1_0_4_0_1 + 0.180599647266313*G0_1_0_5_0_0 + 0.180599647266312*G0_1_0_5_0_1 - 0.180599647266313*G0_1_0_7_1_0 + 0.180599647266313*G0_1_0_8_1_1 + 0.180599647266314*G0_1_0_9_1_0 - 0.180599647266312*G0_1_0_9_1_1 - 0.180599647266314*G0_1_0_10_1_0 - 0.180599647266313*G0_1_0_10_1_1 + 0.180599647266313*G0_1_0_11_1_0 + 0.180599647266312*G0_1_0_11_1_1 - 2.57354497354497*G0_1_1_0_0_0 - 2.57354497354497*G0_1_1_0_0_1 - 0.225749559082889*G0_1_1_1_0_0 - 0.85784832451499*G0_1_1_2_0_1 + 0.632098765432097*G0_1_1_3_0_0 + 1.2641975308642*G0_1_1_3_0_1 - 0.632098765432097*G0_1_1_4_0_0 + 3.43139329805996*G0_1_1_4_0_1 + 2.79929453262786*G0_1_1_5_0_0 - 1.2641975308642*G0_1_1_5_0_1 - 2.57354497354497*G0_1_1_6_1_0 - 2.57354497354497*G0_1_1_6_1_1 - 0.225749559082889*G0_1_1_7_1_0 - 0.85784832451499*G0_1_1_8_1_1 + 0.632098765432097*G0_1_1_9_1_0 + 1.2641975308642*G0_1_1_9_1_1 - 0.632098765432097*G0_1_1_10_1_0 + 3.43139329805996*G0_1_1_10_1_1 + 2.79929453262786*G0_1_1_11_1_0 - 1.2641975308642*G0_1_1_11_1_1; + A[804] = A[281] - 0.451499118165786*G0_0_1_0_0_0 - 0.451499118165786*G0_0_1_0_0_1 + 0.451499118165784*G0_0_1_1_0_0 - 0.361199294532628*G0_0_1_2_0_1 + 0.180599647266313*G0_0_1_3_0_0 + 0.993298059964725*G0_0_1_3_0_1 - 0.180599647266313*G0_0_1_4_0_0 + 0.812698412698414*G0_0_1_4_0_1 - 0.993298059964726*G0_0_1_5_0_1 - 0.451499118165786*G0_0_1_6_1_0 - 0.451499118165786*G0_0_1_6_1_1 + 0.451499118165784*G0_0_1_7_1_0 - 0.361199294532628*G0_0_1_8_1_1 + 0.180599647266313*G0_0_1_9_1_0 + 0.993298059964725*G0_0_1_9_1_1 - 0.180599647266313*G0_0_1_10_1_0 + 0.812698412698414*G0_0_1_10_1_1 - 0.993298059964726*G0_0_1_11_1_1 + 0.451499118165786*G0_1_0_0_0_0 + 0.451499118165786*G0_1_0_0_0_1 - 0.451499118165784*G0_1_0_1_0_0 + 0.361199294532628*G0_1_0_2_0_1 - 0.180599647266313*G0_1_0_3_0_0 - 0.993298059964725*G0_1_0_3_0_1 + 0.180599647266313*G0_1_0_4_0_0 - 0.812698412698414*G0_1_0_4_0_1 + 0.993298059964726*G0_1_0_5_0_1 + 0.451499118165786*G0_1_0_6_1_0 + 0.451499118165786*G0_1_0_6_1_1 - 0.451499118165784*G0_1_0_7_1_0 + 0.361199294532628*G0_1_0_8_1_1 - 0.180599647266313*G0_1_0_9_1_0 - 0.993298059964725*G0_1_0_9_1_1 + 0.180599647266313*G0_1_0_10_1_0 - 0.812698412698414*G0_1_0_10_1_1 + 0.993298059964726*G0_1_0_11_1_1; + A[339] = A[804]; + A[744] = A[279]; + A[705] = A[240]; + A[300] = A[765]; + A[256] = 0.0; + A[343] = A[808]; + A[22] = 0.0; + A[739] = A[274]; + A[430] = A[895]; + A[374] = A[897] - 0.541798941798944*G0_0_1_0_0_0 - 0.541798941798944*G0_0_1_0_0_1 - 1.08359788359788*G0_0_1_1_0_0 + 0.541798941798942*G0_0_1_2_0_1 + 0.541798941798945*G0_0_1_3_0_0 - 1.08359788359788*G0_0_1_3_0_1 - 0.541798941798945*G0_0_1_4_0_0 + 1.62539682539683*G0_0_1_5_0_0 + 1.08359788359788*G0_0_1_5_0_1 - 0.541798941798944*G0_0_1_6_1_0 - 0.541798941798944*G0_0_1_6_1_1 - 1.08359788359788*G0_0_1_7_1_0 + 0.541798941798942*G0_0_1_8_1_1 + 0.541798941798945*G0_0_1_9_1_0 - 1.08359788359788*G0_0_1_9_1_1 - 0.541798941798945*G0_0_1_10_1_0 + 1.62539682539683*G0_0_1_11_1_0 + 1.08359788359788*G0_0_1_11_1_1 + 0.541798941798944*G0_1_0_0_0_0 + 0.541798941798944*G0_1_0_0_0_1 + 1.08359788359788*G0_1_0_1_0_0 - 0.541798941798942*G0_1_0_2_0_1 - 0.541798941798945*G0_1_0_3_0_0 + 1.08359788359788*G0_1_0_3_0_1 + 0.541798941798945*G0_1_0_4_0_0 - 1.62539682539683*G0_1_0_5_0_0 - 1.08359788359788*G0_1_0_5_0_1 + 0.541798941798944*G0_1_0_6_1_0 + 0.541798941798944*G0_1_0_6_1_1 + 1.08359788359788*G0_1_0_7_1_0 - 0.541798941798942*G0_1_0_8_1_1 - 0.541798941798945*G0_1_0_9_1_0 + 1.08359788359788*G0_1_0_9_1_1 + 0.541798941798945*G0_1_0_10_1_0 - 1.62539682539683*G0_1_0_11_1_0 - 1.08359788359788*G0_1_0_11_1_1; + A[53] = 0.0; + A[768] = A[303]; + A[453] = 0.0; + A[405] = 0.0; + A[80] = 0.0; + A[789] = 0.0; + A[12] = A[477]; + A[99] = A[273] + 0.0451499118165798*G0_0_1_0_0_0 + 0.0451499118165797*G0_0_1_0_0_1 + 0.180599647266315*G0_0_1_1_0_0 - 0.135449735449735*G0_0_1_2_0_1 - 0.135449735449736*G0_0_1_3_0_0 + 0.180599647266314*G0_0_1_3_0_1 + 0.135449735449736*G0_0_1_4_0_0 + 0.0902998236331557*G0_0_1_4_0_1 - 0.225749559082894*G0_0_1_5_0_0 - 0.180599647266315*G0_0_1_5_0_1 + 0.0451499118165798*G0_0_1_6_1_0 + 0.0451499118165797*G0_0_1_6_1_1 + 0.180599647266315*G0_0_1_7_1_0 - 0.135449735449735*G0_0_1_8_1_1 - 0.135449735449736*G0_0_1_9_1_0 + 0.180599647266314*G0_0_1_9_1_1 + 0.135449735449736*G0_0_1_10_1_0 + 0.0902998236331557*G0_0_1_10_1_1 - 0.225749559082894*G0_0_1_11_1_0 - 0.180599647266315*G0_0_1_11_1_1 - 0.0451499118165798*G0_1_0_0_0_0 - 0.0451499118165797*G0_1_0_0_0_1 - 0.180599647266315*G0_1_0_1_0_0 + 0.135449735449735*G0_1_0_2_0_1 + 0.135449735449736*G0_1_0_3_0_0 - 0.180599647266314*G0_1_0_3_0_1 - 0.135449735449736*G0_1_0_4_0_0 - 0.0902998236331557*G0_1_0_4_0_1 + 0.225749559082894*G0_1_0_5_0_0 + 0.180599647266315*G0_1_0_5_0_1 - 0.0451499118165798*G0_1_0_6_1_0 - 0.0451499118165797*G0_1_0_6_1_1 - 0.180599647266315*G0_1_0_7_1_0 + 0.135449735449735*G0_1_0_8_1_1 + 0.135449735449736*G0_1_0_9_1_0 - 0.180599647266314*G0_1_0_9_1_1 - 0.135449735449736*G0_1_0_10_1_0 - 0.0902998236331557*G0_1_0_10_1_1 + 0.225749559082894*G0_1_0_11_1_0 + 0.180599647266315*G0_1_0_11_1_1; + A[814] = 0.0; + A[39] = A[504]; + A[122] = A[587]; + A[847] = 0.0; + A[74] = A[539]; + A[153] = -A[161] + 0.112874779541447*G0_0_0_0_0_0 + 0.112874779541446*G0_0_0_0_0_1 - 0.383774250440916*G0_0_0_1_0_0 + 0.8352733686067*G0_0_0_2_0_1 + 1.17389770723104*G0_0_0_3_0_0 - 0.045149911816579*G0_0_0_3_0_1 - 1.17389770723104*G0_0_0_4_0_0 - 0.948148148148146*G0_0_0_4_0_1 + 0.27089947089947*G0_0_0_5_0_0 + 0.0451499118165788*G0_0_0_5_0_1 + 0.112874779541447*G0_0_0_6_1_0 + 0.112874779541446*G0_0_0_6_1_1 - 0.383774250440916*G0_0_0_7_1_0 + 0.8352733686067*G0_0_0_8_1_1 + 1.17389770723104*G0_0_0_9_1_0 - 0.045149911816579*G0_0_0_9_1_1 - 1.17389770723104*G0_0_0_10_1_0 - 0.948148148148146*G0_0_0_10_1_1 + 0.27089947089947*G0_0_0_11_1_0 + 0.0451499118165788*G0_0_0_11_1_1 - 0.496649029982364*G0_1_0_0_0_0 - 0.496649029982364*G0_1_0_0_0_1 - 0.632098765432101*G0_1_0_1_0_0 - 0.406349206349206*G0_1_0_2_0_1 - 0.948148148148148*G0_1_0_3_0_0 - 1.17389770723104*G0_1_0_3_0_1 + 0.948148148148148*G0_1_0_4_0_0 + 0.90299823633157*G0_1_0_4_0_1 + 1.12874779541446*G0_1_0_5_0_0 + 1.17389770723104*G0_1_0_5_0_1 - 0.496649029982364*G0_1_0_6_1_0 - 0.496649029982364*G0_1_0_6_1_1 - 0.632098765432101*G0_1_0_7_1_0 - 0.406349206349206*G0_1_0_8_1_1 - 0.948148148148148*G0_1_0_9_1_0 - 1.17389770723104*G0_1_0_9_1_1 + 0.948148148148148*G0_1_0_10_1_0 + 0.90299823633157*G0_1_0_10_1_1 + 1.12874779541446*G0_1_0_11_1_0 + 1.17389770723104*G0_1_0_11_1_1; + A[741] = -A[153] + 1.24162257495591*G0_0_0_0_0_0 + 1.24162257495591*G0_0_0_0_0_1 + 0.29347442680776*G0_0_0_1_0_0 + 1.15132275132275*G0_0_0_2_0_1 + 1.35449735449735*G0_0_0_3_0_0 + 0.496649029982362*G0_0_0_3_0_1 - 1.35449735449735*G0_0_0_4_0_0 - 2.39294532627865*G0_0_0_4_0_1 - 1.53509700176367*G0_0_0_5_0_0 - 0.496649029982363*G0_0_0_5_0_1 + 1.24162257495591*G0_0_0_6_1_0 + 1.24162257495591*G0_0_0_6_1_1 + 0.29347442680776*G0_0_0_7_1_0 + 1.15132275132275*G0_0_0_8_1_1 + 1.35449735449735*G0_0_0_9_1_0 + 0.496649029982362*G0_0_0_9_1_1 - 1.35449735449735*G0_0_0_10_1_0 - 2.39294532627865*G0_0_0_10_1_1 - 1.53509700176367*G0_0_0_11_1_0 - 0.496649029982363*G0_0_0_11_1_1 - 1.69312169312169*G0_0_1_0_0_0 - 1.69312169312169*G0_0_1_0_0_1 - 0.338624338624339*G0_0_1_1_0_0 - 0.33862433862434*G0_0_1_2_0_1 + 0.677248677248673*G0_0_1_3_0_0 + 0.677248677248674*G0_0_1_3_0_1 - 0.677248677248673*G0_0_1_4_0_0 + 2.03174603174603*G0_0_1_4_0_1 + 2.03174603174603*G0_0_1_5_0_0 - 0.677248677248674*G0_0_1_5_0_1 - 1.69312169312169*G0_0_1_6_1_0 - 1.69312169312169*G0_0_1_6_1_1 - 0.338624338624339*G0_0_1_7_1_0 - 0.33862433862434*G0_0_1_8_1_1 + 0.677248677248673*G0_0_1_9_1_0 + 0.677248677248674*G0_0_1_9_1_1 - 0.677248677248673*G0_0_1_10_1_0 + 2.03174603174603*G0_0_1_10_1_1 + 2.03174603174603*G0_0_1_11_1_0 - 0.677248677248674*G0_0_1_11_1_1 - 1.42222222222222*G0_1_0_0_0_0 - 1.42222222222222*G0_1_0_0_0_1 - 0.474074074074073*G0_1_0_1_0_0 - 0.474074074074073*G0_1_0_2_0_1 + 1.89629629629629*G0_1_0_4_0_1 + 1.89629629629629*G0_1_0_5_0_0 - 1.42222222222222*G0_1_0_6_1_0 - 1.42222222222222*G0_1_0_6_1_1 - 0.474074074074073*G0_1_0_7_1_0 - 0.474074074074073*G0_1_0_8_1_1 + 1.89629629629629*G0_1_0_10_1_1 + 1.89629629629629*G0_1_0_11_1_0 + 1.24162257495591*G0_1_1_0_0_0 + 1.24162257495591*G0_1_1_0_0_1 + 1.15132275132275*G0_1_1_1_0_0 + 0.293474426807759*G0_1_1_2_0_1 + 0.496649029982363*G0_1_1_3_0_0 + 1.35449735449736*G0_1_1_3_0_1 - 0.496649029982363*G0_1_1_4_0_0 - 1.53509700176366*G0_1_1_4_0_1 - 2.39294532627866*G0_1_1_5_0_0 - 1.35449735449736*G0_1_1_5_0_1 + 1.24162257495591*G0_1_1_6_1_0 + 1.24162257495591*G0_1_1_6_1_1 + 1.15132275132275*G0_1_1_7_1_0 + 0.293474426807759*G0_1_1_8_1_1 + 0.496649029982363*G0_1_1_9_1_0 + 1.35449735449736*G0_1_1_9_1_1 - 0.496649029982363*G0_1_1_10_1_0 - 1.53509700176366*G0_1_1_10_1_1 - 2.39294532627866*G0_1_1_11_1_0 - 1.35449735449736*G0_1_1_11_1_1; + A[276] = A[741]; + A[654] = A[741] + 0.632098765432101*G0_0_1_0_0_0 + 0.632098765432101*G0_0_1_0_0_1 + 0.31604938271605*G0_0_1_1_0_0 + 0.316049382716051*G0_0_1_2_0_1 + 0.316049382716051*G0_0_1_3_0_0 + 0.31604938271605*G0_0_1_3_0_1 - 0.316049382716051*G0_0_1_4_0_0 - 0.948148148148152*G0_0_1_4_0_1 - 0.948148148148151*G0_0_1_5_0_0 - 0.31604938271605*G0_0_1_5_0_1 + 0.632098765432101*G0_0_1_6_1_0 + 0.632098765432101*G0_0_1_6_1_1 + 0.31604938271605*G0_0_1_7_1_0 + 0.316049382716051*G0_0_1_8_1_1 + 0.316049382716051*G0_0_1_9_1_0 + 0.31604938271605*G0_0_1_9_1_1 - 0.316049382716051*G0_0_1_10_1_0 - 0.948148148148152*G0_0_1_10_1_1 - 0.948148148148151*G0_0_1_11_1_0 - 0.31604938271605*G0_0_1_11_1_1 - 0.632098765432101*G0_1_0_0_0_0 - 0.632098765432101*G0_1_0_0_0_1 - 0.31604938271605*G0_1_0_1_0_0 - 0.316049382716051*G0_1_0_2_0_1 - 0.316049382716051*G0_1_0_3_0_0 - 0.31604938271605*G0_1_0_3_0_1 + 0.316049382716051*G0_1_0_4_0_0 + 0.948148148148152*G0_1_0_4_0_1 + 0.94814814814815*G0_1_0_5_0_0 + 0.31604938271605*G0_1_0_5_0_1 - 0.632098765432101*G0_1_0_6_1_0 - 0.632098765432101*G0_1_0_6_1_1 - 0.31604938271605*G0_1_0_7_1_0 - 0.316049382716051*G0_1_0_8_1_1 - 0.316049382716051*G0_1_0_9_1_0 - 0.31604938271605*G0_1_0_9_1_1 + 0.316049382716051*G0_1_0_10_1_0 + 0.948148148148152*G0_1_0_10_1_1 + 0.94814814814815*G0_1_0_11_1_0 + 0.31604938271605*G0_1_0_11_1_1; + A[189] = A[654]; + A[876] = 0.0; + A[485] = 0.0; + A[188] = A[653]; + A[586] = A[121]; + A[510] = 0.0; + A[223] = A[688]; + A[611] = 0.0; + A[547] = 0.0; + A[507] = A[42]; + A[640] = 0.0; + A[536] = A[71]; + A[661] = 0.0; + A[282] = A[747]; + A[694] = 0.0; + A[311] = A[776]; + A[263] = 0.0; + A[332] = A[797]; + A[292] = 0.0; + A[746] = A[281]; + A[433] = A[898]; + A[365] = A[830]; + A[321] = 0.0; + A[777] = A[312]; + A[458] = 0.0; + A[398] = A[863]; + A[354] = 0.0; + A[796] = A[331]; + A[3] = A[468]; + A[720] = 0.0; + A[104] = A[569]; + A[839] = A[374]; + A[32] = A[497]; + A[129] = A[594]; + A[69] = A[534]; + A[162] = A[627]; + A[110] = 0.0; + A[183] = A[648]; + A[143] = 0.0; + A[595] = A[130]; + A[220] = A[685]; + A[172] = 0.0; + A[618] = A[153]; + A[498] = A[33]; + A[649] = A[184]; + A[529] = A[64]; + A[684] = A[219]; + A[564] = A[99]; + A[719] = A[254]; + A[440] = 0.0; + A[328] = 0.0; + A[778] = A[313]; + A[467] = A[2]; + A[391] = A[856]; + A[347] = 0.0; + A[807] = A[342]; + A[26] = 0.0; + A[727] = 0.0; + A[386] = 0.0; + A[828] = A[363]; + A[57] = 0.0; + A[756] = 0.0; + A[417] = 0.0; + A[861] = A[396]; + A[60] = A[525]; + A[785] = 0.0; + A[894] = A[429]; + A[119] = 0.0; + A[818] = 0.0; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p2_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p2_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p2_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q4_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p2_q4_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p2_q4_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q1_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q1_excafe.h new file mode 100644 index 0000000..2c6747d --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q1_excafe.h @@ -0,0 +1,128 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 4.77 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][0]; + const double var_1 = x[1][0] + var_0; + const double var_2 = -x[0][1]; + const double var_3 = x[2][1] + var_2; + const double var_4 = x[1][1] + var_2; + const double var_5 = x[2][0] + var_0; + const double var_6 = -var_4*var_5 + var_1*var_3; + const double var_7 = w[0][14] + w[0][13]; + const double var_8 = -w[0][10] + 3.0000000000000000000000000*var_7; + const double var_9 = w[0][4] + w[0][3]; + const double var_10 = w[0][0] + -3.0000000000000000000000000*var_9; + const double var_11 = var_1*var_8 + var_10*var_4; + const double var_12 = w[0][10] + -3.0000000000000000000000000*var_7; + const double var_13 = var_12*var_5; + const double var_14 = var_11 + var_13; + const double var_15 = w[0][8] + w[0][7]; + const double var_16 = w[0][16] + w[0][15]; + const double var_17 = var_15*var_4 + var_16*var_5; + const double var_18 = var_1*w[0][12] + var_3*w[0][1] + 3.0000000000000000000000000*var_17; + const double var_19 = w[0][6] + w[0][5]; + const double var_20 = w[0][17] + w[0][18]; + const double var_21 = var_19*var_3 + var_1*var_20; + const double var_22 = var_5*w[0][11] + 3.0000000000000000000000000*var_21 + var_4*w[0][2]; + const double var_23 = var_18 + -var_22; + const double var_24 = var_14 + var_23; + const double var_25 = var_6; + const double var_26 = std::abs(var_25); + const double var_27 = var_6; + const double var_28 = -w[0][0] + 3.0000000000000000000000000*var_9; + const double var_29 = -var_18 + var_22; + const double var_30 = var_3*var_3 + var_5*var_5; + const double var_31 = var_10*var_3; + const double var_32 = var_28*var_4; + const double var_33 = var_31 + var_32; + const double var_34 = var_5*var_8; + const double var_35 = var_33 + var_34; + const double var_36 = var_23 + var_28*var_3; + const double var_37 = var_36 + var_11; + const double var_38 = var_1*var_37; + const double var_39 = var_35*var_5 + var_38; + const double var_40 = var_1*var_12; + const double var_41 = var_34 + var_40; + const double var_42 = var_41 + var_31; + const double var_43 = var_24*var_4; + const double var_44 = var_3*var_42 + var_43; + const double var_45 = var_39*var_5 + var_29*var_30 + var_3*var_44; + const double var_46 = var_28*var_3*var_3*var_4 + var_1*var_12*var_5*var_5 + 0.5000000000000000000000000*var_45; + A[1] = 0.2500000000000000000000000*var_26*var_46/(var_27*var_27*var_27); + A[27] = A[1]; + A[25] = 0.0000000000000000000000000; + const double var_47 = var_3*var_3*var_8 + 3.0000000000000000000000000*var_41*var_5 + var_38; + A[4] = 0.0000000000000000000000000; + const double var_48 = var_14 + var_36; + A[7] = 0.1250000000000000000000000*var_26*var_30*var_48/(var_27*var_27*var_27); + A[28] = A[7]; + const double var_49 = var_3*var_4 + var_1*var_5; + const double var_50 = var_36 + var_13; + const double var_51 = var_10*var_4*var_5; + const double var_52 = 3.0000000000000000000000000*var_3*var_33 + var_43; + const double var_53 = var_1*var_47 + var_4*var_52 + var_30*var_50 + var_5*var_51; + const double var_54 = var_29*var_49 + var_3*var_4*var_41 + var_1*var_33*var_5 + 0.5000000000000000000000000*var_53; + const double var_55 = var_29 + var_41 + var_33; + A[8] = 0.1250000000000000000000000*var_26*var_49*var_55/(var_27*var_27*var_27); + A[34] = A[8]; + A[6] = A[1]; + const double var_56 = var_33 + var_40; + const double var_57 = var_51 + var_3*var_4*var_8 + var_1*var_56; + A[24] = 0.0000000000000000000000000; + A[30] = 0.0000000000000000000000000; + A[3] = 0.0000000000000000000000000; + A[26] = 0.0000000000000000000000000; + A[5] = 0.0000000000000000000000000; + A[11] = 0.0000000000000000000000000; + A[22] = A[1]; + const double var_58 = var_1*var_1 + var_4*var_4; + const double var_59 = var_41 + var_32; + const double var_60 = var_1*var_57 + var_29*var_58 + var_49*var_50 + var_4*var_4*var_59; + const double var_61 = var_10*var_3*var_4*var_4 + var_1*var_1*var_5*var_8 + 0.5000000000000000000000000*var_60; + A[2] = 0.2500000000000000000000000*var_26*var_61/(var_27*var_27*var_27); + A[12] = A[2]; + A[13] = A[8]; + A[0] = 0.2500000000000000000000000*var_26*var_54/(var_27*var_27*var_27); + A[21] = A[0]; + A[20] = 0.0000000000000000000000000; + A[16] = 0.0000000000000000000000000; + A[15] = 0.0000000000000000000000000; + A[10] = 0.0000000000000000000000000; + A[29] = A[8]; + A[14] = 0.1250000000000000000000000*var_26*var_48*var_58/(var_27*var_27*var_27); + A[9] = 0.0000000000000000000000000; + A[32] = 0.0000000000000000000000000; + A[33] = A[2]; + A[31] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[35] = A[14]; + A[19] = 0.0000000000000000000000000; + A[17] = 0.0000000000000000000000000; + A[23] = A[2]; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q1_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q1_quadrature.h new file mode 100644 index 0000000..4dcde0e --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q1_quadrature.h @@ -0,0 +1,12060 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P3_Q1_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P3_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q1_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q1_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q1_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q1_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q1_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q1_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p3_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W3[3] = {0.166666666666667, 0.166666666666667, 0.166666666666667}; + // Quadrature points on the UFC reference element: (0.166666666666667, 0.166666666666667), (0.166666666666667, 0.666666666666667), (0.666666666666667, 0.166666666666667) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[3][2] = \ + {{-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + static const double FE1_C0_D01[3][9] = \ + {{-1, -0.125, -0.374999999999999, 0.0, 0.750000000000001, 0.375, -2.25, 0.375, 2.25}, + {0.125, 1.0, -0.374999999999999, 2.25, -0.375000000000001, -0.75, 0.0, 0.375, -2.25}, + {0.125, -0.125, 3.0, 0.0, -0.375, 0.375, 0.0, -3.0, 0.0}}; + + // Array of non-zero columns + static const unsigned int nzc10[9] = {10, 12, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc7[9] = {0, 2, 3, 4, 5, 6, 7, 8, 9}; + + static const double FE1_C0_D10[3][9] = \ + {{-1.0, -0.125, 0.0, -0.375, -2.25, 0.375, 0.750000000000001, 0.375, 2.25}, + {0.125, -0.125, 0.0, 3.0, 0.0, -3.0, -0.375, 0.374999999999999, 0.0}, + {0.125, 1.0, 2.25, -0.374999999999999, 0.0, 0.375, -0.375, -0.75, -2.25}}; + + // Array of non-zero columns + static const unsigned int nzc11[9] = {10, 11, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc8[9] = {0, 1, 3, 4, 5, 6, 7, 8, 9}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 60. + double G[12]; + G[0] = K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 576 + for (unsigned int ip = 0; ip < 3; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 72 + for (unsigned int r = 0; r < 9; r++) + { + F0 += FE1_C0_D10[ip][r]*w[0][nzc8[r]]; + F1 += FE1_C0_D01[ip][r]*w[0][nzc7[r]]; + F2 += FE1_C0_D10[ip][r]*w[0][nzc11[r]]; + F3 += FE1_C0_D01[ip][r]*w[0][nzc10[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 24 + double I[3]; + // Number of operations: 8 + I[0] = W3[ip]*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 8 + I[1] = W3[ip]*(F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 8 + I[2] = W3[ip]*(F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 96 + for (unsigned int j = 0; j < 2; j++) + { + for (unsigned int k = 0; k < 2; k++) + { + // Number of operations to compute entry: 3 + A[nzc1[j]*6 + nzc1[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc1[j]*6 + nzc2[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*6 + nzc1[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*6 + nzc2[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc4[j]*6 + nzc4[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc4[j]*6 + nzc5[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*6 + nzc4[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*6 + nzc5[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p3_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q1_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q1_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q1_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q1_tensor.h new file mode 100644 index 0000000..b23d6a6 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q1_tensor.h @@ -0,0 +1,12070 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P3_Q1_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P3_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q1_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q1_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q1_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q1_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q1_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q1_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p3_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 288 + // Number of operations (multiply-add pairs) for tensor contraction: 238 + // Total number of operations (multiply-add pairs): 537 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0 = det*(w[0][3]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1 = det*(w[0][3]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0 = det*(w[0][4]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1 = det*(w[0][4]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0 = det*(w[0][5]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_0_0 = det*(w[0][6]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_0_1 = det*(w[0][7]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_0_1 = det*(w[0][8]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0 = det*(w[0][10]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1 = det*(w[0][10]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0 = det*(w[0][11]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_12_1_1 = det*(w[0][12]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_13_1_0 = det*(w[0][13]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_13_1_1 = det*(w[0][13]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_14_1_0 = det*(w[0][14]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_14_1_1 = det*(w[0][14]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_15_1_0 = det*(w[0][15]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_16_1_0 = det*(w[0][16]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_17_1_1 = det*(w[0][17]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_18_1_1 = det*(w[0][18]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0 = det*(w[0][3]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1 = det*(w[0][3]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0 = det*(w[0][4]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1 = det*(w[0][4]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0 = det*(w[0][5]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_0_0 = det*(w[0][6]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_0_1 = det*(w[0][7]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_0_1 = det*(w[0][8]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0 = det*(w[0][10]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1 = det*(w[0][10]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0 = det*(w[0][11]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_12_1_1 = det*(w[0][12]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_13_1_0 = det*(w[0][13]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_13_1_1 = det*(w[0][13]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_14_1_0 = det*(w[0][14]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_14_1_1 = det*(w[0][14]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_15_1_0 = det*(w[0][15]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_16_1_0 = det*(w[0][16]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_17_1_1 = det*(w[0][17]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_18_1_1 = det*(w[0][18]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0 = det*(w[0][3]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1 = det*(w[0][3]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0 = det*(w[0][4]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1 = det*(w[0][4]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0 = det*(w[0][5]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_0_0 = det*(w[0][6]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_0_1 = det*(w[0][7]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_0_1 = det*(w[0][8]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0 = det*(w[0][10]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1 = det*(w[0][10]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0 = det*(w[0][11]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_12_1_1 = det*(w[0][12]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_13_1_0 = det*(w[0][13]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_13_1_1 = det*(w[0][13]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_14_1_0 = det*(w[0][14]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_14_1_1 = det*(w[0][14]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_15_1_0 = det*(w[0][15]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_16_1_0 = det*(w[0][16]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_17_1_1 = det*(w[0][17]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_18_1_1 = det*(w[0][18]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0 = det*(w[0][3]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1 = det*(w[0][3]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0 = det*(w[0][4]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1 = det*(w[0][4]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0 = det*(w[0][5]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_0_0 = det*(w[0][6]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_0_1 = det*(w[0][7]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_0_1 = det*(w[0][8]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0 = det*(w[0][10]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1 = det*(w[0][10]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0 = det*(w[0][11]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_12_1_1 = det*(w[0][12]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_13_1_0 = det*(w[0][13]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_13_1_1 = det*(w[0][13]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_14_1_0 = det*(w[0][14]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_14_1_1 = det*(w[0][14]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_15_1_0 = det*(w[0][15]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_16_1_0 = det*(w[0][16]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_17_1_1 = det*(w[0][17]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_18_1_1 = det*(w[0][18]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[9] = 0.0; + A[18] = 0.0; + A[20] = 0.0; + A[31] = 0.0; + A[3] = 0.0; + A[17] = 0.0; + A[24] = 0.0; + A[8] = -0.125*G0_0_1_0_0_0 - 0.125*G0_0_1_0_0_1 + 0.125*G0_0_1_1_0_0 + 0.125*G0_0_1_2_0_1 + 0.374999999999999*G0_0_1_3_0_0 + 0.375*G0_0_1_3_0_1 + 0.375*G0_0_1_4_0_0 + 0.375*G0_0_1_4_0_1 - 0.375*G0_0_1_5_0_0 - 0.375*G0_0_1_6_0_0 - 0.375*G0_0_1_7_0_1 - 0.375*G0_0_1_8_0_1 - 0.125*G0_0_1_10_1_0 - 0.125*G0_0_1_10_1_1 + 0.125*G0_0_1_11_1_0 + 0.125*G0_0_1_12_1_1 + 0.374999999999999*G0_0_1_13_1_0 + 0.375*G0_0_1_13_1_1 + 0.375*G0_0_1_14_1_0 + 0.375*G0_0_1_14_1_1 - 0.375*G0_0_1_15_1_0 - 0.375*G0_0_1_16_1_0 - 0.375*G0_0_1_17_1_1 - 0.375*G0_0_1_18_1_1; + A[28] = -0.125*G0_0_0_0_0_0 - 0.125*G0_0_0_0_0_1 + 0.125*G0_0_0_1_0_0 + 0.125*G0_0_0_2_0_1 + 0.374999999999999*G0_0_0_3_0_0 + 0.375*G0_0_0_3_0_1 + 0.375*G0_0_0_4_0_0 + 0.375*G0_0_0_4_0_1 - 0.375*G0_0_0_5_0_0 - 0.375*G0_0_0_6_0_0 - 0.375*G0_0_0_7_0_1 - 0.375*G0_0_0_8_0_1 - 0.125*G0_0_0_10_1_0 - 0.125*G0_0_0_10_1_1 + 0.125*G0_0_0_11_1_0 + 0.125*G0_0_0_12_1_1 + 0.374999999999999*G0_0_0_13_1_0 + 0.375*G0_0_0_13_1_1 + 0.375*G0_0_0_14_1_0 + 0.375*G0_0_0_14_1_1 - 0.375*G0_0_0_15_1_0 - 0.375*G0_0_0_16_1_0 - 0.375*G0_0_0_17_1_1 - 0.375*G0_0_0_18_1_1; + A[11] = 0.0; + A[30] = 0.0; + A[4] = 0.0; + A[25] = 0.0; + A[7] = A[28]; + A[34] = -0.125*G0_1_0_0_0_0 - 0.125*G0_1_0_0_0_1 + 0.125*G0_1_0_1_0_0 + 0.125*G0_1_0_2_0_1 + 0.374999999999999*G0_1_0_3_0_0 + 0.375*G0_1_0_3_0_1 + 0.375*G0_1_0_4_0_0 + 0.375*G0_1_0_4_0_1 - 0.375*G0_1_0_5_0_0 - 0.375*G0_1_0_6_0_0 - 0.375*G0_1_0_7_0_1 - 0.375*G0_1_0_8_0_1 - 0.125*G0_1_0_10_1_0 - 0.125*G0_1_0_10_1_1 + 0.125*G0_1_0_11_1_0 + 0.125*G0_1_0_12_1_1 + 0.374999999999999*G0_1_0_13_1_0 + 0.375*G0_1_0_13_1_1 + 0.375*G0_1_0_14_1_0 + 0.375*G0_1_0_14_1_1 - 0.375*G0_1_0_15_1_0 - 0.375*G0_1_0_16_1_0 - 0.375*G0_1_0_17_1_1 - 0.375*G0_1_0_18_1_1; + A[13] = A[34]; + A[33] = -A[34] + 0.125*G0_1_1_0_0_0 + 0.125*G0_1_1_0_0_1 - 0.125*G0_1_1_1_0_0 - 0.125*G0_1_1_2_0_1 - 0.374999999999999*G0_1_1_3_0_0 - 0.375*G0_1_1_3_0_1 - 0.375*G0_1_1_4_0_0 - 0.375*G0_1_1_4_0_1 + 0.375*G0_1_1_5_0_0 + 0.375*G0_1_1_6_0_0 + 0.375*G0_1_1_7_0_1 + 0.375*G0_1_1_8_0_1 + 0.125*G0_1_1_10_1_0 + 0.125*G0_1_1_10_1_1 - 0.125*G0_1_1_11_1_0 - 0.125*G0_1_1_12_1_1 - 0.374999999999999*G0_1_1_13_1_0 - 0.375*G0_1_1_13_1_1 - 0.375*G0_1_1_14_1_0 - 0.375*G0_1_1_14_1_1 + 0.375*G0_1_1_15_1_0 + 0.375*G0_1_1_16_1_0 + 0.375*G0_1_1_17_1_1 + 0.375*G0_1_1_18_1_1; + A[1] = -A[34] + 0.125*G0_0_0_0_0_0 + 0.125*G0_0_0_0_0_1 - 0.125*G0_0_0_1_0_0 - 0.125*G0_0_0_2_0_1 - 0.374999999999999*G0_0_0_3_0_0 - 0.375*G0_0_0_3_0_1 - 0.375*G0_0_0_4_0_0 - 0.375*G0_0_0_4_0_1 + 0.375*G0_0_0_5_0_0 + 0.375*G0_0_0_6_0_0 + 0.375*G0_0_0_7_0_1 + 0.375*G0_0_0_8_0_1 + 0.125*G0_0_0_10_1_0 + 0.125*G0_0_0_10_1_1 - 0.125*G0_0_0_11_1_0 - 0.125*G0_0_0_12_1_1 - 0.374999999999999*G0_0_0_13_1_0 - 0.375*G0_0_0_13_1_1 - 0.375*G0_0_0_14_1_0 - 0.375*G0_0_0_14_1_1 + 0.375*G0_0_0_15_1_0 + 0.375*G0_0_0_16_1_0 + 0.375*G0_0_0_17_1_1 + 0.375*G0_0_0_18_1_1; + A[29] = A[8]; + A[14] = -0.125*G0_1_1_0_0_0 - 0.125*G0_1_1_0_0_1 + 0.125*G0_1_1_1_0_0 + 0.125*G0_1_1_2_0_1 + 0.374999999999999*G0_1_1_3_0_0 + 0.375*G0_1_1_3_0_1 + 0.375*G0_1_1_4_0_0 + 0.375*G0_1_1_4_0_1 - 0.375*G0_1_1_5_0_0 - 0.375*G0_1_1_6_0_0 - 0.375*G0_1_1_7_0_1 - 0.375*G0_1_1_8_0_1 - 0.125*G0_1_1_10_1_0 - 0.125*G0_1_1_10_1_1 + 0.125*G0_1_1_11_1_0 + 0.125*G0_1_1_12_1_1 + 0.374999999999999*G0_1_1_13_1_0 + 0.375*G0_1_1_13_1_1 + 0.375*G0_1_1_14_1_0 + 0.375*G0_1_1_14_1_1 - 0.375*G0_1_1_15_1_0 - 0.375*G0_1_1_16_1_0 - 0.375*G0_1_1_17_1_1 - 0.375*G0_1_1_18_1_1; + A[10] = 0.0; + A[5] = 0.0; + A[26] = 0.0; + A[6] = -A[8] + 0.125*G0_0_0_0_0_0 + 0.125*G0_0_0_0_0_1 - 0.125*G0_0_0_1_0_0 - 0.125*G0_0_0_2_0_1 - 0.374999999999999*G0_0_0_3_0_0 - 0.375*G0_0_0_3_0_1 - 0.375*G0_0_0_4_0_0 - 0.375*G0_0_0_4_0_1 + 0.375*G0_0_0_5_0_0 + 0.375*G0_0_0_6_0_0 + 0.375*G0_0_0_7_0_1 + 0.375*G0_0_0_8_0_1 + 0.125*G0_0_0_10_1_0 + 0.125*G0_0_0_10_1_1 - 0.125*G0_0_0_11_1_0 - 0.125*G0_0_0_12_1_1 - 0.374999999999999*G0_0_0_13_1_0 - 0.375*G0_0_0_13_1_1 - 0.375*G0_0_0_14_1_0 - 0.375*G0_0_0_14_1_1 + 0.375*G0_0_0_15_1_0 + 0.375*G0_0_0_16_1_0 + 0.375*G0_0_0_17_1_1 + 0.375*G0_0_0_18_1_1; + A[35] = A[14]; + A[23] = -A[8] + 0.125*G0_1_1_0_0_0 + 0.125*G0_1_1_0_0_1 - 0.125*G0_1_1_1_0_0 - 0.125*G0_1_1_2_0_1 - 0.374999999999999*G0_1_1_3_0_0 - 0.375*G0_1_1_3_0_1 - 0.375*G0_1_1_4_0_0 - 0.375*G0_1_1_4_0_1 + 0.375*G0_1_1_5_0_0 + 0.375*G0_1_1_6_0_0 + 0.375*G0_1_1_7_0_1 + 0.375*G0_1_1_8_0_1 + 0.125*G0_1_1_10_1_0 + 0.125*G0_1_1_10_1_1 - 0.125*G0_1_1_11_1_0 - 0.125*G0_1_1_12_1_1 - 0.374999999999999*G0_1_1_13_1_0 - 0.375*G0_1_1_13_1_1 - 0.375*G0_1_1_14_1_0 - 0.375*G0_1_1_14_1_1 + 0.375*G0_1_1_15_1_0 + 0.375*G0_1_1_16_1_0 + 0.375*G0_1_1_17_1_1 + 0.375*G0_1_1_18_1_1; + A[21] = -A[23] - 0.125*G0_0_0_0_0_0 - 0.125*G0_0_0_0_0_1 + 0.125*G0_0_0_1_0_0 + 0.125*G0_0_0_2_0_1 + 0.374999999999999*G0_0_0_3_0_0 + 0.375*G0_0_0_3_0_1 + 0.375*G0_0_0_4_0_0 + 0.375*G0_0_0_4_0_1 - 0.375*G0_0_0_5_0_0 - 0.375*G0_0_0_6_0_0 - 0.375*G0_0_0_7_0_1 - 0.375*G0_0_0_8_0_1 - 0.125*G0_0_0_10_1_0 - 0.125*G0_0_0_10_1_1 + 0.125*G0_0_0_11_1_0 + 0.125*G0_0_0_12_1_1 + 0.374999999999999*G0_0_0_13_1_0 + 0.375*G0_0_0_13_1_1 + 0.375*G0_0_0_14_1_0 + 0.375*G0_0_0_14_1_1 - 0.375*G0_0_0_15_1_0 - 0.375*G0_0_0_16_1_0 - 0.375*G0_0_0_17_1_1 - 0.375*G0_0_0_18_1_1 - 0.125*G0_1_0_0_0_0 - 0.125*G0_1_0_0_0_1 + 0.125*G0_1_0_1_0_0 + 0.125*G0_1_0_2_0_1 + 0.374999999999999*G0_1_0_3_0_0 + 0.375*G0_1_0_3_0_1 + 0.375*G0_1_0_4_0_0 + 0.375*G0_1_0_4_0_1 - 0.375*G0_1_0_5_0_0 - 0.375*G0_1_0_6_0_0 - 0.375*G0_1_0_7_0_1 - 0.375*G0_1_0_8_0_1 - 0.125*G0_1_0_10_1_0 - 0.125*G0_1_0_10_1_1 + 0.125*G0_1_0_11_1_0 + 0.125*G0_1_0_12_1_1 + 0.374999999999999*G0_1_0_13_1_0 + 0.375*G0_1_0_13_1_1 + 0.375*G0_1_0_14_1_0 + 0.375*G0_1_0_14_1_1 - 0.375*G0_1_0_15_1_0 - 0.375*G0_1_0_16_1_0 - 0.375*G0_1_0_17_1_1 - 0.375*G0_1_0_18_1_1; + A[0] = A[21]; + A[22] = A[1]; + A[19] = 0.0; + A[16] = 0.0; + A[12] = A[33]; + A[27] = A[6]; + A[15] = 0.0; + A[32] = 0.0; + A[2] = A[23]; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p3_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q1_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q1_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q1_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q2_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q2_excafe.h new file mode 100644 index 0000000..79df673 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q2_excafe.h @@ -0,0 +1,666 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 3 minutes and 54.08 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][0]; + const double var_1 = x[1][0] + var_0; + const double var_2 = -x[0][1]; + const double var_3 = x[1][1] + var_2; + const double var_4 = x[2][0] + var_0; + const double var_5 = x[2][1] + var_2; + const double var_6 = var_1*var_5; + const double var_7 = var_3*var_4; + const double var_8 = var_6 + var_7; + const double var_9 = var_1*var_1*var_4 + 0.5000000000000000000000000*var_3*var_8; + const double var_10 = -var_4*w[0][17]; + const double var_11 = var_1*w[0][15]; + const double var_12 = var_10 + var_1*w[0][13] + var_11; + const double var_13 = -var_3*var_4 + var_6; + const double var_14 = var_13; + const double var_15 = std::abs(var_14); + const double var_16 = var_4*w[0][4] + var_5*w[0][14]; + const double var_17 = var_1*var_4; + const double var_18 = var_3*var_5; + const double var_19 = var_17 + var_18; + const double var_20 = 3.0000000000000000000000000*var_3*var_4 + var_6; + const double var_21 = 3.0000000000000000000000000*var_1*var_5 + var_7; + const double var_22 = -var_3*var_3*var_4*w[0][18] + var_1*var_1*var_5*w[0][8]; + const double var_23 = var_4*var_4 + var_5*var_5; + const double var_24 = var_5*w[0][9]; + const double var_25 = -var_4*w[0][19] + var_24; + const double var_26 = 2.0000000000000000000000000*var_23*var_25; + const double var_27 = var_4*w[0][13] + -var_5*w[0][3]; + const double var_28 = var_23*var_27; + const double var_29 = -var_5*w[0][5]; + const double var_30 = var_4*w[0][15]; + const double var_31 = var_29 + var_30; + const double var_32 = var_23*var_31; + const double var_33 = var_1*var_1 + var_3*var_3; + const double var_34 = -w[0][13]; + const double var_35 = w[0][18] + var_34; + const double var_36 = w[0][3] + -w[0][8]; + const double var_37 = var_1*var_35 + var_3*var_36; + const double var_38 = var_33*var_37; + const double var_39 = -var_3*w[0][4] + var_1*w[0][14]; + const double var_40 = -var_3*w[0][7]; + const double var_41 = var_1*w[0][17]; + const double var_42 = var_40 + var_41; + const double var_43 = var_39 + var_42; + const double var_44 = w[0][13] + -w[0][18]; + const double var_45 = var_44*var_5; + const double var_46 = -w[0][3]; + const double var_47 = w[0][8] + var_46; + const double var_48 = var_4*var_47; + const double var_49 = var_45 + var_48; + const double var_50 = 3.0000000000000000000000000*var_1*var_49 + 4.0000000000000000000000000*var_3*var_5*w[0][8]; + const double var_51 = var_3*var_3*var_4*w[0][13] + -var_1*var_1*var_5*w[0][3]; + const double var_52 = -var_1*var_1*var_4*w[0][18]; + const double var_53 = var_1*w[0][9]; + const double var_54 = -var_3*w[0][19] + var_53; + const double var_55 = var_51 + 2.0000000000000000000000000*var_52 + var_54*var_8; + const double var_56 = 3.0000000000000000000000000*var_38 + var_3*var_50 + var_28 + -var_21*var_4*w[0][9] + var_26 + var_32 + var_22 + var_20*var_5*w[0][19] + var_19*var_43 + 2.0000000000000000000000000*var_55; + const double var_57 = var_13; + const double var_58 = var_5 + -var_3; + const double var_59 = var_1 + -var_4; + const double var_60 = var_58*w[0][0] + var_59*w[0][10]; + const double var_61 = var_5*w[0][1] + -var_4*w[0][11]; + const double var_62 = var_1*w[0][12] + -var_3*w[0][2]; + const double var_63 = var_62 + var_61; + const double var_64 = var_1*var_44 + var_3*var_47; + const double var_65 = -w[0][6] + w[0][4]; + const double var_66 = -w[0][14]; + const double var_67 = w[0][16] + var_66; + const double var_68 = var_4*var_67 + var_5*var_65; + const double var_69 = var_64 + var_68; + const double var_70 = -var_1*w[0][17]; + const double var_71 = var_3*w[0][7]; + const double var_72 = var_70 + var_71; + const double var_73 = var_31 + var_72; + const double var_74 = var_3*w[0][4] + -var_1*w[0][14]; + const double var_75 = var_74 + var_27; + const double var_76 = -var_1*w[0][16]; + const double var_77 = var_3*w[0][6] + var_76; + const double var_78 = -var_5*w[0][8]; + const double var_79 = var_4*w[0][18] + var_78; + const double var_80 = -var_5*w[0][7]; + const double var_81 = var_4*w[0][17]; + const double var_82 = var_80 + var_81; + const double var_83 = -var_1*w[0][15]; + const double var_84 = var_3*w[0][5]; + const double var_85 = var_83 + var_84; + const double var_86 = var_85 + var_79 + var_82 + var_77; + const double var_87 = var_59*w[0][19] + var_58*w[0][9] + 0.5000000000000000000000000*var_86 + 0.7500000000000000000000000*var_75; + const double var_88 = 0.1500000000000000222044605*var_73 + 0.1166666666666666685170384*var_60 + 0.4833333333333333370340767*var_63 + 0.7500000000000000000000000*var_69 + 0.6000000000000000888178420*var_87; + A[14] = 0.5000000000000000000000000*var_15*var_19*var_88/(var_57*var_57*var_57); + A[92] = A[14]; + const double var_89 = var_3 + -var_5; + const double var_90 = var_8*var_89 + 2.0000000000000000000000000*var_1*var_4*var_59; + const double var_91 = 2.0000000000000000000000000*var_1*var_1*var_4; + const double var_92 = var_3*var_8 + var_91; + const double var_93 = 2.0000000000000000000000000*var_3*var_5*var_5; + const double var_94 = var_4*var_8 + var_93; + const double var_95 = 2.0000000000000000000000000*var_3*var_3*var_5 + var_1*var_8; + const double var_96 = 2.0000000000000000000000000*var_1*var_4*var_4 + var_5*var_8; + const double var_97 = var_4 + -var_1; + const double var_98 = 2.0000000000000000000000000*var_3*var_5*var_58 + var_8*var_97; + const double var_99 = -4.0000000000000000000000000*var_1*var_1*var_4 + -var_21*var_3; + const double var_100 = -4.0000000000000000000000000*var_3*var_5*var_5 + -var_21*var_4; + const double var_101 = 4.0000000000000000000000000*var_3*var_3*var_5 + var_1*var_20; + const double var_102 = 4.0000000000000000000000000*var_1*var_4*var_4 + var_20*var_5; + const double var_103 = -var_4*w[0][13] + var_5*w[0][3]; + const double var_104 = var_33*var_39 + var_103*var_23; + const double var_105 = var_3*w[0][9]; + const double var_106 = -var_1*w[0][19] + var_105; + const double var_107 = var_106*var_33; + const double var_108 = var_4*w[0][19]; + const double var_109 = -var_5*w[0][9] + var_108; + const double var_110 = var_109*var_23; + const double var_111 = var_107 + var_110; + const double var_112 = -var_4*w[0][15]; + const double var_113 = var_5*w[0][5]; + const double var_114 = var_112 + var_113; + const double var_115 = var_114*var_23; + const double var_116 = var_33*var_42; + const double var_117 = var_98*w[0][9] + 2.0000000000000000000000000*var_111 + var_104 + var_115 + var_116; + const double var_118 = w[0][18] + w[0][16]; + const double var_119 = w[0][7] + w[0][3]; + const double var_120 = w[0][4] + w[0][5]; + const double var_121 = w[0][8] + w[0][6]; + const double var_122 = w[0][15] + w[0][14]; + const double var_123 = w[0][17] + w[0][13]; + const double var_124 = var_4*w[0][5]; + const double var_125 = var_3*w[0][17]; + const double var_126 = var_124 + var_125; + const double var_127 = var_5*w[0][15]; + const double var_128 = var_1*w[0][7]; + const double var_129 = var_127 + var_128; + const double var_130 = var_126 + var_129; + const double var_131 = var_102*var_123 + var_121*var_98 + var_118*var_90 + var_100*var_119 + -var_92*w[0][13] + var_96*w[0][14] + 2.0000000000000000000000000*var_117 + var_95*w[0][3] + -var_94*w[0][4] + var_122*var_99 + var_101*var_120 + var_13*var_130; + const double var_132 = var_4*w[0][11] + -var_5*w[0][1]; + const double var_133 = -var_1*w[0][12] + var_3*w[0][2]; + const double var_134 = var_132 + var_133; + const double var_135 = 1.3333333333333332593184650*var_19*var_60 + 0.6000000000000000888178420*var_131 + 1.2000000000000001776356839*var_90*w[0][19] + 0.1333333333333333314829616*var_134*var_19; + A[53] = var_135*var_15/(var_57*var_57*var_57); + A[89] = 0.0000000000000000000000000; + const double var_136 = var_3*w[0][0] + -var_1*w[0][10]; + const double var_137 = var_5*w[0][0] + -var_4*w[0][10]; + const double var_138 = var_136*var_19 + var_137*var_23; + A[134] = 0.0000000000000000000000000; + const double var_139 = 0.2000000000000000111022302*var_1*var_5 + var_7; + const double var_140 = 0.7000000000000000666133815*var_3*var_4*w[0][6] + var_139*w[0][9]; + const double var_141 = var_136*var_33; + const double var_142 = var_4*w[0][10] + -var_5*w[0][0]; + const double var_143 = var_142*var_23; + const double var_144 = var_141 + var_143; + A[121] = 0.0000000000000000000000000; + const double var_145 = -var_3*var_3*var_4*w[0][13] + var_1*var_1*var_5*w[0][3]; + const double var_146 = var_1*var_5*var_5*w[0][14] + -var_3*var_4*var_4*w[0][4]; + const double var_147 = var_145 + var_146; + const double var_148 = var_147 + -var_126*var_21 + var_129*var_20; + const double var_149 = var_62 + var_136; + const double var_150 = -var_3*var_4*var_4*w[0][6] + var_1*var_5*var_5*w[0][16]; + const double var_151 = -var_3*w[0][0] + var_1*w[0][10]; + const double var_152 = var_151*var_33 + var_142*var_19; + const double var_153 = var_1*var_1*var_4*w[0][14] + -var_3*var_3*var_5*w[0][4]; + const double var_154 = -var_1*var_4*var_4*w[0][13] + var_3*var_5*var_5*w[0][3]; + const double var_155 = var_3*var_5*var_5 + 0.5000000000000000000000000*var_4*var_8; + const double var_156 = var_3*var_3*var_5 + 0.5000000000000000000000000*var_1*var_8; + const double var_157 = var_1*var_4*var_4 + 0.5000000000000000000000000*var_5*var_8; + const double var_158 = var_89*w[0][17] + var_5*var_67; + const double var_159 = -1.5000000000000000000000000*var_4*w[0][15] + 7.0000000000000000000000000*var_5*w[0][6]; + const double var_160 = -var_1*var_5 + var_7; + const double var_161 = var_160*w[0][19]; + const double var_162 = var_159*var_3 + 3.5000000000000000000000000*var_158*var_4 + var_161; + const double var_163 = -w[0][16] + w[0][14]; + const double var_164 = -w[0][4]; + const double var_165 = w[0][6] + var_164; + const double var_166 = var_163*var_3*var_3*var_4 + var_1*var_1*var_165*var_5; + const double var_167 = -var_3*w[0][6]; + const double var_168 = var_167 + var_42; + const double var_169 = -var_157*w[0][15] + var_168*var_33 + 0.5000000000000000000000000*var_166 + var_155*w[0][5]; + const double var_170 = var_133*var_23; + const double var_171 = -var_20*var_5*w[0][13] + var_21*var_4*w[0][3]; + const double var_172 = var_33*var_74; + const double var_173 = var_172 + var_28; + const double var_174 = 0.5000000000000000000000000*var_171 + 3.0000000000000000000000000*var_169 + -var_155*w[0][8] + var_156*var_47 + var_170 + var_157*w[0][18] + var_44*var_9 + var_162*var_3 + var_173; + const double var_175 = var_163*var_4 + var_165*var_5; + const double var_176 = var_175*var_23; + const double var_177 = -var_1*var_5*var_5*w[0][14] + var_3*var_4*var_4*w[0][4]; + const double var_178 = var_3*var_4*var_4*w[0][7] + -var_1*var_5*var_5*w[0][17] + var_177; + const double var_179 = 0.5000000000000000000000000*var_32 + -var_155*w[0][9] + 0.2500000000000000000000000*var_178 + var_157*w[0][19]; + const double var_180 = -var_3*var_5*var_5*w[0][6]; + const double var_181 = var_17*var_4*w[0][16] + var_179 + var_180; + const double var_182 = -var_3*var_3*var_5*w[0][7] + 3.0000000000000000000000000*var_181 + var_154 + var_176 + 0.5000000000000000000000000*var_174 + 2.0000000000000000000000000*var_153 + var_26 + var_17*var_41 + var_107; + const double var_183 = -var_4*w[0][5] + var_127; + const double var_184 = -var_5*w[0][16]; + const double var_185 = 2.2000000000000001776356839*w[0][6] + var_164 + 0.6000000000000000888178420*w[0][7]; + const double var_186 = -0.6000000000000000888178420*w[0][17] + w[0][14]; + const double var_187 = var_185*var_4 + 2.6000000000000000888178420*var_183 + var_186*var_5 + 2.2000000000000001776356839*var_184; + const double var_188 = var_10 + 0.7000000000000000666133815*var_5*var_65 + -var_4*w[0][14] + 1.4000000000000001332267630*var_76; + const double var_189 = var_160*w[0][9]; + const double var_190 = 0.7000000000000000666133815*var_5*var_97*w[0][7] + 0.2000000000000000111022302*var_189 + var_17*w[0][15] + var_188*var_4 + 0.3000000000000000444089210*var_1*var_5*w[0][5] + 0.6000000000000000888178420*var_33*w[0][16] + 0.5000000000000000000000000*var_187*var_3; + const double var_191 = -var_3*w[0][5]; + const double var_192 = var_5*w[0][7]; + const double var_193 = var_191 + var_5*w[0][4] + var_192; + const double var_194 = var_18*var_193 + var_33*var_85 + var_1*var_190; + const double var_195 = var_156*w[0][0] + -var_9*w[0][10]; + const double var_196 = var_132*var_33; + const double var_197 = var_19*var_61; + const double var_198 = var_196 + var_197; + const double var_199 = 0.0666666666666666657414808*var_198; + const double var_200 = 1.9333333333333333481363070*var_195 + 1.5000000000000000000000000*var_194 + 0.6666666666666666296592325*var_19*var_62 + var_199 + 0.6000000000000000888178420*var_182 + 0.3666666666666666407614628*var_133*var_33 + 0.7500000000000000000000000*var_150 + 0.9666666666666666740681535*var_152; + A[4] = var_15*var_200/(var_57*var_57*var_57); + A[82] = A[4]; + A[88] = 0.0000000000000000000000000; + A[142] = A[53]; + const double var_201 = var_17 + 1.3750000000000000000000000*var_3*var_5; + const double var_202 = var_17 + 1.6250000000000000000000000*var_3*var_5; + const double var_203 = -1.5000000000000000000000000*var_3*var_4 + var_6; + const double var_204 = var_5*w[0][17]; + const double var_205 = var_124 + var_204 + -var_4*w[0][3]; + const double var_206 = var_3*var_4*w[0][13] + var_167*var_5 + var_1*var_205; + const double var_207 = var_1*var_65; + const double var_208 = var_3*var_67; + const double var_209 = var_207 + var_208; + const double var_210 = var_18*w[0][5] + var_209*var_4; + const double var_211 = var_18*var_46 + 0.2500000000000000000000000*var_203*w[0][15] + -var_201*w[0][7] + 0.3750000000000000000000000*var_206 + var_202*w[0][8] + 0.1250000000000000000000000*var_210; + const double var_212 = 1.3750000000000000000000000*var_1*var_4 + var_18; + const double var_213 = 1.6250000000000000000000000*var_1*var_4 + var_18; + const double var_214 = w[0][13] + -0.1250000000000000000000000*w[0][15]; + const double var_215 = var_1*w[0][16]; + const double var_216 = var_40 + var_215; + const double var_217 = 1.5000000000000000000000000*var_216 + var_191; + const double var_218 = var_212*w[0][17] + 0.2500000000000000000000000*var_217*var_4 + var_17*var_214 + -var_213*w[0][18]; + const double var_219 = var_10 + var_192; + const double var_220 = var_219*var_23; + const double var_221 = var_23*var_79 + var_220; + const double var_222 = var_176 + var_146; + const double var_223 = var_31 + var_103; + const double var_224 = var_106 + 0.7500000000000000000000000*var_223; + const double var_225 = 0.1250000000000000000000000*var_222 + var_221 + var_211*var_5 + 0.2500000000000000000000000*var_150 + var_218*var_4 + 0.5000000000000000000000000*var_224*var_23; + const double var_226 = var_1*var_4*var_97*w[0][19] + var_3*var_5*var_89*w[0][9]; + const double var_227 = 4.8000000000000007105427358*var_226; + const double var_228 = var_19*var_62; + const double var_229 = var_95*w[0][0] + var_152 + -var_92*w[0][10] + var_133*var_33 + var_228; + const double var_230 = w[0][17] + w[0][15]; + const double var_231 = var_67 + -var_230; + const double var_232 = w[0][7] + w[0][5]; + const double var_233 = var_232 + var_65; + const double var_234 = var_231*var_96 + var_100*w[0][8] + var_102*w[0][18] + 2.0000000000000000000000000*var_56 + var_233*var_94; + const double var_235 = var_91 + -var_139*var_5; + const double var_236 = 0.2000000000000000111022302*var_3*var_4 + var_6; + const double var_237 = -2.0000000000000000000000000*var_3*var_3*var_5 + var_236*var_4; + const double var_238 = 0.2000000000000000111022302*var_234 + 1.2000000000000001776356839*var_154 + var_237*w[0][3] + var_235*w[0][13]; + const double var_239 = 0.1333333333333333314829616*var_229 + 3.0000000000000000000000000*var_238 + 1.3333333333333332593184650*var_198 + var_227; + A[41] = var_15*var_239/(var_57*var_57*var_57); + A[119] = A[41]; + const double var_240 = var_74 + var_42; + const double var_241 = 0.3333333333333333148296163*var_136 + 4.8333333333333330372738601*var_61 + 12.0000000000000000000000000*var_64 + 1.5000000000000000000000000*var_240; + const double var_242 = 0.0666666666666666657414808*var_17*w[0][0]; + const double var_243 = 0.4333333333333333481363070*var_3*var_5*w[0][0] + var_242; + A[47] = 0.0000000000000000000000000; + const double var_244 = var_1*var_1*var_5*var_65 + var_3*var_3*var_4*var_67; + const double var_245 = var_5*w[0][19]; + const double var_246 = var_53 + var_245; + const double var_247 = var_3*var_65 + var_47*var_5; + const double var_248 = -var_1*var_246 + var_247*var_3; + const double var_249 = var_82 + var_27; + const double var_250 = var_1*var_35*var_5*var_5 + var_3*var_36*var_4*var_4; + A[103] = A[14]; + const double var_251 = 0.7500000000000000000000000*var_4*w[0][13] + var_24; + const double var_252 = var_97*w[0][5] + var_1*var_47; + const double var_253 = -1.5000000000000000000000000*var_3*w[0][7] + 7.0000000000000000000000000*var_1*w[0][18]; + const double var_254 = var_253*var_4 + 3.5000000000000000000000000*var_252*var_3 + var_189; + const double var_255 = -var_4*w[0][18]; + const double var_256 = var_114 + var_255; + const double var_257 = var_9*w[0][17] + -var_156*w[0][7] + 0.5000000000000000000000000*var_250 + var_23*var_256; + const double var_258 = var_21*var_3*w[0][14] + -var_1*var_20*w[0][4]; + const double var_259 = 0.5000000000000000000000000*var_258 + var_156*w[0][6] + var_155*var_65 + -var_9*w[0][16] + var_196 + var_157*var_67 + 3.0000000000000000000000000*var_257 + var_173 + var_254*var_4; + const double var_260 = var_1*w[0][19]; + const double var_261 = -var_3*w[0][9] + var_260; + const double var_262 = 2.0000000000000000000000000*var_261*var_33; + const double var_263 = var_33*var_72; + const double var_264 = -var_1*var_1*var_5*w[0][5] + var_51 + var_3*var_3*var_4*w[0][15]; + const double var_265 = 0.5000000000000000000000000*var_263 + var_156*w[0][9] + -var_9*w[0][19] + 0.2500000000000000000000000*var_264; + const double var_266 = var_265 + var_18*var_3*w[0][8] + var_52; + const double var_267 = 3.0000000000000000000000000*var_266 + var_153 + var_110 + var_38 + 2.0000000000000000000000000*var_154 + -var_1*var_4*var_4*w[0][15] + 0.5000000000000000000000000*var_259 + var_262 + var_113*var_18; + const double var_268 = -var_3*w[0][17] + var_128; + const double var_269 = -var_1*w[0][8]; + const double var_270 = 2.2000000000000001776356839*w[0][18] + var_34 + 0.6000000000000000888178420*w[0][15]; + const double var_271 = w[0][3] + -0.6000000000000000888178420*w[0][5]; + const double var_272 = var_270*var_3 + 2.2000000000000001776356839*var_269 + 2.6000000000000000888178420*var_268 + var_1*var_271; + const double var_273 = 0.7000000000000000666133815*var_1*var_44 + -var_3*w[0][3] + var_191 + 1.4000000000000001332267630*var_78; + const double var_274 = var_273*var_3 + 0.7000000000000000666133815*var_1*var_89*w[0][15] + 0.6000000000000000888178420*var_23*w[0][8] + 0.5000000000000000000000000*var_272*var_4 + 0.3000000000000000444089210*var_1*var_5*w[0][17] + var_18*w[0][7] + 0.2000000000000000111022302*var_161; + const double var_275 = var_23*var_82 + var_274*var_5 + var_12*var_17; + const double var_276 = -var_155*w[0][0] + var_157*w[0][10]; + const double var_277 = var_170 + var_228; + const double var_278 = 0.0666666666666666657414808*var_277; + const double var_279 = 1.9333333333333333481363070*var_276 + var_278 + 0.7500000000000000000000000*var_22 + 0.9666666666666666740681535*var_138 + 0.6000000000000000888178420*var_267 + 0.3666666666666666407614628*var_132*var_23 + 0.6666666666666666296592325*var_19*var_61 + 1.5000000000000000000000000*var_275; + A[5] = var_15*var_279/(var_57*var_57*var_57); + A[138] = A[5]; + const double var_280 = var_25 + 0.5000000000000000000000000*var_79; + const double var_281 = var_137 + var_133; + const double var_282 = 0.4500000000000000111022302*var_31 + 0.6000000000000000888178420*var_280 + 0.1500000000000000222044605*var_27 + 0.4833333333333333370340767*var_281 + 0.3000000000000000444089210*var_82 + 0.7500000000000000000000000*var_175; + const double var_283 = var_1*w[0][5]; + const double var_284 = var_125 + -var_3*w[0][14] + var_283; + const double var_285 = var_284*var_5 + var_3*var_4*w[0][4] + var_1*var_255; + const double var_286 = var_17*w[0][17] + var_3*var_49; + const double var_287 = var_17*var_66 + 0.2500000000000000000000000*var_203*w[0][7] + -var_212*w[0][15] + var_213*w[0][16] + 0.3750000000000000000000000*var_285 + 0.1250000000000000000000000*var_286; + const double var_288 = w[0][4] + -0.1250000000000000000000000*w[0][7]; + const double var_289 = var_5*w[0][8]; + const double var_290 = var_289 + var_112; + const double var_291 = var_10 + 1.5000000000000000000000000*var_290; + const double var_292 = var_18*var_288 + var_201*w[0][5] + 0.2500000000000000000000000*var_291*var_3 + -var_202*w[0][6]; + const double var_293 = var_191 + var_11; + const double var_294 = var_293*var_33; + const double var_295 = var_33*var_77 + var_294; + const double var_296 = var_38 + var_145; + const double var_297 = var_39 + var_72; + const double var_298 = var_109 + 0.7500000000000000000000000*var_297; + const double var_299 = 0.1250000000000000000000000*var_296 + 0.2500000000000000000000000*var_22 + var_295 + var_1*var_287 + var_292*var_3 + 0.5000000000000000000000000*var_298*var_33; + const double var_300 = var_9*w[0][10] + -var_156*w[0][0]; + const double var_301 = 0.2416666666666666685170384*var_149*var_33 + 0.5000000000000000000000000*var_19*var_282 + 0.6000000000000000888178420*var_299 + 0.0583333333333333342585192*var_198 + 0.3750000000000000000000000*var_244 + 0.4833333333333333370340767*var_300; + A[2] = var_15*var_301/(var_57*var_57*var_57); + A[102] = A[2]; + A[111] = 0.0000000000000000000000000; + const double var_302 = var_89*w[0][0] + var_97*w[0][10]; + const double var_303 = var_215 + var_39 + var_133 + var_302 + var_293 + var_168; + const double var_304 = var_114 + var_103; + const double var_305 = 4.0000000000000000000000000*var_1*var_4*w[0][16] + 3.0000000000000000000000000*var_209*var_5; + const double var_306 = -var_4*w[0][9] + var_245; + const double var_307 = var_177 + 2.0000000000000000000000000*var_180 + var_306*var_8; + const double var_308 = var_305*var_4 + 3.0000000000000000000000000*var_176 + var_172 + var_263 + var_19*var_304 + var_150 + var_1*var_20*w[0][9] + -var_21*var_3*w[0][19] + 2.0000000000000000000000000*var_307 + var_262; + const double var_309 = var_44 + var_230; + const double var_310 = -var_232 + var_47; + const double var_311 = var_101*w[0][6] + var_309*var_92 + var_99*w[0][16] + 2.0000000000000000000000000*var_308 + var_310*var_95; + const double var_312 = -var_1*var_139 + var_93; + const double var_313 = -2.0000000000000000000000000*var_1*var_4*var_4 + var_236*var_3; + const double var_314 = 1.2000000000000001776356839*var_153 + var_313*w[0][14] + 0.2000000000000000111022302*var_311 + var_312*w[0][4]; + A[67] = 0.0000000000000000000000000; + A[99] = 0.0000000000000000000000000; + const double var_315 = -var_1*var_4*var_4*w[0][16] + var_3*var_5*var_5*w[0][6]; + const double var_316 = var_283 + var_204; + const double var_317 = 1.4000000000000001332267630*var_3*var_5 + var_17; + A[43] = 0.0000000000000000000000000; + const double var_318 = w[0][8] + w[0][7]; + const double var_319 = 0.7500000000000000000000000*var_3*w[0][4] + var_260; + const double var_320 = 0.7000000000000000666133815*var_1*var_5*w[0][16] + var_236*w[0][19]; + const double var_321 = 1.8000000000000000444089210*var_1*var_319*var_4 + 0.3000000000000000444089210*var_156*var_318 + 1.5000000000000000000000000*var_3*var_320; + const double var_322 = w[0][18] + w[0][17]; + const double var_323 = 0.7500000000000000000000000*var_1*w[0][14] + var_105; + const double var_324 = 0.1000000000000000055511151*var_322*var_9 + 0.6000000000000000888178420*var_3*var_323*var_5 + 0.5000000000000000000000000*var_1*var_140; + const double var_325 = var_74 + var_85; + const double var_326 = var_167 + var_215; + const double var_327 = 0.9000000000000000222044605*var_325 + 0.3000000000000000444089210*var_42 + 0.6000000000000000888178420*var_261 + 0.9666666666666666740681535*var_133 + 0.3666666666666666407614628*var_151 + 1.5000000000000000000000000*var_326; + const double var_328 = -var_3*var_3*var_5*w[0][5]; + const double var_329 = -0.3666666666666666407614628*var_3*var_4*w[0][10] + var_243 + 0.1500000000000000222044605*var_20*w[0][15] + 3.0000000000000000000000000*var_18*w[0][6]; + const double var_330 = 6.5000000000000000000000000*var_1*var_4 + var_18; + const double var_331 = 0.0666666666666666657414808*var_330*w[0][10]; + const double var_332 = var_331 + 3.0000000000000000000000000*var_17*w[0][16] + 0.1500000000000000222044605*var_21*w[0][5]; + const double var_333 = 0.6000000000000000888178420*var_17*w[0][15] + 0.3666666666666666407614628*var_1*var_5*w[0][0] + -var_332; + const double var_334 = var_114 + var_27; + const double var_335 = 12.0000000000000000000000000*var_68 + 1.5000000000000000000000000*var_334 + 0.3333333333333333148296163*var_142 + 4.8333333333333330372738601*var_62; + const double var_336 = var_156*w[0][3] + 11.0000000000000000000000000*var_153 + -var_9*w[0][13]; + const double var_337 = var_199 + 3.0000000000000000000000000*var_324 + -var_321 + 0.2000000000000000111022302*var_19*var_335 + 0.6000000000000000888178420*var_328 + var_327*var_33 + 1.9500000000000001776356839*var_166 + var_3*var_329 + var_1*var_333 + 0.3000000000000000444089210*var_336; + const double var_338 = 1.4000000000000001332267630*var_1*var_4 + var_18; + const double var_339 = var_338*w[0][14] + var_236*w[0][6]; + A[125] = 0.0000000000000000000000000; + const double var_340 = var_23 + var_33; + const double var_341 = var_220 + var_294; + const double var_342 = var_113 + var_40; + const double var_343 = -var_4*w[0][16] + 3.0000000000000000000000000*var_342 + var_1*w[0][18]; + const double var_344 = var_41 + var_112; + const double var_345 = var_5*w[0][6] + -var_3*w[0][8] + 3.0000000000000000000000000*var_344; + const double var_346 = var_83 + var_81; + const double var_347 = w[0][3] + w[0][4]; + const double var_348 = 5.8000000000000007105427358*var_58*w[0][0] + 0.6000000000000000888178420*var_347*var_89; + const double var_349 = w[0][13] + w[0][14]; + const double var_350 = 5.8000000000000007105427358*var_59*w[0][10] + 0.6000000000000000888178420*var_349*var_97; + const double var_351 = var_167 + var_289; + const double var_352 = var_80 + var_84; + const double var_353 = var_255 + var_215; + const double var_354 = 0.3750000000000000000000000*var_353 + var_352 + var_97*w[0][19]; + const double var_355 = 0.6000000000000000888178420*var_351 + 0.2500000000000000000000000*var_348 + 0.4500000000000000111022302*var_343 + 1.2000000000000001776356839*var_89*w[0][9] + 0.1500000000000000222044605*var_345 + 1.1250000000000000000000000*var_346 + 0.3750000000000000000000000*var_350 + 1.8000000000000000444089210*var_354; + const double var_356 = var_4*w[0][9] + var_3*w[0][19]; + const double var_357 = var_3*w[0][10] + var_4*w[0][0]; + const double var_358 = w[0][6] + 2.2500000000000000000000000*w[0][7]; + const double var_359 = w[0][18] + 2.2500000000000000000000000*w[0][15]; + const double var_360 = var_3*var_359 + -3.0000000000000000000000000*var_126 + var_358*var_4; + const double var_361 = 3.6250000000000000000000000*var_357 + -3.0000000000000000000000000*var_356 + 1.5000000000000000000000000*var_360; + const double var_362 = var_1*var_355 + 0.2000000000000000111022302*var_3*var_361; + const double var_363 = 0.3750000000000000000000000*var_351 + var_89*w[0][9] + var_346 + 0.2500000000000000000000000*var_345; + const double var_364 = 0.1500000000000000222044605*var_343 + 0.6000000000000000888178420*var_353 + 0.3750000000000000000000000*var_348 + 1.1250000000000000000000000*var_352 + 1.2000000000000001776356839*var_97*w[0][19] + 0.2500000000000000000000000*var_350 + 1.8000000000000000444089210*var_363; + const double var_365 = var_1*w[0][0] + var_5*w[0][10]; + const double var_366 = 3.0000000000000000000000000*var_129 + var_184 + var_269; + const double var_367 = 3.0000000000000000000000000*var_246 + -3.3750000000000000000000000*var_316 + -3.6250000000000000000000000*var_365 + 1.5000000000000000000000000*var_366; + const double var_368 = 0.2000000000000000111022302*var_1*var_367 + var_3*var_364; + const double var_369 = var_134*var_19; + const double var_370 = var_3*var_4*var_4*var_47 + var_1*var_44*var_5*var_5; + const double var_371 = var_33*var_64; + const double var_372 = var_23*var_68; + const double var_373 = var_371 + var_372; + const double var_374 = var_104 + var_373 + var_370 + var_147 + var_244; + const double var_375 = var_261 + 0.5000000000000000000000000*var_77; + const double var_376 = var_32 + var_263; + const double var_377 = 1.1250000000000000000000000*var_376 + var_33*var_375 + 0.1250000000000000000000000*var_374 + var_23*var_280; + const double var_378 = 0.2500000000000000000000000*var_369 + 0.1250000000000000000000000*var_340*var_63 + 0.9000000000000000222044605*var_341 + var_362*var_4 + var_368*var_5 + 0.7250000000000000888178420*var_144 + 0.6000000000000000888178420*var_377; + const double var_379 = var_338*w[0][13] + var_139*w[0][8]; + const double var_380 = 0.6666666666666666296592325*var_5*var_5*w[0][10] + 0.7333333333333332815229255*var_4*var_4*w[0][10] + 3.0000000000000000000000000*var_379; + const double var_381 = var_340*var_61 + var_143; + const double var_382 = var_340*var_62 + var_141; + const double var_383 = var_236*w[0][18] + var_317*w[0][3]; + const double var_384 = 0.7333333333333332815229255*var_5*var_5*w[0][0] + 0.6666666666666666296592325*var_4*var_4*w[0][0] + 3.0000000000000000000000000*var_383; + const double var_385 = 0.3333333333333333148296163*w[0][10] + 6.0000000000000000000000000*w[0][19]; + const double var_386 = 0.3333333333333333148296163*w[0][0] + 6.0000000000000000000000000*w[0][9]; + const double var_387 = 3.0000000000000000000000000*var_82 + 0.3333333333333333148296163*var_133 + 6.0000000000000000000000000*var_72 + 6.3333333333333330372738601*var_132 + 12.0000000000000000000000000*var_25; + const double var_388 = var_221 + var_370 + var_145; + const double var_389 = var_1*var_1*var_4*w[0][18] + -var_3*var_3*var_5*w[0][8]; + const double var_390 = var_96*w[0][15] + 3.0000000000000000000000000*var_371 + 6.0000000000000000000000000*var_389 + var_223*var_23 + -var_94*w[0][5]; + const double var_391 = -0.3333333333333333148296163*var_18*var_4*w[0][10] + var_19*var_387 + -var_386*var_95 + var_385*var_92 + 3.0000000000000000000000000*var_390 + 6.0000000000000000000000000*var_388; + const double var_392 = 0.6000000000000000888178420*var_1*var_4 + var_18; + const double var_393 = 0.6000000000000000888178420*var_3*var_5 + var_17; + const double var_394 = var_392*var_47*var_5 + var_393*var_4*var_44; + const double var_395 = 0.2000000000000000111022302*var_391 + 0.6666666666666666296592325*var_381 + 0.0666666666666666657414808*var_382 + var_3*var_384 + -var_1*var_380 + var_242*var_5 + 3.0000000000000000000000000*var_394; + const double var_396 = 1.5000000000000000000000000*var_3*var_5 + var_17; + A[75] = 0.0000000000000000000000000; + A[54] = 0.0000000000000000000000000; + A[22] = 0.0000000000000000000000000; + const double var_397 = var_45 + var_207; + const double var_398 = var_208 + var_48; + const double var_399 = var_139*var_397 + var_236*var_398; + A[66] = 0.0000000000000000000000000; + const double var_400 = var_243 + 0.1500000000000000222044605*var_21*w[0][17] + 3.0000000000000000000000000*var_18*w[0][8]; + const double var_401 = 0.6000000000000000888178420*var_18*w[0][7] + -var_400 + 0.3666666666666666407614628*var_1*var_5*w[0][10]; + const double var_402 = var_3*w[0][3] + -var_5*w[0][4]; + const double var_403 = var_70 + var_30; + const double var_404 = 0.2500000000000000000000000*var_402 + 0.7000000000000000666133815*var_58*w[0][9] + 0.6000000000000000888178420*var_403; + const double var_405 = var_4*w[0][14] + -var_1*w[0][13]; + const double var_406 = var_29 + var_71; + const double var_407 = 0.2500000000000000000000000*var_405 + 0.6000000000000000888178420*var_406 + 0.7000000000000000666133815*var_59*w[0][19]; + const double var_408 = -var_9*w[0][15] + var_156*w[0][5] + var_116; + const double var_409 = -var_155*w[0][7] + var_157*w[0][17] + var_115; + const double var_410 = var_4*var_44 + var_1*var_67; + const double var_411 = var_1*var_410 + var_3*var_356; + const double var_412 = var_409 + 0.5000000000000000000000000*var_148 + var_4*var_411 + var_408 + var_248*var_5; + const double var_413 = var_33*var_61; + const double var_414 = var_23*var_62; + const double var_415 = var_413 + var_414; + const double var_416 = var_104 + 3.0000000000000000000000000*var_412 + var_415; + const double var_417 = var_155*w[0][6] + var_9*w[0][18] + -var_157*w[0][16] + -var_156*w[0][8] + 0.5000000000000000000000000*var_399 + 0.2000000000000000111022302*var_416; + const double var_418 = var_1*var_4*var_405 + var_3*var_402*var_5; + const double var_419 = var_418 + var_111; + const double var_420 = var_1*var_4*var_404 + var_18*var_58*w[0][9] + 0.1000000000000000055511151*var_134*var_19 + var_17*var_59*w[0][19] + 0.5000000000000000000000000*var_417 + 0.2000000000000000111022302*var_373 + 0.4000000000000000222044605*var_419 + var_3*var_407*var_5; + A[3] = 3.0000000000000000000000000*var_15*var_420/(var_57*var_57*var_57); + const double var_421 = var_302 + var_62; + const double var_422 = var_31 + var_68; + const double var_423 = 0.1250000000000000000000000*var_421 + 0.3000000000000000444089210*var_219 + 0.6000000000000000888178420*var_109 + 0.2250000000000000055511151*var_240 + 0.7250000000000000888178420*var_61 + 0.6750000000000000444089210*var_103 + 0.0750000000000000111022302*var_422 + 1.5750000000000001776356839*var_64 + 0.9000000000000000222044605*var_79; + A[13] = var_15*var_23*var_423/(var_57*var_57*var_57); + A[91] = A[13]; + A[63] = A[41]; + const double var_424 = 1.5000000000000000000000000*var_39 + 0.5000000000000000000000000*var_132 + 2.0000000000000000000000000*var_106 + var_37; + const double var_425 = -0.5000000000000000000000000*w[0][6] + 0.6000000000000000888178420*w[0][4]; + const double var_426 = -0.6000000000000000888178420*w[0][14] + 0.5000000000000000000000000*w[0][16]; + const double var_427 = var_1*w[0][3] + var_3*w[0][13]; + const double var_428 = 1.5000000000000000000000000*var_244 + var_408 + var_19*var_223 + 0.5000000000000000000000000*var_13*var_427; + const double var_429 = var_18*var_3*var_425 + 0.8000000000000000444089210*var_175*var_19 + var_1*var_17*var_426 + 0.2000000000000000111022302*var_33*var_424 + 0.1000000000000000055511151*var_428 + -var_324; + A[124] = 0.0000000000000000000000000; + A[59] = 0.0000000000000000000000000; + const double var_430 = var_139*w[0][16] + var_317*w[0][4]; + const double var_431 = 0.7333333333333332815229255*var_3*var_3*w[0][0] + 0.6666666666666666296592325*var_1*var_1*w[0][0] + 3.0000000000000000000000000*var_430; + const double var_432 = var_289 + var_132 + var_103 + var_302 + var_219 + var_256; + const double var_433 = 1.5000000000000000000000000*var_1*var_4 + var_18; + const double var_434 = var_163*var_9 + var_1*var_1*var_4*w[0][15] + var_328 + var_156*var_165 + var_172; + const double var_435 = var_128 + var_125; + const double var_436 = -var_1*var_20*w[0][8] + var_21*var_3*w[0][18] + var_160*var_435; + const double var_437 = var_19*var_432 + -var_1*var_396*w[0][13] + var_3*var_433*w[0][3] + 0.5000000000000000000000000*var_436 + 3.0000000000000000000000000*var_434 + var_413; + const double var_438 = var_302 + var_61; + const double var_439 = var_64 + var_72; + const double var_440 = 0.3000000000000000444089210*var_293 + 0.6750000000000000444089210*var_39 + 0.1250000000000000000000000*var_438 + 0.7250000000000000888178420*var_62 + 1.5750000000000001776356839*var_68 + 0.9000000000000000222044605*var_77 + 0.6000000000000000888178420*var_106 + 0.2250000000000000055511151*var_334 + 0.0750000000000000111022302*var_439; + A[26] = var_15*var_33*var_440/(var_57*var_57*var_57); + const double var_441 = var_124 + var_127; + const double var_442 = -var_20*var_5*w[0][16] + var_21*var_4*w[0][6] + var_160*var_441; + A[69] = 0.0000000000000000000000000; + A[9] = 0.0000000000000000000000000; + A[96] = 0.0000000000000000000000000; + const double var_443 = w[0][6] + w[0][5]; + const double var_444 = 0.7500000000000000000000000*var_5*w[0][3] + var_108; + const double var_445 = var_139*w[0][19] + 0.7000000000000000666133815*var_3*var_4*w[0][18]; + const double var_446 = 0.6000000000000000888178420*var_1*var_4*var_444 + 0.1000000000000000055511151*var_155*var_443 + 0.5000000000000000000000000*var_445*var_5; + const double var_447 = 2.0000000000000000000000000*var_109 + 0.5000000000000000000000000*var_133 + 1.5000000000000000000000000*var_103 + var_175; + const double var_448 = -0.5000000000000000000000000*w[0][18] + 0.6000000000000000888178420*w[0][13]; + const double var_449 = 0.5000000000000000000000000*w[0][8] + -0.6000000000000000888178420*w[0][3]; + const double var_450 = var_409 + var_19*var_297 + 1.5000000000000000000000000*var_370 + 0.5000000000000000000000000*var_13*var_16; + const double var_451 = 0.2000000000000000111022302*var_23*var_447 + 0.8000000000000000444089210*var_19*var_37 + var_17*var_4*var_448 + var_18*var_449*var_5 + -var_446 + 0.1000000000000000055511151*var_450; + const double var_452 = var_389 + var_371 + var_109*var_19 + var_262 + 0.5000000000000000000000000*var_437 + var_265; + const double var_453 = 0.2000000000000000111022302*var_452 + 0.2500000000000000000000000*var_1*var_183*var_3; + A[29] = 3.0000000000000000000000000*var_15*var_453/(var_57*var_57*var_57); + A[62] = A[29]; + A[101] = 0.0000000000000000000000000; + A[122] = 0.0000000000000000000000000; + A[0] = var_15*var_378/(var_57*var_57*var_57); + A[86] = 0.0000000000000000000000000; + const double var_454 = 14.5000000000000000000000000*var_133 + var_60 + var_132; + const double var_455 = 0.0666666666666666657414808*var_19*var_454 + var_321 + 3.0000000000000000000000000*var_429; + A[27] = var_15*var_455/(var_57*var_57*var_57); + A[84] = 0.0000000000000000000000000; + A[28] = var_15*var_337/(var_57*var_57*var_57); + A[106] = A[28]; + const double var_456 = var_155*w[0][0] + -var_157*w[0][10]; + const double var_457 = 0.6666666666666666296592325*var_3*var_3*w[0][10] + 0.7333333333333332815229255*var_1*var_1*w[0][10] + 3.0000000000000000000000000*var_339; + const double var_458 = var_95*w[0][7] + var_297*var_33 + 3.0000000000000000000000000*var_23*var_68 + -var_92*w[0][17] + var_19*var_85; + const double var_459 = 2.0000000000000000000000000*var_261 + var_31; + const double var_460 = var_295 + var_146 + var_244 + 3.0000000000000000000000000*var_315 + var_19*var_459; + const double var_461 = var_1*var_393*var_67 + 0.4000000000000000222044605*var_460 + var_3*var_392*var_65; + const double var_462 = 19.0000000000000000000000000*var_133 + var_132; + const double var_463 = var_1*var_18*w[0][10] + -var_17*var_3*w[0][0] + var_381 + var_19*var_462; + const double var_464 = 0.3333333333333333148296163*var_463 + var_386*var_94 + -var_385*var_96; + const double var_465 = 3.0000000000000000000000000*var_461 + -var_431*var_5 + var_4*var_457 + 0.6000000000000000888178420*var_458 + 0.6666666666666666296592325*var_382 + 0.2000000000000000111022302*var_464; + A[52] = 2.0000000000000000000000000*var_15*var_465/(var_57*var_57*var_57); + A[6] = 0.0000000000000000000000000; + const double var_466 = w[0][15] + w[0][16]; + const double var_467 = 0.7000000000000000666133815*var_1*var_5*w[0][8] + var_236*w[0][9]; + const double var_468 = 0.3000000000000000444089210*var_157*var_466 + 1.8000000000000000444089210*var_251*var_3*var_5 + 1.5000000000000000000000000*var_4*var_467; + const double var_469 = var_133 + var_60 + 14.5000000000000000000000000*var_132; + const double var_470 = 0.0666666666666666657414808*var_19*var_469 + var_468 + 3.0000000000000000000000000*var_451; + A[100] = 0.0000000000000000000000000; + A[131] = A[53]; + A[65] = 2.0000000000000000000000000*var_15*var_395/(var_57*var_57*var_57); + A[143] = A[65]; + const double var_471 = var_19*var_75 + var_147; + const double var_472 = -var_96*w[0][16] + -var_95*w[0][8] + var_17*var_402 + var_92*w[0][18] + 3.0000000000000000000000000*var_418 + var_94*w[0][6] + var_18*var_405 + 2.0000000000000000000000000*var_471; + A[21] = 0.0000000000000000000000000; + A[7] = 0.0000000000000000000000000; + A[20] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[135] = 0.0000000000000000000000000; + A[24] = A[2]; + const double var_473 = -var_94*w[0][0] + var_138 + var_96*w[0][10] + var_132*var_23 + var_197; + const double var_474 = 0.1333333333333333314829616*var_473 + 1.3333333333333332593184650*var_277 + 3.0000000000000000000000000*var_314 + var_227; + A[40] = var_15*var_474/(var_57*var_57*var_57); + A[118] = A[40]; + A[104] = A[26]; + const double var_475 = -var_1*var_4*var_4*w[0][17]; + const double var_476 = var_142 + var_61; + A[15] = var_15*var_470/(var_57*var_57*var_57); + const double var_477 = var_475 + var_157*var_35 + var_155*var_36 + var_3*var_5*var_5*w[0][7] + var_28; + const double var_478 = 3.0000000000000000000000000*var_477 + 0.5000000000000000000000000*var_442 + var_396*var_4*w[0][14] + -var_433*var_5*w[0][4] + var_19*var_303 + var_414; + const double var_479 = 0.5000000000000000000000000*var_478 + var_315 + var_26 + var_372 + var_106*var_19 + var_179; + const double var_480 = 0.2000000000000000111022302*var_479 + 0.2500000000000000000000000*var_268*var_4*var_5; + A[16] = 3.0000000000000000000000000*var_15*var_480/(var_57*var_57*var_57); + A[71] = 0.0000000000000000000000000; + A[10] = 0.0000000000000000000000000; + A[33] = 0.0000000000000000000000000; + A[58] = 0.0000000000000000000000000; + A[46] = 0.0000000000000000000000000; + A[116] = A[27]; + const double var_481 = var_151 + var_132; + const double var_482 = 0.6000000000000000888178420*var_375 + 0.1500000000000000222044605*var_74 + 0.7500000000000000000000000*var_37 + 0.4500000000000000111022302*var_72 + 0.3000000000000000444089210*var_85 + 0.4833333333333333370340767*var_481; + const double var_483 = 0.6000000000000000888178420*var_225 + 0.3750000000000000000000000*var_370 + 0.4833333333333333370340767*var_456 + 0.5000000000000000000000000*var_19*var_482 + 0.0583333333333333342585192*var_277 + 0.2416666666666666685170384*var_23*var_476; + A[1] = var_15*var_483/(var_57*var_57*var_57); + A[12] = A[1]; + A[72] = 0.0000000000000000000000000; + A[70] = 0.0000000000000000000000000; + A[126] = A[4]; + const double var_484 = var_289 + var_255; + const double var_485 = 1.5000000000000000000000000*var_484 + 0.6000000000000000888178420*var_25 + 0.9666666666666666740681535*var_132 + 0.3666666666666666407614628*var_137 + 0.3000000000000000444089210*var_114 + 0.9000000000000000222044605*var_249; + const double var_486 = 0.1500000000000000222044605*var_20*w[0][7] + var_331 + 3.0000000000000000000000000*var_17*w[0][18] + -0.3666666666666666407614628*var_3*var_4*w[0][0]; + const double var_487 = 11.0000000000000000000000000*var_154 + var_157*w[0][14] + -var_155*w[0][4]; + const double var_488 = var_278 + 3.0000000000000000000000000*var_446 + var_401*var_5 + -var_468 + 1.9500000000000001776356839*var_250 + var_4*var_486 + 0.6000000000000000888178420*var_475 + var_23*var_485 + 0.2000000000000000111022302*var_19*var_241 + 0.3000000000000000444089210*var_487; + A[17] = var_15*var_488/(var_57*var_57*var_57); + A[139] = A[17]; + A[83] = A[5]; + A[127] = A[16]; + A[80] = A[2]; + A[95] = A[17]; + A[108] = 0.0000000000000000000000000; + A[36] = A[3]; + A[115] = A[15]; + A[35] = 0.0000000000000000000000000; + A[11] = 0.0000000000000000000000000; + A[23] = 0.0000000000000000000000000; + A[64] = A[53]; + A[133] = 0.0000000000000000000000000; + A[76] = 0.0000000000000000000000000; + A[49] = A[16]; + A[19] = 0.0000000000000000000000000; + A[107] = A[29]; + A[85] = 0.0000000000000000000000000; + A[110] = 0.0000000000000000000000000; + A[136] = 0.0000000000000000000000000; + A[79] = A[1]; + A[74] = 0.0000000000000000000000000; + A[61] = A[17]; + A[78] = A[0]; + A[140] = A[29]; + A[81] = A[3]; + A[87] = 0.0000000000000000000000000; + A[37] = A[15]; + A[44] = 0.0000000000000000000000000; + A[137] = 0.0000000000000000000000000; + A[57] = 0.0000000000000000000000000; + A[8] = 0.0000000000000000000000000; + A[51] = A[40]; + A[31] = 0.0000000000000000000000000; + A[34] = 0.0000000000000000000000000; + A[60] = A[5]; + A[90] = A[1]; + A[55] = 0.0000000000000000000000000; + A[77] = 0.0000000000000000000000000; + A[132] = 0.0000000000000000000000000; + A[113] = 0.0000000000000000000000000; + const double var_489 = var_149*var_33 + var_23*var_476 + var_369; + A[109] = 0.0000000000000000000000000; + A[25] = A[14]; + A[105] = A[27]; + A[45] = 0.0000000000000000000000000; + A[56] = 0.0000000000000000000000000; + A[32] = 0.0000000000000000000000000; + A[129] = A[40]; + A[130] = A[52]; + A[94] = A[16]; + A[73] = 0.0000000000000000000000000; + A[50] = A[28]; + A[42] = 0.0000000000000000000000000; + A[38] = A[27]; + A[112] = 0.0000000000000000000000000; + A[128] = A[28]; + const double var_490 = var_386*var_98 + var_385*var_90 + 3.0000000000000000000000000*var_472 + 9.0000000000000000000000000*var_373; + const double var_491 = 0.0666666666666666657414808*var_489 + 0.2000000000000000111022302*var_490 + 0.6666666666666666296592325*var_415; + A[39] = 2.0000000000000000000000000*var_15*var_491/(var_57*var_57*var_57); + A[68] = 0.0000000000000000000000000; + A[114] = A[3]; + A[93] = A[15]; + A[98] = 0.0000000000000000000000000; + A[30] = 0.0000000000000000000000000; + A[141] = A[41]; + A[97] = 0.0000000000000000000000000; + A[117] = A[39]; + A[123] = 0.0000000000000000000000000; + A[120] = 0.0000000000000000000000000; + A[48] = A[4]; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q2_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q2_quadrature.h new file mode 100644 index 0000000..f8488c0 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q2_quadrature.h @@ -0,0 +1,14345 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P3_Q2_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P3_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q2_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q2_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q2_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q2_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q2_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q2_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q2_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q2_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q2_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p3_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W6[6] = {0.054975871827661, 0.054975871827661, 0.054975871827661, 0.111690794839005, 0.111690794839005, 0.111690794839005}; + // Quadrature points on the UFC reference element: (0.816847572980459, 0.091576213509771), (0.091576213509771, 0.816847572980459), (0.091576213509771, 0.091576213509771), (0.10810301816807, 0.445948490915965), (0.445948490915965, 0.10810301816807), (0.445948490915965, 0.445948490915965) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[6][5] = \ + {{0.63369514596092, -0.633695145960916, 3.26739029192183, 0.0, -3.26739029192184}, + {0.63369514596092, 2.26739029192184, 0.366304854039083, -2.90108543788276, -0.366304854039083}, + {-2.26739029192183, -0.633695145960916, 0.366304854039083, 2.90108543788275, -0.366304854039084}, + {-0.78379396366386, 0.78379396366386, 0.43241207267228, 0.0, -0.43241207267228}, + {-0.78379396366386, -0.567587927327719, 1.78379396366386, 1.35138189099158, -1.78379396366386}, + {0.56758792732772, 0.78379396366386, 1.78379396366386, -1.35138189099158, -1.78379396366386}}; + + // Array of non-zero columns + static const unsigned int nzc4[5] = {6, 8, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc1[5] = {0, 2, 3, 4, 5}; + + static const double FE0_C0_D10[6][5] = \ + {{0.633695145960919, 2.26739029192183, 0.366304854039083, -0.366304854039083, -2.90108543788275}, + {0.633695145960921, -0.633695145960916, 3.26739029192183, -3.26739029192183, 0.0}, + {-2.26739029192183, -0.633695145960916, 0.366304854039083, -0.366304854039083, 2.90108543788275}, + {-0.78379396366386, -0.56758792732772, 1.78379396366386, -1.78379396366386, 1.35138189099158}, + {-0.78379396366386, 0.78379396366386, 0.432412072672279, -0.432412072672279, 0.0}, + {0.56758792732772, 0.78379396366386, 1.78379396366386, -1.78379396366386, -1.35138189099158}}; + + // Array of non-zero columns + static const unsigned int nzc5[5] = {6, 7, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc2[5] = {0, 1, 3, 4, 5}; + + static const double FE1_C0_D01[6][9] = \ + {{-0.289027817302694, 0.289027817302687, 5.33192534762283, -1.65611126921075, -0.113213738890623, 0.113213738890629, 1.65611126921077, -5.33192534762283, -2.06501482580279e-14}, + {-0.289027817302695, 2.65611126921076, -0.298879221903342, 1.60760984840734, 1.35723204730744, -3.72431549921551, 0.185665483012719, 0.298879221903341, -1.79327533142006}, + {-2.65611126921075, 0.289027817302687, -0.298879221903341, -0.185665483012718, 3.72431549921547, -1.35723204730741, -1.60760984840734, 0.298879221903342, 1.79327533142006}, + {0.328790654815627, -0.328790654815627, -0.328699037506192, 0.815162619262507, -2.68474576342806, 2.68474576342806, -0.815162619262507, 0.328699037506193, 0.0}, + {0.328790654815627, 0.184837380737491, 0.677977554306217, -0.70514200810302, -0.137185064956293, -0.376442970596826, -3.36272331773427, -0.677977554306216, 4.06786532583729}, + {-0.184837380737492, -0.328790654815627, 0.677977554306215, 3.36272331773427, 0.376442970596826, 0.137185064956294, 0.70514200810302, -0.677977554306216, -4.06786532583729}}; + + // Array of non-zero columns + static const unsigned int nzc10[9] = {10, 12, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc7[9] = {0, 2, 3, 4, 5, 6, 7, 8, 9}; + + static const double FE1_C0_D10[6][9] = \ + {{-0.289027817302695, 2.65611126921076, 1.60760984840734, -0.298879221903343, 0.185665483012717, 0.298879221903344, 1.35723204730743, -3.7243154992155, -1.79327533142006}, + {-0.289027817302695, 0.289027817302689, -1.65611126921075, 5.33192534762283, 1.65611126921078, -5.33192534762283, -0.113213738890622, 0.113213738890627, -2.16402533218167e-14}, + {-2.65611126921075, 0.289027817302688, -0.185665483012718, -0.298879221903344, -1.60760984840734, 0.298879221903344, 3.72431549921547, -1.35723204730741, 1.79327533142006}, + {0.328790654815627, 0.184837380737492, -0.70514200810302, 0.677977554306215, -3.36272331773427, -0.677977554306215, -0.137185064956292, -0.376442970596827, 4.06786532583729}, + {0.328790654815627, -0.328790654815627, 0.815162619262508, -0.328699037506193, -0.815162619262508, 0.328699037506194, -2.68474576342806, 2.68474576342806, 0.0}, + {-0.184837380737492, -0.328790654815627, 3.36272331773427, 0.677977554306218, 0.705142008103019, -0.677977554306217, 0.376442970596827, 0.137185064956292, -4.06786532583729}}; + + // Array of non-zero columns + static const unsigned int nzc11[9] = {10, 11, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc8[9] = {0, 1, 3, 4, 5, 6, 7, 8, 9}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 144; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 60. + double G[12]; + G[0] = K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 4176 + for (unsigned int ip = 0; ip < 6; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 72 + for (unsigned int r = 0; r < 9; r++) + { + F0 += FE1_C0_D10[ip][r]*w[0][nzc8[r]]; + F1 += FE1_C0_D01[ip][r]*w[0][nzc7[r]]; + F2 += FE1_C0_D10[ip][r]*w[0][nzc11[r]]; + F3 += FE1_C0_D01[ip][r]*w[0][nzc10[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 24 + double I[3]; + // Number of operations: 8 + I[0] = W6[ip]*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 8 + I[1] = W6[ip]*(F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 8 + I[2] = W6[ip]*(F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 600 + for (unsigned int j = 0; j < 5; j++) + { + for (unsigned int k = 0; k < 5; k++) + { + // Number of operations to compute entry: 3 + A[nzc1[j]*12 + nzc1[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc1[j]*12 + nzc2[k]] += FE0_C0_D01[ip][j]*FE0_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*12 + nzc1[k]] += FE0_C0_D01[ip][k]*FE0_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*12 + nzc2[k]] += FE0_C0_D10[ip][j]*FE0_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc4[j]*12 + nzc4[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc4[j]*12 + nzc5[k]] += FE0_C0_D01[ip][j]*FE0_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*12 + nzc4[k]] += FE0_C0_D01[ip][k]*FE0_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*12 + nzc5[k]] += FE0_C0_D10[ip][j]*FE0_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p3_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q2_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q2_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q2_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q2_tensor.h new file mode 100644 index 0000000..3a05431 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q2_tensor.h @@ -0,0 +1,14494 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P3_Q2_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P3_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q2_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q2_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q2_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q2_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q2_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q2_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q2_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q2_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q2_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p3_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 432 + // Number of operations (multiply-add pairs) for tensor contraction: 1941 + // Total number of operations (multiply-add pairs): 2384 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0 = det*(w[0][3]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1 = det*(w[0][3]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0 = det*(w[0][4]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1 = det*(w[0][4]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0 = det*(w[0][5]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1 = det*(w[0][5]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_0_0 = det*(w[0][6]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_0_1 = det*(w[0][6]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_0_0 = det*(w[0][7]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_0_1 = det*(w[0][7]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_0_0 = det*(w[0][8]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_0_1 = det*(w[0][8]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_0_0 = det*(w[0][9]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_0_1 = det*(w[0][9]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0 = det*(w[0][10]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1 = det*(w[0][10]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0 = det*(w[0][11]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_12_1_1 = det*(w[0][12]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_13_1_0 = det*(w[0][13]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_13_1_1 = det*(w[0][13]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_14_1_0 = det*(w[0][14]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_14_1_1 = det*(w[0][14]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_15_1_0 = det*(w[0][15]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_15_1_1 = det*(w[0][15]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_16_1_0 = det*(w[0][16]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_16_1_1 = det*(w[0][16]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_17_1_0 = det*(w[0][17]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_17_1_1 = det*(w[0][17]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_18_1_0 = det*(w[0][18]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_18_1_1 = det*(w[0][18]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_19_1_0 = det*(w[0][19]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_19_1_1 = det*(w[0][19]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0 = det*(w[0][3]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1 = det*(w[0][3]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0 = det*(w[0][4]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1 = det*(w[0][4]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0 = det*(w[0][5]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1 = det*(w[0][5]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_0_0 = det*(w[0][6]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_0_1 = det*(w[0][6]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_0_0 = det*(w[0][7]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_0_1 = det*(w[0][7]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_0_0 = det*(w[0][8]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_0_1 = det*(w[0][8]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_0_0 = det*(w[0][9]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_0_1 = det*(w[0][9]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0 = det*(w[0][10]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1 = det*(w[0][10]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0 = det*(w[0][11]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_12_1_1 = det*(w[0][12]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_13_1_0 = det*(w[0][13]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_13_1_1 = det*(w[0][13]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_14_1_0 = det*(w[0][14]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_14_1_1 = det*(w[0][14]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_15_1_0 = det*(w[0][15]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_15_1_1 = det*(w[0][15]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_16_1_0 = det*(w[0][16]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_16_1_1 = det*(w[0][16]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_17_1_0 = det*(w[0][17]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_17_1_1 = det*(w[0][17]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_18_1_0 = det*(w[0][18]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_18_1_1 = det*(w[0][18]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_19_1_0 = det*(w[0][19]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_19_1_1 = det*(w[0][19]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0 = det*(w[0][3]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1 = det*(w[0][3]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0 = det*(w[0][4]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1 = det*(w[0][4]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0 = det*(w[0][5]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1 = det*(w[0][5]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_0_0 = det*(w[0][6]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_0_1 = det*(w[0][6]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_0_0 = det*(w[0][7]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_0_1 = det*(w[0][7]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_0_0 = det*(w[0][8]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_0_1 = det*(w[0][8]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_0_0 = det*(w[0][9]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_0_1 = det*(w[0][9]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0 = det*(w[0][10]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1 = det*(w[0][10]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0 = det*(w[0][11]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_12_1_1 = det*(w[0][12]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_13_1_0 = det*(w[0][13]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_13_1_1 = det*(w[0][13]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_14_1_0 = det*(w[0][14]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_14_1_1 = det*(w[0][14]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_15_1_0 = det*(w[0][15]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_15_1_1 = det*(w[0][15]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_16_1_0 = det*(w[0][16]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_16_1_1 = det*(w[0][16]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_17_1_0 = det*(w[0][17]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_17_1_1 = det*(w[0][17]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_18_1_0 = det*(w[0][18]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_18_1_1 = det*(w[0][18]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_19_1_0 = det*(w[0][19]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_19_1_1 = det*(w[0][19]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0 = det*(w[0][3]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1 = det*(w[0][3]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0 = det*(w[0][4]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1 = det*(w[0][4]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0 = det*(w[0][5]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1 = det*(w[0][5]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_0_0 = det*(w[0][6]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_0_1 = det*(w[0][6]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_0_0 = det*(w[0][7]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_0_1 = det*(w[0][7]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_0_0 = det*(w[0][8]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_0_1 = det*(w[0][8]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_0_0 = det*(w[0][9]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_0_1 = det*(w[0][9]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0 = det*(w[0][10]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1 = det*(w[0][10]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0 = det*(w[0][11]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_12_1_1 = det*(w[0][12]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_13_1_0 = det*(w[0][13]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_13_1_1 = det*(w[0][13]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_14_1_0 = det*(w[0][14]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_14_1_1 = det*(w[0][14]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_15_1_0 = det*(w[0][15]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_15_1_1 = det*(w[0][15]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_16_1_0 = det*(w[0][16]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_16_1_1 = det*(w[0][16]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_17_1_0 = det*(w[0][17]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_17_1_1 = det*(w[0][17]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_18_1_0 = det*(w[0][18]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_18_1_1 = det*(w[0][18]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_19_1_0 = det*(w[0][19]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_19_1_1 = det*(w[0][19]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[87] = 0.0; + A[7] = 0.0; + A[18] = 0.0; + A[10] = 0.0; + A[43] = 0.0; + A[29] = 0.299999999999999*G0_1_0_0_0_0 + 0.299999999999999*G0_1_0_0_0_1 + 0.3*G0_1_0_1_0_0 - 0.299999999999999*G0_1_0_3_0_0 + 0.450000000000001*G0_1_0_3_0_1 - 0.45*G0_1_0_4_0_1 - 0.3*G0_1_0_5_0_0 - 0.749999999999999*G0_1_0_5_0_1 + 0.450000000000001*G0_1_0_6_0_1 - 0.299999999999996*G0_1_0_7_0_0 + 0.150000000000002*G0_1_0_7_0_1 - 0.300000000000003*G0_1_0_8_0_0 - 0.450000000000001*G0_1_0_8_0_1 + 0.6*G0_1_0_9_0_0 + 0.299999999999999*G0_1_0_9_0_1 + 0.299999999999999*G0_1_0_10_1_0 + 0.299999999999999*G0_1_0_10_1_1 + 0.3*G0_1_0_11_1_0 - 0.299999999999999*G0_1_0_13_1_0 + 0.450000000000001*G0_1_0_13_1_1 - 0.45*G0_1_0_14_1_1 - 0.3*G0_1_0_15_1_0 - 0.749999999999999*G0_1_0_15_1_1 + 0.450000000000001*G0_1_0_16_1_1 - 0.299999999999996*G0_1_0_17_1_0 + 0.150000000000002*G0_1_0_17_1_1 - 0.300000000000003*G0_1_0_18_1_0 - 0.450000000000001*G0_1_0_18_1_1 + 0.6*G0_1_0_19_1_0 + 0.299999999999999*G0_1_0_19_1_1 + 0.3*G0_1_1_1_0_0 - 0.149999999999999*G0_1_1_3_0_0 + 0.6*G0_1_1_3_0_1 - 0.450000000000002*G0_1_1_4_0_0 - 0.9*G0_1_1_4_0_1 - 0.150000000000002*G0_1_1_5_0_0 + 0.450000000000002*G0_1_1_6_0_0 - 0.149999999999999*G0_1_1_7_0_0 - 0.299999999999999*G0_1_1_7_0_1 - 0.150000000000002*G0_1_1_8_0_0 - 0.6*G0_1_1_8_0_1 + 0.3*G0_1_1_9_0_0 + 1.2*G0_1_1_9_0_1 + 0.3*G0_1_1_11_1_0 - 0.149999999999999*G0_1_1_13_1_0 + 0.6*G0_1_1_13_1_1 - 0.450000000000002*G0_1_1_14_1_0 - 0.9*G0_1_1_14_1_1 - 0.150000000000002*G0_1_1_15_1_0 + 0.450000000000002*G0_1_1_16_1_0 - 0.149999999999999*G0_1_1_17_1_0 - 0.299999999999999*G0_1_1_17_1_1 - 0.150000000000002*G0_1_1_18_1_0 - 0.6*G0_1_1_18_1_1 + 0.3*G0_1_1_19_1_0 + 1.2*G0_1_1_19_1_1; + A[23] = 0.0; + A[101] = 0.0; + A[68] = 0.0; + A[108] = 0.0; + A[137] = 0.0; + A[127] = 0.3*G0_0_0_2_0_1 - 0.9*G0_0_0_3_0_0 - 0.45*G0_0_0_3_0_1 + 0.6*G0_0_0_4_0_0 - 0.15*G0_0_0_4_0_1 - 0.299999999999999*G0_0_0_5_0_0 - 0.149999999999999*G0_0_0_5_0_1 - 0.600000000000001*G0_0_0_6_0_0 - 0.150000000000002*G0_0_0_6_0_1 - 0.150000000000001*G0_0_0_7_0_1 + 0.45*G0_0_0_8_0_1 + 1.2*G0_0_0_9_0_0 + 0.3*G0_0_0_9_0_1 + 0.3*G0_0_0_12_1_1 - 0.9*G0_0_0_13_1_0 - 0.45*G0_0_0_13_1_1 + 0.6*G0_0_0_14_1_0 - 0.15*G0_0_0_14_1_1 - 0.299999999999999*G0_0_0_15_1_0 - 0.149999999999999*G0_0_0_15_1_1 - 0.600000000000001*G0_0_0_16_1_0 - 0.150000000000002*G0_0_0_16_1_1 - 0.150000000000001*G0_0_0_17_1_1 + 0.45*G0_0_0_18_1_1 + 1.2*G0_0_0_19_1_0 + 0.3*G0_0_0_19_1_1 + 0.299999999999999*G0_1_0_0_0_0 + 0.299999999999999*G0_1_0_0_0_1 + 0.300000000000001*G0_1_0_2_0_1 - 0.45*G0_1_0_3_0_0 + 0.450000000000002*G0_1_0_4_0_0 - 0.299999999999999*G0_1_0_4_0_1 + 0.150000000000002*G0_1_0_5_0_0 - 0.299999999999996*G0_1_0_5_0_1 - 0.450000000000002*G0_1_0_6_0_0 - 0.300000000000004*G0_1_0_6_0_1 - 0.749999999999999*G0_1_0_7_0_0 - 0.3*G0_1_0_7_0_1 + 0.450000000000001*G0_1_0_8_0_0 + 0.299999999999998*G0_1_0_9_0_0 + 0.6*G0_1_0_9_0_1 + 0.299999999999999*G0_1_0_10_1_0 + 0.299999999999999*G0_1_0_10_1_1 + 0.300000000000001*G0_1_0_12_1_1 - 0.45*G0_1_0_13_1_0 + 0.450000000000002*G0_1_0_14_1_0 - 0.299999999999999*G0_1_0_14_1_1 + 0.150000000000002*G0_1_0_15_1_0 - 0.299999999999996*G0_1_0_15_1_1 - 0.450000000000002*G0_1_0_16_1_0 - 0.300000000000004*G0_1_0_16_1_1 - 0.749999999999999*G0_1_0_17_1_0 - 0.3*G0_1_0_17_1_1 + 0.450000000000001*G0_1_0_18_1_0 + 0.299999999999998*G0_1_0_19_1_0 + 0.6*G0_1_0_19_1_1; + A[13] = -0.125000000000002*G0_0_0_0_0_0 - 0.125000000000001*G0_0_0_0_0_1 + 0.725000000000004*G0_0_0_1_0_0 + 0.125*G0_0_0_2_0_1 + 0.675000000000002*G0_0_0_3_0_0 + 1.57500000000001*G0_0_0_3_0_1 + 0.075*G0_0_0_4_0_0 - 0.224999999999999*G0_0_0_4_0_1 - 0.0749999999999993*G0_0_0_5_0_0 - 0.0749999999999998*G0_0_0_6_0_0 + 0.300000000000006*G0_0_0_7_0_0 + 0.225000000000006*G0_0_0_7_0_1 - 0.900000000000008*G0_0_0_8_0_0 - 1.57500000000001*G0_0_0_8_0_1 - 0.600000000000003*G0_0_0_9_0_0 - 0.125000000000002*G0_0_0_10_1_0 - 0.125000000000001*G0_0_0_10_1_1 + 0.725000000000004*G0_0_0_11_1_0 + 0.125*G0_0_0_12_1_1 + 0.675000000000002*G0_0_0_13_1_0 + 1.57500000000001*G0_0_0_13_1_1 + 0.075*G0_0_0_14_1_0 - 0.224999999999999*G0_0_0_14_1_1 - 0.0749999999999993*G0_0_0_15_1_0 - 0.0749999999999998*G0_0_0_16_1_0 + 0.300000000000006*G0_0_0_17_1_0 + 0.225000000000006*G0_0_0_17_1_1 - 0.900000000000008*G0_0_0_18_1_0 - 1.57500000000001*G0_0_0_18_1_1 - 0.600000000000003*G0_0_0_19_1_0; + A[58] = 0.0; + A[38] = -0.0666666666666695*G0_0_1_0_0_0 - 0.0666666666666694*G0_0_1_0_0_1 + 0.0666666666666669*G0_0_1_1_0_0 + 0.966666666666672*G0_0_1_2_0_1 - 0.3*G0_0_1_3_0_0 - 0.15*G0_0_1_3_0_1 + 2.40000000000001*G0_0_1_4_0_0 + 1.35*G0_0_1_4_0_1 + 0.300000000000009*G0_0_1_5_0_0 + 0.15000000000001*G0_0_1_5_0_1 - 2.40000000000001*G0_0_1_6_0_0 - 1.05000000000001*G0_0_1_6_0_1 + 0.150000000000002*G0_0_1_7_0_1 + 0.15*G0_0_1_8_0_1 - 1.50000000000001*G0_0_1_9_0_1 - 0.0666666666666695*G0_0_1_10_1_0 - 0.0666666666666694*G0_0_1_10_1_1 + 0.0666666666666669*G0_0_1_11_1_0 + 0.966666666666672*G0_0_1_12_1_1 - 0.3*G0_0_1_13_1_0 - 0.15*G0_0_1_13_1_1 + 2.40000000000001*G0_0_1_14_1_0 + 1.35*G0_0_1_14_1_1 + 0.300000000000009*G0_0_1_15_1_0 + 0.15000000000001*G0_0_1_15_1_1 - 2.40000000000001*G0_0_1_16_1_0 - 1.05000000000001*G0_0_1_16_1_1 + 0.150000000000002*G0_0_1_17_1_1 + 0.15*G0_0_1_18_1_1 - 1.50000000000001*G0_0_1_19_1_1 - 0.3*G0_1_1_1_0_0 + 0.149999999999999*G0_1_1_3_0_0 - 0.6*G0_1_1_3_0_1 + 0.450000000000001*G0_1_1_4_0_0 + 0.9*G0_1_1_4_0_1 + 0.150000000000001*G0_1_1_5_0_0 - 0.450000000000001*G0_1_1_6_0_0 + 0.149999999999999*G0_1_1_7_0_0 + 0.299999999999999*G0_1_1_7_0_1 + 0.150000000000001*G0_1_1_8_0_0 + 0.6*G0_1_1_8_0_1 - 0.3*G0_1_1_9_0_0 - 1.2*G0_1_1_9_0_1 - 0.3*G0_1_1_11_1_0 + 0.149999999999999*G0_1_1_13_1_0 - 0.6*G0_1_1_13_1_1 + 0.450000000000001*G0_1_1_14_1_0 + 0.9*G0_1_1_14_1_1 + 0.150000000000001*G0_1_1_15_1_0 - 0.450000000000001*G0_1_1_16_1_0 + 0.149999999999999*G0_1_1_17_1_0 + 0.299999999999999*G0_1_1_17_1_1 + 0.150000000000001*G0_1_1_18_1_0 + 0.6*G0_1_1_18_1_1 - 0.3*G0_1_1_19_1_0 - 1.2*G0_1_1_19_1_1; + A[128] = -A[38] + 0.366666666666668*G0_1_1_0_0_0 + 0.366666666666668*G0_1_1_0_0_1 - 0.366666666666667*G0_1_1_1_0_0 - 0.966666666666672*G0_1_1_2_0_1 + 0.3*G0_1_1_3_0_0 - 0.6*G0_1_1_3_0_1 - 1.50000000000001*G0_1_1_4_0_0 - 0.300000000000008*G0_1_1_5_0_0 - 0.900000000000007*G0_1_1_5_0_1 + 1.50000000000001*G0_1_1_6_0_0 + 1.50000000000001*G0_1_1_6_0_1 + 0.599999999999997*G0_1_1_7_0_1 + 0.6*G0_1_1_8_0_1 - 0.599999999999993*G0_1_1_9_0_1 + 0.366666666666668*G0_1_1_10_1_0 + 0.366666666666668*G0_1_1_10_1_1 - 0.366666666666667*G0_1_1_11_1_0 - 0.966666666666672*G0_1_1_12_1_1 + 0.3*G0_1_1_13_1_0 - 0.6*G0_1_1_13_1_1 - 1.50000000000001*G0_1_1_14_1_0 - 0.300000000000008*G0_1_1_15_1_0 - 0.900000000000007*G0_1_1_15_1_1 + 1.50000000000001*G0_1_1_16_1_0 + 1.50000000000001*G0_1_1_16_1_1 + 0.599999999999997*G0_1_1_17_1_1 + 0.6*G0_1_1_18_1_1 - 0.599999999999993*G0_1_1_19_1_1; + A[30] = 0.0; + A[98] = 0.0; + A[71] = 0.0; + A[111] = 0.0; + A[72] = 0.0; + A[132] = 0.0; + A[89] = 0.0; + A[37] = -A[127] + 0.233333333333329*G0_1_0_0_0_0 + 0.23333333333333*G0_1_0_0_0_1 + 0.966666666666671*G0_1_0_1_0_0 + 0.366666666666667*G0_1_0_2_0_1 + 0.900000000000002*G0_1_0_3_0_0 + 2.4*G0_1_0_3_0_1 + 0.300000000000002*G0_1_0_4_0_0 - 0.599999999999998*G0_1_0_4_0_1 + 0.300000000000003*G0_1_0_5_0_0 - 0.299999999999994*G0_1_0_5_0_1 - 0.300000000000002*G0_1_0_6_0_0 - 0.300000000000003*G0_1_0_6_0_1 - 0.599999999999989*G0_1_0_7_0_0 - 0.60000000000001*G0_1_0_8_0_0 - 2.40000000000001*G0_1_0_8_0_1 - 1.20000000000001*G0_1_0_9_0_0 + 0.599999999999991*G0_1_0_9_0_1 + 0.233333333333329*G0_1_0_10_1_0 + 0.23333333333333*G0_1_0_10_1_1 + 0.966666666666671*G0_1_0_11_1_0 + 0.366666666666667*G0_1_0_12_1_1 + 0.900000000000002*G0_1_0_13_1_0 + 2.4*G0_1_0_13_1_1 + 0.300000000000002*G0_1_0_14_1_0 - 0.599999999999998*G0_1_0_14_1_1 + 0.300000000000003*G0_1_0_15_1_0 - 0.299999999999994*G0_1_0_15_1_1 - 0.300000000000002*G0_1_0_16_1_0 - 0.300000000000003*G0_1_0_16_1_1 - 0.599999999999989*G0_1_0_17_1_0 - 0.60000000000001*G0_1_0_18_1_0 - 2.40000000000001*G0_1_0_18_1_1 - 1.20000000000001*G0_1_0_19_1_0 + 0.599999999999991*G0_1_0_19_1_1; + A[35] = 0.0; + A[117] = -0.133333333333338*G0_0_0_0_0_0 - 0.133333333333338*G0_0_0_0_0_1 + 0.133333333333334*G0_0_0_1_0_0 + 1.33333333333334*G0_0_0_2_0_1 + 3.60000000000001*G0_0_0_4_0_0 + 2.4*G0_0_0_4_0_1 - 3.60000000000001*G0_0_0_6_0_0 - 1.20000000000002*G0_0_0_6_0_1 - 2.40000000000001*G0_0_0_9_0_1 - 0.133333333333338*G0_0_0_10_1_0 - 0.133333333333338*G0_0_0_10_1_1 + 0.133333333333334*G0_0_0_11_1_0 + 1.33333333333334*G0_0_0_12_1_1 + 3.60000000000001*G0_0_0_14_1_0 + 2.4*G0_0_0_14_1_1 - 3.60000000000001*G0_0_0_16_1_0 - 1.20000000000002*G0_0_0_16_1_1 - 2.40000000000001*G0_0_0_19_1_1 - 0.0666666666666681*G0_0_1_0_0_0 - 0.0666666666666681*G0_0_1_0_0_1 + 0.0666666666666678*G0_0_1_1_0_0 + 0.0666666666666675*G0_0_1_2_0_1 + 1.2*G0_0_1_3_0_0 + 0.6*G0_0_1_3_0_1 + 0.600000000000002*G0_0_1_4_0_0 + 1.2*G0_0_1_4_0_1 - 0.600000000000001*G0_0_1_6_0_0 - 0.6*G0_0_1_8_0_1 - 1.2*G0_0_1_9_0_0 - 1.2*G0_0_1_9_0_1 - 0.0666666666666681*G0_0_1_10_1_0 - 0.0666666666666681*G0_0_1_10_1_1 + 0.0666666666666678*G0_0_1_11_1_0 + 0.0666666666666675*G0_0_1_12_1_1 + 1.2*G0_0_1_13_1_0 + 0.6*G0_0_1_13_1_1 + 0.600000000000002*G0_0_1_14_1_0 + 1.2*G0_0_1_14_1_1 - 0.600000000000001*G0_0_1_16_1_0 - 0.6*G0_0_1_18_1_1 - 1.2*G0_0_1_19_1_0 - 1.2*G0_0_1_19_1_1 - 0.0666666666666681*G0_1_0_0_0_0 - 0.0666666666666681*G0_1_0_0_0_1 + 0.0666666666666678*G0_1_0_1_0_0 + 0.0666666666666676*G0_1_0_2_0_1 + 1.2*G0_1_0_3_0_0 + 0.6*G0_1_0_3_0_1 + 0.600000000000002*G0_1_0_4_0_0 + 1.2*G0_1_0_4_0_1 - 0.600000000000001*G0_1_0_6_0_0 - 0.6*G0_1_0_8_0_1 - 1.2*G0_1_0_9_0_0 - 1.2*G0_1_0_9_0_1 - 0.0666666666666681*G0_1_0_10_1_0 - 0.0666666666666681*G0_1_0_10_1_1 + 0.0666666666666678*G0_1_0_11_1_0 + 0.0666666666666676*G0_1_0_12_1_1 + 1.2*G0_1_0_13_1_0 + 0.6*G0_1_0_13_1_1 + 0.600000000000002*G0_1_0_14_1_0 + 1.2*G0_1_0_14_1_1 - 0.600000000000001*G0_1_0_16_1_0 - 0.6*G0_1_0_18_1_1 - 1.2*G0_1_0_19_1_0 - 1.2*G0_1_0_19_1_1 - 0.133333333333338*G0_1_1_0_0_0 - 0.133333333333337*G0_1_1_0_0_1 + 1.33333333333334*G0_1_1_1_0_0 + 0.133333333333333*G0_1_1_2_0_1 + 2.4*G0_1_1_3_0_0 + 3.60000000000001*G0_1_1_3_0_1 - 1.20000000000002*G0_1_1_8_0_0 - 3.60000000000001*G0_1_1_8_0_1 - 2.4*G0_1_1_9_0_0 - 0.133333333333338*G0_1_1_10_1_0 - 0.133333333333337*G0_1_1_10_1_1 + 1.33333333333334*G0_1_1_11_1_0 + 0.133333333333333*G0_1_1_12_1_1 + 2.4*G0_1_1_13_1_0 + 3.60000000000001*G0_1_1_13_1_1 - 1.20000000000002*G0_1_1_18_1_0 - 3.60000000000001*G0_1_1_18_1_1 - 2.4*G0_1_1_19_1_0; + A[92] = -0.0583333333333322*G0_0_1_0_0_0 - 0.0583333333333323*G0_0_1_0_0_1 - 0.241666666666667*G0_0_1_1_0_0 - 0.241666666666667*G0_0_1_2_0_1 + 0.225*G0_0_1_3_0_0 - 0.375*G0_0_1_3_0_1 - 0.375000000000001*G0_0_1_4_0_0 + 0.224999999999999*G0_0_1_4_0_1 + 0.0749999999999986*G0_0_1_5_0_0 + 0.149999999999998*G0_0_1_5_0_1 + 0.375000000000001*G0_0_1_6_0_0 + 0.150000000000002*G0_0_1_6_0_1 + 0.149999999999998*G0_0_1_7_0_0 + 0.0749999999999985*G0_0_1_7_0_1 + 0.150000000000002*G0_0_1_8_0_0 + 0.375*G0_0_1_8_0_1 - 0.299999999999998*G0_0_1_9_0_0 - 0.299999999999998*G0_0_1_9_0_1 - 0.0583333333333322*G0_0_1_10_1_0 - 0.0583333333333323*G0_0_1_10_1_1 - 0.241666666666667*G0_0_1_11_1_0 - 0.241666666666667*G0_0_1_12_1_1 + 0.225*G0_0_1_13_1_0 - 0.375*G0_0_1_13_1_1 - 0.375000000000001*G0_0_1_14_1_0 + 0.224999999999999*G0_0_1_14_1_1 + 0.0749999999999986*G0_0_1_15_1_0 + 0.149999999999998*G0_0_1_15_1_1 + 0.375000000000001*G0_0_1_16_1_0 + 0.150000000000002*G0_0_1_16_1_1 + 0.149999999999998*G0_0_1_17_1_0 + 0.0749999999999985*G0_0_1_17_1_1 + 0.150000000000002*G0_0_1_18_1_0 + 0.375*G0_0_1_18_1_1 - 0.299999999999998*G0_0_1_19_1_0 - 0.299999999999998*G0_0_1_19_1_1; + A[90] = A[92] - 0.241666666666666*G0_0_0_0_0_0 - 0.241666666666666*G0_0_0_0_0_1 + 0.241666666666668*G0_0_0_1_0_0 - 0.0583333333333341*G0_0_0_2_0_1 + 0.225000000000001*G0_0_0_3_0_0 + 0.375000000000003*G0_0_0_3_0_1 - 0.0750000000000011*G0_0_0_4_0_0 + 0.0749999999999995*G0_0_0_4_0_1 - 0.225000000000001*G0_0_0_5_0_0 + 0.149999999999998*G0_0_0_5_0_1 + 0.0750000000000011*G0_0_0_6_0_0 + 0.150000000000002*G0_0_0_6_0_1 + 0.6*G0_0_0_7_0_0 + 0.225000000000002*G0_0_0_7_0_1 - 0.600000000000003*G0_0_0_8_0_0 - 0.375000000000003*G0_0_0_8_0_1 - 0.300000000000001*G0_0_0_9_0_1 - 0.241666666666666*G0_0_0_10_1_0 - 0.241666666666666*G0_0_0_10_1_1 + 0.241666666666668*G0_0_0_11_1_0 - 0.0583333333333341*G0_0_0_12_1_1 + 0.225000000000001*G0_0_0_13_1_0 + 0.375000000000003*G0_0_0_13_1_1 - 0.0750000000000011*G0_0_0_14_1_0 + 0.0749999999999995*G0_0_0_14_1_1 - 0.225000000000001*G0_0_0_15_1_0 + 0.149999999999998*G0_0_0_15_1_1 + 0.0750000000000011*G0_0_0_16_1_0 + 0.150000000000002*G0_0_0_16_1_1 + 0.6*G0_0_0_17_1_0 + 0.225000000000002*G0_0_0_17_1_1 - 0.600000000000003*G0_0_0_18_1_0 - 0.375000000000003*G0_0_0_18_1_1 - 0.300000000000001*G0_0_0_19_1_1 - 0.183333333333334*G0_0_1_0_0_0 - 0.183333333333334*G0_0_1_0_0_1 + 0.483333333333336*G0_0_1_1_0_0 + 0.183333333333333*G0_0_1_2_0_1 + 0.750000000000004*G0_0_1_3_0_1 + 0.3*G0_0_1_4_0_0 - 0.15*G0_0_1_4_0_1 - 0.3*G0_0_1_5_0_0 - 0.3*G0_0_1_6_0_0 + 0.450000000000003*G0_0_1_7_0_0 + 0.150000000000004*G0_0_1_7_0_1 - 0.750000000000004*G0_0_1_8_0_0 - 0.750000000000004*G0_0_1_8_0_1 + 0.299999999999998*G0_0_1_9_0_0 - 0.183333333333334*G0_0_1_10_1_0 - 0.183333333333334*G0_0_1_10_1_1 + 0.483333333333336*G0_0_1_11_1_0 + 0.183333333333333*G0_0_1_12_1_1 + 0.750000000000004*G0_0_1_13_1_1 + 0.3*G0_0_1_14_1_0 - 0.15*G0_0_1_14_1_1 - 0.3*G0_0_1_15_1_0 - 0.3*G0_0_1_16_1_0 + 0.450000000000003*G0_0_1_17_1_0 + 0.150000000000004*G0_0_1_17_1_1 - 0.750000000000004*G0_0_1_18_1_0 - 0.750000000000004*G0_0_1_18_1_1 + 0.299999999999998*G0_0_1_19_1_0; + A[47] = 0.0; + A[25] = -0.0583333333333322*G0_1_0_0_0_0 - 0.0583333333333323*G0_1_0_0_0_1 - 0.241666666666667*G0_1_0_1_0_0 - 0.241666666666667*G0_1_0_2_0_1 + 0.225*G0_1_0_3_0_0 - 0.375*G0_1_0_3_0_1 - 0.375000000000001*G0_1_0_4_0_0 + 0.224999999999999*G0_1_0_4_0_1 + 0.0749999999999986*G0_1_0_5_0_0 + 0.149999999999998*G0_1_0_5_0_1 + 0.375000000000001*G0_1_0_6_0_0 + 0.150000000000002*G0_1_0_6_0_1 + 0.149999999999998*G0_1_0_7_0_0 + 0.0749999999999985*G0_1_0_7_0_1 + 0.150000000000002*G0_1_0_8_0_0 + 0.375000000000001*G0_1_0_8_0_1 - 0.299999999999998*G0_1_0_9_0_0 - 0.299999999999998*G0_1_0_9_0_1 - 0.0583333333333322*G0_1_0_10_1_0 - 0.0583333333333323*G0_1_0_10_1_1 - 0.241666666666667*G0_1_0_11_1_0 - 0.241666666666667*G0_1_0_12_1_1 + 0.225*G0_1_0_13_1_0 - 0.375*G0_1_0_13_1_1 - 0.375000000000001*G0_1_0_14_1_0 + 0.224999999999999*G0_1_0_14_1_1 + 0.0749999999999986*G0_1_0_15_1_0 + 0.149999999999998*G0_1_0_15_1_1 + 0.375000000000001*G0_1_0_16_1_0 + 0.150000000000002*G0_1_0_16_1_1 + 0.149999999999998*G0_1_0_17_1_0 + 0.0749999999999985*G0_1_0_17_1_1 + 0.150000000000002*G0_1_0_18_1_0 + 0.375000000000001*G0_1_0_18_1_1 - 0.299999999999998*G0_1_0_19_1_0 - 0.299999999999998*G0_1_0_19_1_1; + A[79] = A[25] - 0.241666666666666*G0_0_0_0_0_0 - 0.241666666666666*G0_0_0_0_0_1 + 0.241666666666668*G0_0_0_1_0_0 - 0.0583333333333341*G0_0_0_2_0_1 + 0.225000000000001*G0_0_0_3_0_0 + 0.375000000000003*G0_0_0_3_0_1 - 0.0750000000000011*G0_0_0_4_0_0 + 0.0749999999999995*G0_0_0_4_0_1 - 0.225000000000001*G0_0_0_5_0_0 + 0.149999999999998*G0_0_0_5_0_1 + 0.0750000000000011*G0_0_0_6_0_0 + 0.150000000000002*G0_0_0_6_0_1 + 0.6*G0_0_0_7_0_0 + 0.225000000000002*G0_0_0_7_0_1 - 0.600000000000003*G0_0_0_8_0_0 - 0.375000000000003*G0_0_0_8_0_1 - 0.300000000000001*G0_0_0_9_0_1 - 0.241666666666666*G0_0_0_10_1_0 - 0.241666666666666*G0_0_0_10_1_1 + 0.241666666666668*G0_0_0_11_1_0 - 0.0583333333333341*G0_0_0_12_1_1 + 0.225000000000001*G0_0_0_13_1_0 + 0.375000000000003*G0_0_0_13_1_1 - 0.0750000000000011*G0_0_0_14_1_0 + 0.0749999999999995*G0_0_0_14_1_1 - 0.225000000000001*G0_0_0_15_1_0 + 0.149999999999998*G0_0_0_15_1_1 + 0.0750000000000011*G0_0_0_16_1_0 + 0.150000000000002*G0_0_0_16_1_1 + 0.6*G0_0_0_17_1_0 + 0.225000000000002*G0_0_0_17_1_1 - 0.600000000000003*G0_0_0_18_1_0 - 0.375000000000003*G0_0_0_18_1_1 - 0.300000000000001*G0_0_0_19_1_1 - 0.183333333333334*G0_1_0_0_0_0 - 0.183333333333334*G0_1_0_0_0_1 + 0.483333333333336*G0_1_0_1_0_0 + 0.183333333333333*G0_1_0_2_0_1 + 0.750000000000004*G0_1_0_3_0_1 + 0.3*G0_1_0_4_0_0 - 0.149999999999999*G0_1_0_4_0_1 - 0.3*G0_1_0_5_0_0 - 0.3*G0_1_0_6_0_0 + 0.450000000000003*G0_1_0_7_0_0 + 0.150000000000004*G0_1_0_7_0_1 - 0.750000000000004*G0_1_0_8_0_0 - 0.750000000000004*G0_1_0_8_0_1 + 0.299999999999998*G0_1_0_9_0_0 - 0.183333333333334*G0_1_0_10_1_0 - 0.183333333333334*G0_1_0_10_1_1 + 0.483333333333336*G0_1_0_11_1_0 + 0.183333333333333*G0_1_0_12_1_1 + 0.750000000000004*G0_1_0_13_1_1 + 0.3*G0_1_0_14_1_0 - 0.149999999999999*G0_1_0_14_1_1 - 0.3*G0_1_0_15_1_0 - 0.3*G0_1_0_16_1_0 + 0.450000000000003*G0_1_0_17_1_0 + 0.150000000000004*G0_1_0_17_1_1 - 0.750000000000004*G0_1_0_18_1_0 - 0.750000000000004*G0_1_0_18_1_1 + 0.299999999999998*G0_1_0_19_1_0; + A[1] = A[79]; + A[105] = -A[29] + 0.233333333333329*G0_1_0_0_0_0 + 0.233333333333329*G0_1_0_0_0_1 + 0.366666666666668*G0_1_0_1_0_0 + 0.966666666666671*G0_1_0_2_0_1 - 0.6*G0_1_0_3_0_0 + 0.300000000000001*G0_1_0_3_0_1 + 2.40000000000001*G0_1_0_4_0_0 + 0.900000000000003*G0_1_0_4_0_1 - 0.599999999999988*G0_1_0_5_0_1 - 2.40000000000001*G0_1_0_6_0_0 - 0.600000000000012*G0_1_0_6_0_1 - 0.299999999999994*G0_1_0_7_0_0 + 0.300000000000004*G0_1_0_7_0_1 - 0.300000000000003*G0_1_0_8_0_0 - 0.300000000000001*G0_1_0_8_0_1 + 0.599999999999991*G0_1_0_9_0_0 - 1.20000000000001*G0_1_0_9_0_1 + 0.233333333333329*G0_1_0_10_1_0 + 0.233333333333329*G0_1_0_10_1_1 + 0.366666666666668*G0_1_0_11_1_0 + 0.966666666666671*G0_1_0_12_1_1 - 0.6*G0_1_0_13_1_0 + 0.300000000000001*G0_1_0_13_1_1 + 2.40000000000001*G0_1_0_14_1_0 + 0.900000000000003*G0_1_0_14_1_1 - 0.599999999999988*G0_1_0_15_1_1 - 2.40000000000001*G0_1_0_16_1_0 - 0.600000000000012*G0_1_0_16_1_1 - 0.299999999999994*G0_1_0_17_1_0 + 0.300000000000004*G0_1_0_17_1_1 - 0.300000000000003*G0_1_0_18_1_0 - 0.300000000000001*G0_1_0_18_1_1 + 0.599999999999991*G0_1_0_19_1_0 - 1.20000000000001*G0_1_0_19_1_1; + A[81] = -A[105] + 0.300000000000003*G0_0_0_2_0_1 + 0.3*G0_0_0_3_0_0 + 0.15*G0_0_0_3_0_1 + 0.600000000000006*G0_0_0_4_0_0 + 0.450000000000003*G0_0_0_4_0_1 + 0.900000000000003*G0_0_0_5_0_0 + 0.450000000000004*G0_0_0_5_0_1 - 0.600000000000006*G0_0_0_6_0_0 - 0.750000000000005*G0_0_0_6_0_1 + 0.45*G0_0_0_7_0_1 - 0.15*G0_0_0_8_0_1 - 1.2*G0_0_0_9_0_0 - 0.900000000000003*G0_0_0_9_0_1 + 0.300000000000003*G0_0_0_12_1_1 + 0.3*G0_0_0_13_1_0 + 0.15*G0_0_0_13_1_1 + 0.600000000000006*G0_0_0_14_1_0 + 0.450000000000003*G0_0_0_14_1_1 + 0.900000000000003*G0_0_0_15_1_0 + 0.450000000000004*G0_0_0_15_1_1 - 0.600000000000006*G0_0_0_16_1_0 - 0.750000000000005*G0_0_0_16_1_1 + 0.45*G0_0_0_17_1_1 - 0.15*G0_0_0_18_1_1 - 1.2*G0_0_0_19_1_0 - 0.900000000000003*G0_0_0_19_1_1 + 0.300000000000002*G0_0_1_1_0_0 + 0.450000000000002*G0_0_1_3_0_0 + 0.600000000000004*G0_0_1_3_0_1 + 0.150000000000001*G0_0_1_4_0_0 + 0.3*G0_0_1_4_0_1 + 0.45*G0_0_1_5_0_0 - 0.150000000000001*G0_0_1_6_0_0 + 0.450000000000003*G0_0_1_7_0_0 + 0.900000000000003*G0_0_1_7_0_1 - 0.750000000000004*G0_0_1_8_0_0 - 0.600000000000004*G0_0_1_8_0_1 - 0.900000000000002*G0_0_1_9_0_0 - 1.2*G0_0_1_9_0_1 + 0.300000000000002*G0_0_1_11_1_0 + 0.450000000000002*G0_0_1_13_1_0 + 0.600000000000004*G0_0_1_13_1_1 + 0.150000000000001*G0_0_1_14_1_0 + 0.3*G0_0_1_14_1_1 + 0.45*G0_0_1_15_1_0 - 0.150000000000001*G0_0_1_16_1_0 + 0.450000000000003*G0_0_1_17_1_0 + 0.900000000000003*G0_0_1_17_1_1 - 0.750000000000004*G0_0_1_18_1_0 - 0.600000000000004*G0_0_1_18_1_1 - 0.900000000000002*G0_0_1_19_1_0 - 1.2*G0_0_1_19_1_1 - 0.0666666666666706*G0_1_0_0_0_0 - 0.0666666666666705*G0_1_0_0_0_1 + 0.0666666666666672*G0_1_0_1_0_0 + 1.26666666666668*G0_1_0_2_0_1 + 3.00000000000001*G0_1_0_4_0_0 + 1.80000000000001*G0_1_0_4_0_1 + 1.20000000000001*G0_1_0_5_0_0 + 0.600000000000014*G0_1_0_5_0_1 - 3.00000000000002*G0_1_0_6_0_0 - 1.80000000000002*G0_1_0_6_0_1 + 0.600000000000002*G0_1_0_7_0_1 - 1.20000000000001*G0_1_0_9_0_0 - 2.40000000000001*G0_1_0_9_0_1 - 0.0666666666666706*G0_1_0_10_1_0 - 0.0666666666666705*G0_1_0_10_1_1 + 0.0666666666666672*G0_1_0_11_1_0 + 1.26666666666668*G0_1_0_12_1_1 + 3.00000000000001*G0_1_0_14_1_0 + 1.80000000000001*G0_1_0_14_1_1 + 1.20000000000001*G0_1_0_15_1_0 + 0.600000000000014*G0_1_0_15_1_1 - 3.00000000000002*G0_1_0_16_1_0 - 1.80000000000002*G0_1_0_16_1_1 + 0.600000000000002*G0_1_0_17_1_1 - 1.20000000000001*G0_1_0_19_1_0 - 2.40000000000001*G0_1_0_19_1_1 + 0.600000000000002*G0_1_1_3_0_0 + 0.600000000000002*G0_1_1_4_0_0 + 1.2*G0_1_1_4_0_1 + 0.600000000000001*G0_1_1_5_0_0 - 0.600000000000002*G0_1_1_6_0_0 + 0.600000000000002*G0_1_1_7_0_0 + 1.2*G0_1_1_7_0_1 - 0.600000000000003*G0_1_1_8_0_0 - 1.2*G0_1_1_9_0_0 - 2.4*G0_1_1_9_0_1 + 0.600000000000002*G0_1_1_13_1_0 + 0.600000000000002*G0_1_1_14_1_0 + 1.2*G0_1_1_14_1_1 + 0.600000000000001*G0_1_1_15_1_0 - 0.600000000000002*G0_1_1_16_1_0 + 0.600000000000002*G0_1_1_17_1_0 + 1.2*G0_1_1_17_1_1 - 0.600000000000003*G0_1_1_18_1_0 - 1.2*G0_1_1_19_1_0 - 2.4*G0_1_1_19_1_1; + A[82] = -A[81] + 0.966666666666664*G0_0_1_0_0_0 + 0.966666666666664*G0_0_1_0_0_1 + 0.233333333333336*G0_0_1_1_0_0 - 0.366666666666669*G0_0_1_2_0_1 + 0.300000000000003*G0_0_1_3_0_0 + 0.600000000000003*G0_0_1_3_0_1 - 0.300000000000005*G0_0_1_4_0_0 + 0.899999999999998*G0_0_1_5_0_0 - 1.5*G0_0_1_5_0_1 + 0.300000000000005*G0_0_1_6_0_0 + 0.900000000000003*G0_0_1_6_0_1 - 0.599999999999993*G0_0_1_7_0_0 + 1.8*G0_0_1_7_0_1 - 0.600000000000007*G0_0_1_8_0_0 - 0.600000000000003*G0_0_1_8_0_1 - 1.2*G0_0_1_9_0_0 - 1.8*G0_0_1_9_0_1 + 0.966666666666664*G0_0_1_10_1_0 + 0.966666666666664*G0_0_1_10_1_1 + 0.233333333333336*G0_0_1_11_1_0 - 0.366666666666669*G0_0_1_12_1_1 + 0.300000000000003*G0_0_1_13_1_0 + 0.600000000000003*G0_0_1_13_1_1 - 0.300000000000005*G0_0_1_14_1_0 + 0.899999999999998*G0_0_1_15_1_0 - 1.5*G0_0_1_15_1_1 + 0.300000000000005*G0_0_1_16_1_0 + 0.900000000000003*G0_0_1_16_1_1 - 0.599999999999993*G0_0_1_17_1_0 + 1.8*G0_0_1_17_1_1 - 0.600000000000007*G0_0_1_18_1_0 - 0.600000000000003*G0_0_1_18_1_1 - 1.2*G0_0_1_19_1_0 - 1.8*G0_0_1_19_1_1 + 0.966666666666664*G0_1_1_0_0_0 + 0.966666666666664*G0_1_1_0_0_1 + 0.233333333333336*G0_1_1_1_0_0 - 0.366666666666669*G0_1_1_2_0_1 + 0.300000000000004*G0_1_1_3_0_0 + 0.600000000000003*G0_1_1_3_0_1 - 0.300000000000005*G0_1_1_4_0_0 + 0.899999999999998*G0_1_1_5_0_0 - 1.5*G0_1_1_5_0_1 + 0.300000000000005*G0_1_1_6_0_0 + 0.900000000000003*G0_1_1_6_0_1 - 0.599999999999993*G0_1_1_7_0_0 + 1.8*G0_1_1_7_0_1 - 0.600000000000007*G0_1_1_8_0_0 - 0.600000000000004*G0_1_1_8_0_1 - 1.2*G0_1_1_9_0_0 - 1.8*G0_1_1_9_0_1 + 0.966666666666664*G0_1_1_10_1_0 + 0.966666666666664*G0_1_1_10_1_1 + 0.233333333333336*G0_1_1_11_1_0 - 0.366666666666669*G0_1_1_12_1_1 + 0.300000000000004*G0_1_1_13_1_0 + 0.600000000000003*G0_1_1_13_1_1 - 0.300000000000005*G0_1_1_14_1_0 + 0.899999999999998*G0_1_1_15_1_0 - 1.5*G0_1_1_15_1_1 + 0.300000000000005*G0_1_1_16_1_0 + 0.900000000000003*G0_1_1_16_1_1 - 0.599999999999993*G0_1_1_17_1_0 + 1.8*G0_1_1_17_1_1 - 0.600000000000007*G0_1_1_18_1_0 - 0.600000000000004*G0_1_1_18_1_1 - 1.2*G0_1_1_19_1_0 - 1.8*G0_1_1_19_1_1; + A[4] = A[82]; + A[112] = 0.0; + A[61] = -A[37] + 0.366666666666668*G0_0_0_0_0_0 + 0.366666666666668*G0_0_0_0_0_1 - 0.966666666666671*G0_0_0_1_0_0 - 0.366666666666666*G0_0_0_2_0_1 - 1.50000000000001*G0_0_0_3_0_1 - 0.6*G0_0_0_4_0_0 + 0.3*G0_0_0_4_0_1 + 0.599999999999999*G0_0_0_5_0_0 + 0.6*G0_0_0_6_0_0 - 0.900000000000006*G0_0_0_7_0_0 - 0.300000000000007*G0_0_0_7_0_1 + 1.50000000000001*G0_0_0_8_0_0 + 1.50000000000001*G0_0_0_8_0_1 - 0.599999999999995*G0_0_0_9_0_0 + 0.366666666666668*G0_0_0_10_1_0 + 0.366666666666668*G0_0_0_10_1_1 - 0.966666666666671*G0_0_0_11_1_0 - 0.366666666666666*G0_0_0_12_1_1 - 1.50000000000001*G0_0_0_13_1_1 - 0.6*G0_0_0_14_1_0 + 0.3*G0_0_0_14_1_1 + 0.599999999999999*G0_0_0_15_1_0 + 0.6*G0_0_0_16_1_0 - 0.900000000000006*G0_0_0_17_1_0 - 0.300000000000007*G0_0_0_17_1_1 + 1.50000000000001*G0_0_0_18_1_0 + 1.50000000000001*G0_0_0_18_1_1 - 0.599999999999995*G0_0_0_19_1_0; + A[123] = 0.0; + A[86] = 0.0; + A[11] = 0.0; + A[42] = 0.0; + A[26] = -0.125000000000002*G0_1_1_0_0_0 - 0.125000000000002*G0_1_1_0_0_1 + 0.125*G0_1_1_1_0_0 + 0.725000000000004*G0_1_1_2_0_1 - 0.225000000000001*G0_1_1_3_0_0 + 0.075*G0_1_1_3_0_1 + 1.57500000000001*G0_1_1_4_0_0 + 0.675000000000003*G0_1_1_4_0_1 + 0.225000000000007*G0_1_1_5_0_0 + 0.300000000000007*G0_1_1_5_0_1 - 1.57500000000001*G0_1_1_6_0_0 - 0.90000000000001*G0_1_1_6_0_1 - 0.0749999999999984*G0_1_1_7_0_1 - 0.075*G0_1_1_8_0_1 - 0.600000000000005*G0_1_1_9_0_1 - 0.125000000000002*G0_1_1_10_1_0 - 0.125000000000002*G0_1_1_10_1_1 + 0.125*G0_1_1_11_1_0 + 0.725000000000004*G0_1_1_12_1_1 - 0.225000000000001*G0_1_1_13_1_0 + 0.075*G0_1_1_13_1_1 + 1.57500000000001*G0_1_1_14_1_0 + 0.675000000000003*G0_1_1_14_1_1 + 0.225000000000007*G0_1_1_15_1_0 + 0.300000000000007*G0_1_1_15_1_1 - 1.57500000000001*G0_1_1_16_1_0 - 0.90000000000001*G0_1_1_16_1_1 - 0.0749999999999984*G0_1_1_17_1_1 - 0.075*G0_1_1_18_1_1 - 0.600000000000005*G0_1_1_19_1_1; + A[22] = 0.0; + A[102] = A[25] - 0.183333333333334*G0_1_0_0_0_0 - 0.183333333333334*G0_1_0_0_0_1 + 0.183333333333334*G0_1_0_1_0_0 + 0.483333333333336*G0_1_0_2_0_1 - 0.150000000000001*G0_1_0_3_0_0 + 0.3*G0_1_0_3_0_1 + 0.750000000000006*G0_1_0_4_0_0 + 0.150000000000004*G0_1_0_5_0_0 + 0.450000000000004*G0_1_0_5_0_1 - 0.750000000000006*G0_1_0_6_0_0 - 0.750000000000006*G0_1_0_6_0_1 - 0.299999999999999*G0_1_0_7_0_1 - 0.3*G0_1_0_8_0_1 + 0.299999999999996*G0_1_0_9_0_1 - 0.183333333333334*G0_1_0_10_1_0 - 0.183333333333334*G0_1_0_10_1_1 + 0.183333333333334*G0_1_0_11_1_0 + 0.483333333333336*G0_1_0_12_1_1 - 0.150000000000001*G0_1_0_13_1_0 + 0.3*G0_1_0_13_1_1 + 0.750000000000006*G0_1_0_14_1_0 + 0.150000000000004*G0_1_0_15_1_0 + 0.450000000000004*G0_1_0_15_1_1 - 0.750000000000006*G0_1_0_16_1_0 - 0.750000000000006*G0_1_0_16_1_1 - 0.299999999999999*G0_1_0_17_1_1 - 0.3*G0_1_0_18_1_1 + 0.299999999999996*G0_1_0_19_1_1 - 0.241666666666667*G0_1_1_0_0_0 - 0.241666666666667*G0_1_1_0_0_1 - 0.0583333333333338*G0_1_1_1_0_0 + 0.241666666666669*G0_1_1_2_0_1 + 0.0749999999999992*G0_1_1_3_0_0 - 0.0750000000000007*G0_1_1_3_0_1 + 0.375000000000004*G0_1_1_4_0_0 + 0.225000000000002*G0_1_1_4_0_1 + 0.225000000000002*G0_1_1_5_0_0 + 0.600000000000001*G0_1_1_5_0_1 - 0.375000000000004*G0_1_1_6_0_0 - 0.600000000000003*G0_1_1_6_0_1 + 0.149999999999999*G0_1_1_7_0_0 - 0.225*G0_1_1_7_0_1 + 0.150000000000002*G0_1_1_8_0_0 + 0.0750000000000006*G0_1_1_8_0_1 - 0.300000000000001*G0_1_1_9_0_0 - 0.241666666666667*G0_1_1_10_1_0 - 0.241666666666667*G0_1_1_10_1_1 - 0.0583333333333338*G0_1_1_11_1_0 + 0.241666666666669*G0_1_1_12_1_1 + 0.0749999999999992*G0_1_1_13_1_0 - 0.0750000000000007*G0_1_1_13_1_1 + 0.375000000000004*G0_1_1_14_1_0 + 0.225000000000002*G0_1_1_14_1_1 + 0.225000000000002*G0_1_1_15_1_0 + 0.600000000000001*G0_1_1_15_1_1 - 0.375000000000004*G0_1_1_16_1_0 - 0.600000000000003*G0_1_1_16_1_1 + 0.149999999999999*G0_1_1_17_1_0 - 0.225*G0_1_1_17_1_1 + 0.150000000000002*G0_1_1_18_1_0 + 0.0750000000000006*G0_1_1_18_1_1 - 0.300000000000001*G0_1_1_19_1_0; + A[49] = A[127]; + A[129] = -A[117] - 1.20000000000001*G0_1_0_2_0_1 + 1.2*G0_1_0_3_0_0 + 0.6*G0_1_0_3_0_1 - 2.40000000000001*G0_1_0_4_0_0 - 0.600000000000006*G0_1_0_4_0_1 - 1.20000000000001*G0_1_0_5_0_0 - 0.60000000000001*G0_1_0_5_0_1 + 2.40000000000001*G0_1_0_6_0_0 + 1.80000000000002*G0_1_0_6_0_1 - 0.599999999999998*G0_1_0_7_0_1 - 0.6*G0_1_0_8_0_1 + 1.2*G0_1_0_9_0_1 - 1.20000000000001*G0_1_0_12_1_1 + 1.2*G0_1_0_13_1_0 + 0.6*G0_1_0_13_1_1 - 2.40000000000001*G0_1_0_14_1_0 - 0.600000000000006*G0_1_0_14_1_1 - 1.20000000000001*G0_1_0_15_1_0 - 0.60000000000001*G0_1_0_15_1_1 + 2.40000000000001*G0_1_0_16_1_0 + 1.80000000000002*G0_1_0_16_1_1 - 0.599999999999998*G0_1_0_17_1_1 - 0.6*G0_1_0_18_1_1 + 1.2*G0_1_0_19_1_1 - 0.133333333333337*G0_1_1_0_0_0 - 0.133333333333337*G0_1_1_0_0_1 + 1.33333333333334*G0_1_1_1_0_0 + 0.133333333333332*G0_1_1_2_0_1 + 1.8*G0_1_1_3_0_0 + 3.60000000000001*G0_1_1_3_0_1 - 0.600000000000001*G0_1_1_4_0_0 - 1.2*G0_1_1_4_0_1 - 0.599999999999999*G0_1_1_5_0_0 + 0.600000000000002*G0_1_1_6_0_0 - 0.599999999999987*G0_1_1_7_0_0 - 1.19999999999999*G0_1_1_7_0_1 - 0.600000000000014*G0_1_1_8_0_0 - 3.60000000000001*G0_1_1_8_0_1 - 1.2*G0_1_1_9_0_0 + 2.39999999999999*G0_1_1_9_0_1 - 0.133333333333337*G0_1_1_10_1_0 - 0.133333333333337*G0_1_1_10_1_1 + 1.33333333333334*G0_1_1_11_1_0 + 0.133333333333332*G0_1_1_12_1_1 + 1.8*G0_1_1_13_1_0 + 3.60000000000001*G0_1_1_13_1_1 - 0.600000000000001*G0_1_1_14_1_0 - 1.2*G0_1_1_14_1_1 - 0.599999999999999*G0_1_1_15_1_0 + 0.600000000000002*G0_1_1_16_1_0 - 0.599999999999987*G0_1_1_17_1_0 - 1.19999999999999*G0_1_1_17_1_1 - 0.600000000000014*G0_1_1_18_1_0 - 3.60000000000001*G0_1_1_18_1_1 - 1.2*G0_1_1_19_1_0 + 2.39999999999999*G0_1_1_19_1_1; + A[53] = -A[129] + 0.133333333333337*G0_0_0_0_0_0 + 0.133333333333337*G0_0_0_0_0_1 - 0.133333333333333*G0_0_0_1_0_0 - 1.33333333333334*G0_0_0_2_0_1 + 1.2*G0_0_0_3_0_0 + 0.6*G0_0_0_3_0_1 - 3.60000000000001*G0_0_0_4_0_0 - 1.8*G0_0_0_4_0_1 + 1.19999999999999*G0_0_0_5_0_0 + 0.599999999999986*G0_0_0_5_0_1 + 3.60000000000001*G0_0_0_6_0_0 + 0.600000000000015*G0_0_0_6_0_1 + 0.599999999999997*G0_0_0_7_0_1 - 0.6*G0_0_0_8_0_1 - 2.39999999999999*G0_0_0_9_0_0 + 1.20000000000001*G0_0_0_9_0_1 + 0.133333333333337*G0_0_0_10_1_0 + 0.133333333333337*G0_0_0_10_1_1 - 0.133333333333333*G0_0_0_11_1_0 - 1.33333333333334*G0_0_0_12_1_1 + 1.2*G0_0_0_13_1_0 + 0.6*G0_0_0_13_1_1 - 3.60000000000001*G0_0_0_14_1_0 - 1.8*G0_0_0_14_1_1 + 1.19999999999999*G0_0_0_15_1_0 + 0.599999999999986*G0_0_0_15_1_1 + 3.60000000000001*G0_0_0_16_1_0 + 0.600000000000015*G0_0_0_16_1_1 + 0.599999999999997*G0_0_0_17_1_1 - 0.6*G0_0_0_18_1_1 - 2.39999999999999*G0_0_0_19_1_0 + 1.20000000000001*G0_0_0_19_1_1 - 1.19999999999999*G0_1_0_0_0_0 - 1.19999999999999*G0_1_0_0_0_1 - 1.20000000000001*G0_1_0_2_0_1 + 0.6*G0_1_0_3_0_0 - 3.00000000000001*G0_1_0_4_0_0 - 1.20000000000001*G0_1_0_4_0_1 - 1.80000000000001*G0_1_0_5_0_0 + 1.19999999999998*G0_1_0_5_0_1 + 3.00000000000001*G0_1_0_6_0_0 + 1.20000000000002*G0_1_0_6_0_1 + 1.79999999999999*G0_1_0_7_0_0 - 1.2*G0_1_0_7_0_1 - 0.599999999999998*G0_1_0_8_0_0 + 1.20000000000001*G0_1_0_9_0_0 + 2.40000000000001*G0_1_0_9_0_1 - 1.19999999999999*G0_1_0_10_1_0 - 1.19999999999999*G0_1_0_10_1_1 - 1.20000000000001*G0_1_0_12_1_1 + 0.6*G0_1_0_13_1_0 - 3.00000000000001*G0_1_0_14_1_0 - 1.20000000000001*G0_1_0_14_1_1 - 1.80000000000001*G0_1_0_15_1_0 + 1.19999999999998*G0_1_0_15_1_1 + 3.00000000000001*G0_1_0_16_1_0 + 1.20000000000002*G0_1_0_16_1_1 + 1.79999999999999*G0_1_0_17_1_0 - 1.2*G0_1_0_17_1_1 - 0.599999999999998*G0_1_0_18_1_0 + 1.20000000000001*G0_1_0_19_1_0 + 2.40000000000001*G0_1_0_19_1_1; + A[115] = A[37]; + A[76] = 0.0; + A[136] = 0.0; + A[124] = 0.0; + A[85] = 0.0; + A[83] = -A[81] + 0.966666666666664*G0_0_0_0_0_0 + 0.966666666666664*G0_0_0_0_0_1 - 0.366666666666668*G0_0_0_1_0_0 + 0.233333333333337*G0_0_0_2_0_1 - 0.300000000000005*G0_0_0_3_0_1 + 0.600000000000006*G0_0_0_4_0_0 + 0.300000000000004*G0_0_0_4_0_1 + 1.8*G0_0_0_5_0_0 - 0.599999999999993*G0_0_0_5_0_1 - 0.600000000000006*G0_0_0_6_0_0 - 0.600000000000008*G0_0_0_6_0_1 - 1.5*G0_0_0_7_0_0 + 0.899999999999998*G0_0_0_7_0_1 + 0.900000000000002*G0_0_0_8_0_0 + 0.300000000000004*G0_0_0_8_0_1 - 1.8*G0_0_0_9_0_0 - 1.2*G0_0_0_9_0_1 + 0.966666666666664*G0_0_0_10_1_0 + 0.966666666666664*G0_0_0_10_1_1 - 0.366666666666668*G0_0_0_11_1_0 + 0.233333333333337*G0_0_0_12_1_1 - 0.300000000000005*G0_0_0_13_1_1 + 0.600000000000006*G0_0_0_14_1_0 + 0.300000000000004*G0_0_0_14_1_1 + 1.8*G0_0_0_15_1_0 - 0.599999999999993*G0_0_0_15_1_1 - 0.600000000000006*G0_0_0_16_1_0 - 0.600000000000008*G0_0_0_16_1_1 - 1.5*G0_0_0_17_1_0 + 0.899999999999998*G0_0_0_17_1_1 + 0.900000000000002*G0_0_0_18_1_0 + 0.300000000000004*G0_0_0_18_1_1 - 1.8*G0_0_0_19_1_0 - 1.2*G0_0_0_19_1_1 + 0.966666666666664*G0_1_0_0_0_0 + 0.966666666666664*G0_1_0_0_0_1 - 0.366666666666669*G0_1_0_1_0_0 + 0.233333333333337*G0_1_0_2_0_1 - 0.300000000000005*G0_1_0_3_0_1 + 0.600000000000005*G0_1_0_4_0_0 + 0.300000000000004*G0_1_0_4_0_1 + 1.8*G0_1_0_5_0_0 - 0.599999999999993*G0_1_0_5_0_1 - 0.600000000000005*G0_1_0_6_0_0 - 0.600000000000008*G0_1_0_6_0_1 - 1.5*G0_1_0_7_0_0 + 0.899999999999998*G0_1_0_7_0_1 + 0.900000000000002*G0_1_0_8_0_0 + 0.300000000000005*G0_1_0_8_0_1 - 1.8*G0_1_0_9_0_0 - 1.2*G0_1_0_9_0_1 + 0.966666666666664*G0_1_0_10_1_0 + 0.966666666666664*G0_1_0_10_1_1 - 0.366666666666669*G0_1_0_11_1_0 + 0.233333333333337*G0_1_0_12_1_1 - 0.300000000000005*G0_1_0_13_1_1 + 0.600000000000005*G0_1_0_14_1_0 + 0.300000000000004*G0_1_0_14_1_1 + 1.8*G0_1_0_15_1_0 - 0.599999999999993*G0_1_0_15_1_1 - 0.600000000000005*G0_1_0_16_1_0 - 0.600000000000008*G0_1_0_16_1_1 - 1.5*G0_1_0_17_1_0 + 0.899999999999998*G0_1_0_17_1_1 + 0.900000000000002*G0_1_0_18_1_0 + 0.300000000000005*G0_1_0_18_1_1 - 1.8*G0_1_0_19_1_0 - 1.2*G0_1_0_19_1_1; + A[141] = -A[117] - 0.133333333333337*G0_0_0_0_0_0 - 0.133333333333337*G0_0_0_0_0_1 + 0.133333333333333*G0_0_0_1_0_0 + 1.33333333333334*G0_0_0_2_0_1 - 1.2*G0_0_0_3_0_0 - 0.6*G0_0_0_3_0_1 + 3.60000000000001*G0_0_0_4_0_0 + 1.8*G0_0_0_4_0_1 - 1.19999999999999*G0_0_0_5_0_0 - 0.599999999999986*G0_0_0_5_0_1 - 3.60000000000001*G0_0_0_6_0_0 - 0.600000000000015*G0_0_0_6_0_1 - 0.599999999999997*G0_0_0_7_0_1 + 0.6*G0_0_0_8_0_1 + 2.39999999999999*G0_0_0_9_0_0 - 1.20000000000001*G0_0_0_9_0_1 - 0.133333333333337*G0_0_0_10_1_0 - 0.133333333333337*G0_0_0_10_1_1 + 0.133333333333333*G0_0_0_11_1_0 + 1.33333333333334*G0_0_0_12_1_1 - 1.2*G0_0_0_13_1_0 - 0.6*G0_0_0_13_1_1 + 3.60000000000001*G0_0_0_14_1_0 + 1.8*G0_0_0_14_1_1 - 1.19999999999999*G0_0_0_15_1_0 - 0.599999999999986*G0_0_0_15_1_1 - 3.60000000000001*G0_0_0_16_1_0 - 0.600000000000015*G0_0_0_16_1_1 - 0.599999999999997*G0_0_0_17_1_1 + 0.6*G0_0_0_18_1_1 + 2.39999999999999*G0_0_0_19_1_0 - 1.20000000000001*G0_0_0_19_1_1 - 1.20000000000001*G0_0_1_1_0_0 - 0.600000000000006*G0_0_1_3_0_0 - 2.40000000000001*G0_0_1_3_0_1 + 0.600000000000001*G0_0_1_4_0_0 + 1.2*G0_0_1_4_0_1 - 0.599999999999998*G0_0_1_5_0_0 - 0.600000000000001*G0_0_1_6_0_0 - 0.600000000000008*G0_0_1_7_0_0 - 1.20000000000001*G0_0_1_7_0_1 + 1.80000000000001*G0_0_1_8_0_0 + 2.40000000000001*G0_0_1_8_0_1 + 1.2*G0_0_1_9_0_0 - 1.20000000000001*G0_0_1_11_1_0 - 0.600000000000006*G0_0_1_13_1_0 - 2.40000000000001*G0_0_1_13_1_1 + 0.600000000000001*G0_0_1_14_1_0 + 1.2*G0_0_1_14_1_1 - 0.599999999999998*G0_0_1_15_1_0 - 0.600000000000001*G0_0_1_16_1_0 - 0.600000000000008*G0_0_1_17_1_0 - 1.20000000000001*G0_0_1_17_1_1 + 1.80000000000001*G0_0_1_18_1_0 + 2.40000000000001*G0_0_1_18_1_1 + 1.2*G0_0_1_19_1_0; + A[143] = -A[141] - 1.33333333333333*G0_0_0_0_0_0 - 1.33333333333333*G0_0_0_0_0_1 + 1.33333333333334*G0_0_0_1_0_0 + 0.13333333333333*G0_0_0_2_0_1 + 1.80000000000001*G0_0_0_3_0_1 - 0.600000000000003*G0_0_0_4_0_1 - 2.4*G0_0_0_5_0_0 + 0.599999999999993*G0_0_0_5_0_1 + 0.600000000000008*G0_0_0_6_0_1 + 2.4*G0_0_0_7_0_0 - 0.599999999999991*G0_0_0_7_0_1 - 2.40000000000001*G0_0_0_8_0_0 - 1.80000000000001*G0_0_0_8_0_1 + 2.4*G0_0_0_9_0_0 + 1.19999999999999*G0_0_0_9_0_1 - 1.33333333333333*G0_0_0_10_1_0 - 1.33333333333333*G0_0_0_10_1_1 + 1.33333333333334*G0_0_0_11_1_0 + 0.13333333333333*G0_0_0_12_1_1 + 1.80000000000001*G0_0_0_13_1_1 - 0.600000000000003*G0_0_0_14_1_1 - 2.4*G0_0_0_15_1_0 + 0.599999999999993*G0_0_0_15_1_1 + 0.600000000000008*G0_0_0_16_1_1 + 2.4*G0_0_0_17_1_0 - 0.599999999999991*G0_0_0_17_1_1 - 2.40000000000001*G0_0_0_18_1_0 - 1.80000000000001*G0_0_0_18_1_1 + 2.4*G0_0_0_19_1_0 + 1.19999999999999*G0_0_0_19_1_1 + 1.20000000000001*G0_1_0_1_0_0 + 0.600000000000006*G0_1_0_3_0_0 + 2.40000000000001*G0_1_0_3_0_1 - 0.600000000000002*G0_1_0_4_0_0 - 1.2*G0_1_0_4_0_1 + 0.599999999999998*G0_1_0_5_0_0 + 0.600000000000002*G0_1_0_6_0_0 + 0.600000000000008*G0_1_0_7_0_0 + 1.20000000000001*G0_1_0_7_0_1 - 1.80000000000001*G0_1_0_8_0_0 - 2.40000000000001*G0_1_0_8_0_1 - 1.2*G0_1_0_9_0_0 + 1.20000000000001*G0_1_0_11_1_0 + 0.600000000000006*G0_1_0_13_1_0 + 2.40000000000001*G0_1_0_13_1_1 - 0.600000000000002*G0_1_0_14_1_0 - 1.2*G0_1_0_14_1_1 + 0.599999999999998*G0_1_0_15_1_0 + 0.600000000000002*G0_1_0_16_1_0 + 0.600000000000008*G0_1_0_17_1_0 + 1.20000000000001*G0_1_0_17_1_1 - 1.80000000000001*G0_1_0_18_1_0 - 2.40000000000001*G0_1_0_18_1_1 - 1.2*G0_1_0_19_1_0; + A[65] = A[143]; + A[5] = A[83]; + A[12] = A[90]; + A[8] = 0.0; + A[59] = 0.0; + A[41] = A[141] + 1.20000000000001*G0_0_1_1_0_0 + 0.600000000000005*G0_0_1_3_0_0 + 2.40000000000001*G0_0_1_3_0_1 - 0.600000000000002*G0_0_1_4_0_0 - 1.2*G0_0_1_4_0_1 + 0.599999999999997*G0_0_1_5_0_0 + 0.600000000000002*G0_0_1_6_0_0 + 0.600000000000008*G0_0_1_7_0_0 + 1.20000000000001*G0_0_1_7_0_1 - 1.80000000000001*G0_0_1_8_0_0 - 2.40000000000001*G0_0_1_8_0_1 - 1.2*G0_0_1_9_0_0 + 1.20000000000001*G0_0_1_11_1_0 + 0.600000000000005*G0_0_1_13_1_0 + 2.40000000000001*G0_0_1_13_1_1 - 0.600000000000002*G0_0_1_14_1_0 - 1.2*G0_0_1_14_1_1 + 0.599999999999997*G0_0_1_15_1_0 + 0.600000000000002*G0_0_1_16_1_0 + 0.600000000000008*G0_0_1_17_1_0 + 1.20000000000001*G0_0_1_17_1_1 - 1.80000000000001*G0_0_1_18_1_0 - 2.40000000000001*G0_0_1_18_1_1 - 1.2*G0_0_1_19_1_0 - 1.20000000000001*G0_1_0_1_0_0 - 0.600000000000005*G0_1_0_3_0_0 - 2.40000000000001*G0_1_0_3_0_1 + 0.600000000000002*G0_1_0_4_0_0 + 1.2*G0_1_0_4_0_1 - 0.599999999999997*G0_1_0_5_0_0 - 0.600000000000002*G0_1_0_6_0_0 - 0.600000000000008*G0_1_0_7_0_0 - 1.20000000000001*G0_1_0_7_0_1 + 1.80000000000001*G0_1_0_8_0_0 + 2.40000000000001*G0_1_0_8_0_1 + 1.2*G0_1_0_9_0_0 - 1.20000000000001*G0_1_0_11_1_0 - 0.600000000000005*G0_1_0_13_1_0 - 2.40000000000001*G0_1_0_13_1_1 + 0.600000000000002*G0_1_0_14_1_0 + 1.2*G0_1_0_14_1_1 - 0.599999999999997*G0_1_0_15_1_0 - 0.600000000000002*G0_1_0_16_1_0 - 0.600000000000008*G0_1_0_17_1_0 - 1.20000000000001*G0_1_0_17_1_1 + 1.80000000000001*G0_1_0_18_1_0 + 2.40000000000001*G0_1_0_18_1_1 + 1.2*G0_1_0_19_1_0; + A[31] = 0.0; + A[99] = 0.0; + A[70] = 0.0; + A[54] = 0.0; + A[130] = -A[129] + 1.20000000000001*G0_0_1_2_0_1 - 1.2*G0_0_1_3_0_0 - 0.6*G0_0_1_3_0_1 + 2.40000000000001*G0_0_1_4_0_0 + 0.600000000000006*G0_0_1_4_0_1 + 1.20000000000001*G0_0_1_5_0_0 + 0.60000000000001*G0_0_1_5_0_1 - 2.40000000000001*G0_0_1_6_0_0 - 1.80000000000002*G0_0_1_6_0_1 + 0.599999999999998*G0_0_1_7_0_1 + 0.6*G0_0_1_8_0_1 - 1.2*G0_0_1_9_0_1 + 1.20000000000001*G0_0_1_12_1_1 - 1.2*G0_0_1_13_1_0 - 0.6*G0_0_1_13_1_1 + 2.40000000000001*G0_0_1_14_1_0 + 0.600000000000006*G0_0_1_14_1_1 + 1.20000000000001*G0_0_1_15_1_0 + 0.60000000000001*G0_0_1_15_1_1 - 2.40000000000001*G0_0_1_16_1_0 - 1.80000000000002*G0_0_1_16_1_1 + 0.599999999999998*G0_0_1_17_1_1 + 0.6*G0_0_1_18_1_1 - 1.2*G0_0_1_19_1_1 - 1.33333333333333*G0_1_1_0_0_0 - 1.33333333333333*G0_1_1_0_0_1 + 0.133333333333332*G0_1_1_1_0_0 + 1.33333333333334*G0_1_1_2_0_1 - 0.600000000000003*G0_1_1_3_0_0 + 1.80000000000001*G0_1_1_4_0_0 - 0.599999999999991*G0_1_1_5_0_0 + 2.4*G0_1_1_5_0_1 - 1.80000000000001*G0_1_1_6_0_0 - 2.40000000000001*G0_1_1_6_0_1 + 0.599999999999994*G0_1_1_7_0_0 - 2.4*G0_1_1_7_0_1 + 0.600000000000007*G0_1_1_8_0_0 + 1.19999999999999*G0_1_1_9_0_0 + 2.4*G0_1_1_9_0_1 - 1.33333333333333*G0_1_1_10_1_0 - 1.33333333333333*G0_1_1_10_1_1 + 0.133333333333332*G0_1_1_11_1_0 + 1.33333333333334*G0_1_1_12_1_1 - 0.600000000000003*G0_1_1_13_1_0 + 1.80000000000001*G0_1_1_14_1_0 - 0.599999999999991*G0_1_1_15_1_0 + 2.4*G0_1_1_15_1_1 - 1.80000000000001*G0_1_1_16_1_0 - 2.40000000000001*G0_1_1_16_1_1 + 0.599999999999994*G0_1_1_17_1_0 - 2.4*G0_1_1_17_1_1 + 0.600000000000007*G0_1_1_18_1_0 + 1.19999999999999*G0_1_1_19_1_0 + 2.4*G0_1_1_19_1_1; + A[110] = 0.0; + A[73] = 0.0; + A[67] = 0.0; + A[135] = 0.0; + A[88] = 0.0; + A[2] = A[92] - 0.183333333333334*G0_0_1_0_0_0 - 0.183333333333334*G0_0_1_0_0_1 + 0.183333333333333*G0_0_1_1_0_0 + 0.483333333333336*G0_0_1_2_0_1 - 0.150000000000001*G0_0_1_3_0_0 + 0.3*G0_0_1_3_0_1 + 0.750000000000006*G0_0_1_4_0_0 + 0.150000000000004*G0_0_1_5_0_0 + 0.450000000000004*G0_0_1_5_0_1 - 0.750000000000006*G0_0_1_6_0_0 - 0.750000000000006*G0_0_1_6_0_1 - 0.299999999999999*G0_0_1_7_0_1 - 0.3*G0_0_1_8_0_1 + 0.299999999999996*G0_0_1_9_0_1 - 0.183333333333334*G0_0_1_10_1_0 - 0.183333333333334*G0_0_1_10_1_1 + 0.183333333333333*G0_0_1_11_1_0 + 0.483333333333336*G0_0_1_12_1_1 - 0.150000000000001*G0_0_1_13_1_0 + 0.3*G0_0_1_13_1_1 + 0.750000000000006*G0_0_1_14_1_0 + 0.150000000000004*G0_0_1_15_1_0 + 0.450000000000004*G0_0_1_15_1_1 - 0.750000000000006*G0_0_1_16_1_0 - 0.750000000000006*G0_0_1_16_1_1 - 0.299999999999999*G0_0_1_17_1_1 - 0.3*G0_0_1_18_1_1 + 0.299999999999996*G0_0_1_19_1_1 - 0.241666666666667*G0_1_1_0_0_0 - 0.241666666666667*G0_1_1_0_0_1 - 0.0583333333333338*G0_1_1_1_0_0 + 0.241666666666669*G0_1_1_2_0_1 + 0.0749999999999992*G0_1_1_3_0_0 - 0.0750000000000007*G0_1_1_3_0_1 + 0.375000000000004*G0_1_1_4_0_0 + 0.225000000000002*G0_1_1_4_0_1 + 0.225000000000002*G0_1_1_5_0_0 + 0.600000000000001*G0_1_1_5_0_1 - 0.375000000000004*G0_1_1_6_0_0 - 0.600000000000003*G0_1_1_6_0_1 + 0.149999999999999*G0_1_1_7_0_0 - 0.225*G0_1_1_7_0_1 + 0.150000000000002*G0_1_1_8_0_0 + 0.0750000000000006*G0_1_1_8_0_1 - 0.300000000000001*G0_1_1_9_0_0 - 0.241666666666667*G0_1_1_10_1_0 - 0.241666666666667*G0_1_1_10_1_1 - 0.0583333333333338*G0_1_1_11_1_0 + 0.241666666666669*G0_1_1_12_1_1 + 0.0749999999999992*G0_1_1_13_1_0 - 0.0750000000000007*G0_1_1_13_1_1 + 0.375000000000004*G0_1_1_14_1_0 + 0.225000000000002*G0_1_1_14_1_1 + 0.225000000000002*G0_1_1_15_1_0 + 0.600000000000001*G0_1_1_15_1_1 - 0.375000000000004*G0_1_1_16_1_0 - 0.600000000000003*G0_1_1_16_1_1 + 0.149999999999999*G0_1_1_17_1_0 - 0.225*G0_1_1_17_1_1 + 0.150000000000002*G0_1_1_18_1_0 + 0.0750000000000006*G0_1_1_18_1_1 - 0.300000000000001*G0_1_1_19_1_0; + A[15] = -0.3*G0_0_0_2_0_1 + 0.9*G0_0_0_3_0_0 + 0.45*G0_0_0_3_0_1 - 0.6*G0_0_0_4_0_0 + 0.15*G0_0_0_4_0_1 + 0.299999999999999*G0_0_0_5_0_0 + 0.149999999999998*G0_0_0_5_0_1 + 0.600000000000001*G0_0_0_6_0_0 + 0.150000000000002*G0_0_0_6_0_1 + 0.150000000000001*G0_0_0_7_0_1 - 0.45*G0_0_0_8_0_1 - 1.2*G0_0_0_9_0_0 - 0.3*G0_0_0_9_0_1 - 0.3*G0_0_0_12_1_1 + 0.9*G0_0_0_13_1_0 + 0.45*G0_0_0_13_1_1 - 0.6*G0_0_0_14_1_0 + 0.15*G0_0_0_14_1_1 + 0.299999999999999*G0_0_0_15_1_0 + 0.149999999999998*G0_0_0_15_1_1 + 0.600000000000001*G0_0_0_16_1_0 + 0.150000000000002*G0_0_0_16_1_1 + 0.150000000000001*G0_0_0_17_1_1 - 0.45*G0_0_0_18_1_1 - 1.2*G0_0_0_19_1_0 - 0.3*G0_0_0_19_1_1 - 0.0666666666666694*G0_0_1_0_0_0 - 0.0666666666666691*G0_0_1_0_0_1 + 0.966666666666672*G0_0_1_1_0_0 + 0.0666666666666659*G0_0_1_2_0_1 + 1.35*G0_0_1_3_0_0 + 2.40000000000001*G0_0_1_3_0_1 - 0.15*G0_0_1_4_0_0 - 0.299999999999999*G0_0_1_4_0_1 + 0.150000000000001*G0_0_1_5_0_0 + 0.150000000000001*G0_0_1_6_0_0 + 0.150000000000009*G0_0_1_7_0_0 + 0.300000000000009*G0_0_1_7_0_1 - 1.05000000000001*G0_0_1_8_0_0 - 2.40000000000001*G0_0_1_8_0_1 - 1.5*G0_0_1_9_0_0 - 0.0666666666666694*G0_0_1_10_1_0 - 0.0666666666666691*G0_0_1_10_1_1 + 0.966666666666672*G0_0_1_11_1_0 + 0.0666666666666659*G0_0_1_12_1_1 + 1.35*G0_0_1_13_1_0 + 2.40000000000001*G0_0_1_13_1_1 - 0.15*G0_0_1_14_1_0 - 0.299999999999999*G0_0_1_14_1_1 + 0.150000000000001*G0_0_1_15_1_0 + 0.150000000000001*G0_0_1_16_1_0 + 0.150000000000009*G0_0_1_17_1_0 + 0.300000000000009*G0_0_1_17_1_1 - 1.05000000000001*G0_0_1_18_1_0 - 2.40000000000001*G0_0_1_18_1_1 - 1.5*G0_0_1_19_1_0; + A[17] = -A[15] + 0.366666666666668*G0_0_0_0_0_0 + 0.366666666666668*G0_0_0_0_0_1 - 0.966666666666671*G0_0_0_1_0_0 - 0.366666666666666*G0_0_0_2_0_1 - 1.50000000000001*G0_0_0_3_0_1 - 0.6*G0_0_0_4_0_0 + 0.3*G0_0_0_4_0_1 + 0.599999999999999*G0_0_0_5_0_0 + 0.6*G0_0_0_6_0_0 - 0.900000000000006*G0_0_0_7_0_0 - 0.300000000000007*G0_0_0_7_0_1 + 1.50000000000001*G0_0_0_8_0_0 + 1.50000000000001*G0_0_0_8_0_1 - 0.599999999999995*G0_0_0_9_0_0 + 0.366666666666668*G0_0_0_10_1_0 + 0.366666666666668*G0_0_0_10_1_1 - 0.966666666666671*G0_0_0_11_1_0 - 0.366666666666666*G0_0_0_12_1_1 - 1.50000000000001*G0_0_0_13_1_1 - 0.6*G0_0_0_14_1_0 + 0.3*G0_0_0_14_1_1 + 0.599999999999999*G0_0_0_15_1_0 + 0.6*G0_0_0_16_1_0 - 0.900000000000006*G0_0_0_17_1_0 - 0.300000000000007*G0_0_0_17_1_1 + 1.50000000000001*G0_0_0_18_1_0 + 1.50000000000001*G0_0_0_18_1_1 - 0.599999999999995*G0_0_0_19_1_0; + A[56] = 0.0; + A[36] = A[81] - 0.300000000000002*G0_0_1_1_0_0 + 0.300000000000003*G0_0_1_2_0_1 - 0.150000000000002*G0_0_1_3_0_0 - 0.450000000000004*G0_0_1_3_0_1 + 0.450000000000005*G0_0_1_4_0_0 + 0.150000000000002*G0_0_1_4_0_1 + 0.450000000000003*G0_0_1_5_0_0 + 0.450000000000003*G0_0_1_5_0_1 - 0.450000000000005*G0_0_1_6_0_0 - 0.750000000000006*G0_0_1_6_0_1 - 0.450000000000002*G0_0_1_7_0_0 - 0.450000000000002*G0_0_1_7_0_1 + 0.750000000000004*G0_0_1_8_0_0 + 0.450000000000004*G0_0_1_8_0_1 - 0.3*G0_0_1_9_0_0 + 0.3*G0_0_1_9_0_1 - 0.300000000000002*G0_0_1_11_1_0 + 0.300000000000003*G0_0_1_12_1_1 - 0.150000000000002*G0_0_1_13_1_0 - 0.450000000000004*G0_0_1_13_1_1 + 0.450000000000005*G0_0_1_14_1_0 + 0.150000000000002*G0_0_1_14_1_1 + 0.450000000000003*G0_0_1_15_1_0 + 0.450000000000003*G0_0_1_15_1_1 - 0.450000000000005*G0_0_1_16_1_0 - 0.750000000000006*G0_0_1_16_1_1 - 0.450000000000002*G0_0_1_17_1_0 - 0.450000000000002*G0_0_1_17_1_1 + 0.750000000000004*G0_0_1_18_1_0 + 0.450000000000004*G0_0_1_18_1_1 - 0.3*G0_0_1_19_1_0 + 0.3*G0_0_1_19_1_1 + 0.300000000000002*G0_1_0_1_0_0 - 0.300000000000003*G0_1_0_2_0_1 + 0.150000000000002*G0_1_0_3_0_0 + 0.450000000000003*G0_1_0_3_0_1 - 0.450000000000005*G0_1_0_4_0_0 - 0.150000000000002*G0_1_0_4_0_1 - 0.450000000000003*G0_1_0_5_0_0 - 0.450000000000003*G0_1_0_5_0_1 + 0.450000000000005*G0_1_0_6_0_0 + 0.750000000000006*G0_1_0_6_0_1 + 0.450000000000002*G0_1_0_7_0_0 + 0.450000000000002*G0_1_0_7_0_1 - 0.750000000000004*G0_1_0_8_0_0 - 0.450000000000004*G0_1_0_8_0_1 + 0.3*G0_1_0_9_0_0 - 0.3*G0_1_0_9_0_1 + 0.300000000000002*G0_1_0_11_1_0 - 0.300000000000003*G0_1_0_12_1_1 + 0.150000000000002*G0_1_0_13_1_0 + 0.450000000000003*G0_1_0_13_1_1 - 0.450000000000005*G0_1_0_14_1_0 - 0.150000000000002*G0_1_0_14_1_1 - 0.450000000000003*G0_1_0_15_1_0 - 0.450000000000003*G0_1_0_15_1_1 + 0.450000000000005*G0_1_0_16_1_0 + 0.750000000000006*G0_1_0_16_1_1 + 0.450000000000002*G0_1_0_17_1_0 + 0.450000000000002*G0_1_0_17_1_1 - 0.750000000000004*G0_1_0_18_1_0 - 0.450000000000004*G0_1_0_18_1_1 + 0.3*G0_1_0_19_1_0 - 0.3*G0_1_0_19_1_1; + A[48] = -A[36] + 0.966666666666664*G0_1_0_0_0_0 + 0.966666666666664*G0_1_0_0_0_1 + 0.233333333333336*G0_1_0_1_0_0 - 0.366666666666669*G0_1_0_2_0_1 + 0.300000000000003*G0_1_0_3_0_0 + 0.600000000000003*G0_1_0_3_0_1 - 0.300000000000005*G0_1_0_4_0_0 + 0.899999999999998*G0_1_0_5_0_0 - 1.5*G0_1_0_5_0_1 + 0.300000000000005*G0_1_0_6_0_0 + 0.900000000000003*G0_1_0_6_0_1 - 0.599999999999993*G0_1_0_7_0_0 + 1.8*G0_1_0_7_0_1 - 0.600000000000007*G0_1_0_8_0_0 - 0.600000000000003*G0_1_0_8_0_1 - 1.2*G0_1_0_9_0_0 - 1.8*G0_1_0_9_0_1 + 0.966666666666664*G0_1_0_10_1_0 + 0.966666666666664*G0_1_0_10_1_1 + 0.233333333333336*G0_1_0_11_1_0 - 0.366666666666669*G0_1_0_12_1_1 + 0.300000000000003*G0_1_0_13_1_0 + 0.600000000000003*G0_1_0_13_1_1 - 0.300000000000005*G0_1_0_14_1_0 + 0.899999999999998*G0_1_0_15_1_0 - 1.5*G0_1_0_15_1_1 + 0.300000000000005*G0_1_0_16_1_0 + 0.900000000000003*G0_1_0_16_1_1 - 0.599999999999993*G0_1_0_17_1_0 + 1.8*G0_1_0_17_1_1 - 0.600000000000007*G0_1_0_18_1_0 - 0.600000000000003*G0_1_0_18_1_1 - 1.2*G0_1_0_19_1_0 - 1.8*G0_1_0_19_1_1 + 0.966666666666664*G0_1_1_0_0_0 + 0.966666666666664*G0_1_1_0_0_1 + 0.233333333333336*G0_1_1_1_0_0 - 0.366666666666669*G0_1_1_2_0_1 + 0.300000000000004*G0_1_1_3_0_0 + 0.600000000000003*G0_1_1_3_0_1 - 0.300000000000005*G0_1_1_4_0_0 + 0.899999999999998*G0_1_1_5_0_0 - 1.5*G0_1_1_5_0_1 + 0.300000000000005*G0_1_1_6_0_0 + 0.900000000000003*G0_1_1_6_0_1 - 0.599999999999993*G0_1_1_7_0_0 + 1.8*G0_1_1_7_0_1 - 0.600000000000007*G0_1_1_8_0_0 - 0.600000000000004*G0_1_1_8_0_1 - 1.2*G0_1_1_9_0_0 - 1.8*G0_1_1_9_0_1 + 0.966666666666664*G0_1_1_10_1_0 + 0.966666666666664*G0_1_1_10_1_1 + 0.233333333333336*G0_1_1_11_1_0 - 0.366666666666669*G0_1_1_12_1_1 + 0.300000000000004*G0_1_1_13_1_0 + 0.600000000000003*G0_1_1_13_1_1 - 0.300000000000005*G0_1_1_14_1_0 + 0.899999999999998*G0_1_1_15_1_0 - 1.5*G0_1_1_15_1_1 + 0.300000000000005*G0_1_1_16_1_0 + 0.900000000000003*G0_1_1_16_1_1 - 0.599999999999993*G0_1_1_17_1_0 + 1.8*G0_1_1_17_1_1 - 0.600000000000007*G0_1_1_18_1_0 - 0.600000000000004*G0_1_1_18_1_1 - 1.2*G0_1_1_19_1_0 - 1.8*G0_1_1_19_1_1; + A[32] = 0.0; + A[116] = A[38]; + A[96] = 0.0; + A[74] = 0.0; + A[95] = A[17]; + A[46] = 0.0; + A[106] = -A[105] + 0.366666666666668*G0_1_1_0_0_0 + 0.366666666666668*G0_1_1_0_0_1 - 0.366666666666667*G0_1_1_1_0_0 - 0.966666666666671*G0_1_1_2_0_1 + 0.3*G0_1_1_3_0_0 - 0.6*G0_1_1_3_0_1 - 1.50000000000001*G0_1_1_4_0_0 - 0.300000000000008*G0_1_1_5_0_0 - 0.900000000000007*G0_1_1_5_0_1 + 1.50000000000001*G0_1_1_6_0_0 + 1.50000000000001*G0_1_1_6_0_1 + 0.599999999999997*G0_1_1_7_0_1 + 0.6*G0_1_1_8_0_1 - 0.599999999999993*G0_1_1_9_0_1 + 0.366666666666668*G0_1_1_10_1_0 + 0.366666666666668*G0_1_1_10_1_1 - 0.366666666666667*G0_1_1_11_1_0 - 0.966666666666671*G0_1_1_12_1_1 + 0.3*G0_1_1_13_1_0 - 0.6*G0_1_1_13_1_1 - 1.50000000000001*G0_1_1_14_1_0 - 0.300000000000008*G0_1_1_15_1_0 - 0.900000000000007*G0_1_1_15_1_1 + 1.50000000000001*G0_1_1_16_1_0 + 1.50000000000001*G0_1_1_16_1_1 + 0.599999999999997*G0_1_1_17_1_1 + 0.6*G0_1_1_18_1_1 - 0.599999999999993*G0_1_1_19_1_1; + A[119] = A[41]; + A[60] = -A[36] + 0.966666666666664*G0_0_0_0_0_0 + 0.966666666666664*G0_0_0_0_0_1 - 0.366666666666668*G0_0_0_1_0_0 + 0.233333333333337*G0_0_0_2_0_1 - 0.300000000000005*G0_0_0_3_0_1 + 0.600000000000006*G0_0_0_4_0_0 + 0.300000000000004*G0_0_0_4_0_1 + 1.8*G0_0_0_5_0_0 - 0.599999999999993*G0_0_0_5_0_1 - 0.600000000000006*G0_0_0_6_0_0 - 0.600000000000008*G0_0_0_6_0_1 - 1.5*G0_0_0_7_0_0 + 0.899999999999998*G0_0_0_7_0_1 + 0.900000000000002*G0_0_0_8_0_0 + 0.300000000000004*G0_0_0_8_0_1 - 1.8*G0_0_0_9_0_0 - 1.2*G0_0_0_9_0_1 + 0.966666666666664*G0_0_0_10_1_0 + 0.966666666666664*G0_0_0_10_1_1 - 0.366666666666668*G0_0_0_11_1_0 + 0.233333333333337*G0_0_0_12_1_1 - 0.300000000000005*G0_0_0_13_1_1 + 0.600000000000006*G0_0_0_14_1_0 + 0.300000000000004*G0_0_0_14_1_1 + 1.8*G0_0_0_15_1_0 - 0.599999999999993*G0_0_0_15_1_1 - 0.600000000000006*G0_0_0_16_1_0 - 0.600000000000008*G0_0_0_16_1_1 - 1.5*G0_0_0_17_1_0 + 0.899999999999998*G0_0_0_17_1_1 + 0.900000000000002*G0_0_0_18_1_0 + 0.300000000000004*G0_0_0_18_1_1 - 1.8*G0_0_0_19_1_0 - 1.2*G0_0_0_19_1_1 + 0.966666666666664*G0_0_1_0_0_0 + 0.966666666666664*G0_0_1_0_0_1 - 0.366666666666669*G0_0_1_1_0_0 + 0.233333333333337*G0_0_1_2_0_1 - 0.300000000000005*G0_0_1_3_0_1 + 0.600000000000005*G0_0_1_4_0_0 + 0.300000000000004*G0_0_1_4_0_1 + 1.8*G0_0_1_5_0_0 - 0.599999999999993*G0_0_1_5_0_1 - 0.600000000000005*G0_0_1_6_0_0 - 0.600000000000008*G0_0_1_6_0_1 - 1.5*G0_0_1_7_0_0 + 0.899999999999998*G0_0_1_7_0_1 + 0.900000000000002*G0_0_1_8_0_0 + 0.300000000000005*G0_0_1_8_0_1 - 1.8*G0_0_1_9_0_0 - 1.2*G0_0_1_9_0_1 + 0.966666666666664*G0_0_1_10_1_0 + 0.966666666666664*G0_0_1_10_1_1 - 0.366666666666669*G0_0_1_11_1_0 + 0.233333333333337*G0_0_1_12_1_1 - 0.300000000000005*G0_0_1_13_1_1 + 0.600000000000005*G0_0_1_14_1_0 + 0.300000000000004*G0_0_1_14_1_1 + 1.8*G0_0_1_15_1_0 - 0.599999999999993*G0_0_1_15_1_1 - 0.600000000000005*G0_0_1_16_1_0 - 0.600000000000008*G0_0_1_16_1_1 - 1.5*G0_0_1_17_1_0 + 0.899999999999998*G0_0_1_17_1_1 + 0.900000000000002*G0_0_1_18_1_0 + 0.300000000000005*G0_0_1_18_1_1 - 1.8*G0_0_1_19_1_0 - 1.2*G0_0_1_19_1_1; + A[120] = 0.0; + A[16] = -A[15] + 0.233333333333329*G0_0_1_0_0_0 + 0.23333333333333*G0_0_1_0_0_1 + 0.966666666666671*G0_0_1_1_0_0 + 0.366666666666667*G0_0_1_2_0_1 + 0.900000000000002*G0_0_1_3_0_0 + 2.4*G0_0_1_3_0_1 + 0.300000000000002*G0_0_1_4_0_0 - 0.599999999999998*G0_0_1_4_0_1 + 0.300000000000003*G0_0_1_5_0_0 - 0.299999999999994*G0_0_1_5_0_1 - 0.300000000000002*G0_0_1_6_0_0 - 0.300000000000003*G0_0_1_6_0_1 - 0.599999999999989*G0_0_1_7_0_0 - 0.60000000000001*G0_0_1_8_0_0 - 2.40000000000001*G0_0_1_8_0_1 - 1.20000000000001*G0_0_1_9_0_0 + 0.599999999999991*G0_0_1_9_0_1 + 0.233333333333329*G0_0_1_10_1_0 + 0.23333333333333*G0_0_1_10_1_1 + 0.966666666666671*G0_0_1_11_1_0 + 0.366666666666667*G0_0_1_12_1_1 + 0.900000000000002*G0_0_1_13_1_0 + 2.4*G0_0_1_13_1_1 + 0.300000000000002*G0_0_1_14_1_0 - 0.599999999999998*G0_0_1_14_1_1 + 0.300000000000003*G0_0_1_15_1_0 - 0.299999999999994*G0_0_1_15_1_1 - 0.300000000000002*G0_0_1_16_1_0 - 0.300000000000003*G0_0_1_16_1_1 - 0.599999999999989*G0_0_1_17_1_0 - 0.60000000000001*G0_0_1_18_1_0 - 2.40000000000001*G0_0_1_18_1_1 - 1.20000000000001*G0_0_1_19_1_0 + 0.599999999999991*G0_0_1_19_1_1; + A[45] = 0.0; + A[27] = A[105]; + A[21] = 0.0; + A[103] = A[25]; + A[50] = A[128]; + A[114] = A[36]; + A[77] = 0.0; + A[63] = A[141]; + A[139] = A[61]; + A[125] = 0.0; + A[84] = 0.0; + A[80] = A[2]; + A[140] = -A[38] + 0.233333333333329*G0_0_1_0_0_0 + 0.233333333333329*G0_0_1_0_0_1 + 0.366666666666668*G0_0_1_1_0_0 + 0.966666666666671*G0_0_1_2_0_1 - 0.6*G0_0_1_3_0_0 + 0.300000000000001*G0_0_1_3_0_1 + 2.40000000000001*G0_0_1_4_0_0 + 0.900000000000003*G0_0_1_4_0_1 - 0.599999999999988*G0_0_1_5_0_1 - 2.40000000000001*G0_0_1_6_0_0 - 0.600000000000012*G0_0_1_6_0_1 - 0.299999999999994*G0_0_1_7_0_0 + 0.300000000000004*G0_0_1_7_0_1 - 0.300000000000003*G0_0_1_8_0_0 - 0.300000000000001*G0_0_1_8_0_1 + 0.599999999999991*G0_0_1_9_0_0 - 1.20000000000001*G0_0_1_9_0_1 + 0.233333333333329*G0_0_1_10_1_0 + 0.233333333333329*G0_0_1_10_1_1 + 0.366666666666668*G0_0_1_11_1_0 + 0.966666666666671*G0_0_1_12_1_1 - 0.6*G0_0_1_13_1_0 + 0.300000000000001*G0_0_1_13_1_1 + 2.40000000000001*G0_0_1_14_1_0 + 0.900000000000003*G0_0_1_14_1_1 - 0.599999999999988*G0_0_1_15_1_1 - 2.40000000000001*G0_0_1_16_1_0 - 0.600000000000012*G0_0_1_16_1_1 - 0.299999999999994*G0_0_1_17_1_0 + 0.300000000000004*G0_0_1_17_1_1 - 0.300000000000003*G0_0_1_18_1_0 - 0.300000000000001*G0_0_1_18_1_1 + 0.599999999999991*G0_0_1_19_1_0 - 1.20000000000001*G0_0_1_19_1_1; + A[6] = 0.0; + A[19] = 0.0; + A[9] = 0.0; + A[40] = A[129] - 1.20000000000001*G0_0_1_2_0_1 + 1.2*G0_0_1_3_0_0 + 0.6*G0_0_1_3_0_1 - 2.40000000000001*G0_0_1_4_0_0 - 0.600000000000006*G0_0_1_4_0_1 - 1.20000000000001*G0_0_1_5_0_0 - 0.60000000000001*G0_0_1_5_0_1 + 2.40000000000001*G0_0_1_6_0_0 + 1.80000000000002*G0_0_1_6_0_1 - 0.599999999999998*G0_0_1_7_0_1 - 0.6*G0_0_1_8_0_1 + 1.2*G0_0_1_9_0_1 - 1.20000000000001*G0_0_1_12_1_1 + 1.2*G0_0_1_13_1_0 + 0.6*G0_0_1_13_1_1 - 2.40000000000001*G0_0_1_14_1_0 - 0.600000000000006*G0_0_1_14_1_1 - 1.20000000000001*G0_0_1_15_1_0 - 0.60000000000001*G0_0_1_15_1_1 + 2.40000000000001*G0_0_1_16_1_0 + 1.80000000000002*G0_0_1_16_1_1 - 0.599999999999998*G0_0_1_17_1_1 - 0.6*G0_0_1_18_1_1 + 1.2*G0_0_1_19_1_1 + 1.20000000000001*G0_1_0_2_0_1 - 1.2*G0_1_0_3_0_0 - 0.6*G0_1_0_3_0_1 + 2.40000000000001*G0_1_0_4_0_0 + 0.600000000000006*G0_1_0_4_0_1 + 1.20000000000001*G0_1_0_5_0_0 + 0.60000000000001*G0_1_0_5_0_1 - 2.40000000000001*G0_1_0_6_0_0 - 1.80000000000002*G0_1_0_6_0_1 + 0.599999999999998*G0_1_0_7_0_1 + 0.6*G0_1_0_8_0_1 - 1.2*G0_1_0_9_0_1 + 1.20000000000001*G0_1_0_12_1_1 - 1.2*G0_1_0_13_1_0 - 0.6*G0_1_0_13_1_1 + 2.40000000000001*G0_1_0_14_1_0 + 0.600000000000006*G0_1_0_14_1_1 + 1.20000000000001*G0_1_0_15_1_0 + 0.60000000000001*G0_1_0_15_1_1 - 2.40000000000001*G0_1_0_16_1_0 - 1.80000000000002*G0_1_0_16_1_1 + 0.599999999999998*G0_1_0_17_1_1 + 0.6*G0_1_0_18_1_1 - 1.2*G0_1_0_19_1_1; + A[142] = -A[40] + 0.133333333333337*G0_0_0_0_0_0 + 0.133333333333337*G0_0_0_0_0_1 - 0.133333333333333*G0_0_0_1_0_0 - 1.33333333333334*G0_0_0_2_0_1 + 1.2*G0_0_0_3_0_0 + 0.6*G0_0_0_3_0_1 - 3.60000000000001*G0_0_0_4_0_0 - 1.8*G0_0_0_4_0_1 + 1.19999999999999*G0_0_0_5_0_0 + 0.599999999999986*G0_0_0_5_0_1 + 3.60000000000001*G0_0_0_6_0_0 + 0.600000000000015*G0_0_0_6_0_1 + 0.599999999999997*G0_0_0_7_0_1 - 0.6*G0_0_0_8_0_1 - 2.39999999999999*G0_0_0_9_0_0 + 1.20000000000001*G0_0_0_9_0_1 + 0.133333333333337*G0_0_0_10_1_0 + 0.133333333333337*G0_0_0_10_1_1 - 0.133333333333333*G0_0_0_11_1_0 - 1.33333333333334*G0_0_0_12_1_1 + 1.2*G0_0_0_13_1_0 + 0.6*G0_0_0_13_1_1 - 3.60000000000001*G0_0_0_14_1_0 - 1.8*G0_0_0_14_1_1 + 1.19999999999999*G0_0_0_15_1_0 + 0.599999999999986*G0_0_0_15_1_1 + 3.60000000000001*G0_0_0_16_1_0 + 0.600000000000015*G0_0_0_16_1_1 + 0.599999999999997*G0_0_0_17_1_1 - 0.6*G0_0_0_18_1_1 - 2.39999999999999*G0_0_0_19_1_0 + 1.20000000000001*G0_0_0_19_1_1 - 1.19999999999999*G0_0_1_0_0_0 - 1.19999999999999*G0_0_1_0_0_1 - 1.20000000000001*G0_0_1_2_0_1 + 0.6*G0_0_1_3_0_0 - 3.00000000000001*G0_0_1_4_0_0 - 1.20000000000001*G0_0_1_4_0_1 - 1.80000000000001*G0_0_1_5_0_0 + 1.19999999999998*G0_0_1_5_0_1 + 3.00000000000001*G0_0_1_6_0_0 + 1.20000000000002*G0_0_1_6_0_1 + 1.79999999999999*G0_0_1_7_0_0 - 1.2*G0_0_1_7_0_1 - 0.599999999999998*G0_0_1_8_0_0 + 1.20000000000001*G0_0_1_9_0_0 + 2.40000000000001*G0_0_1_9_0_1 - 1.19999999999999*G0_0_1_10_1_0 - 1.19999999999999*G0_0_1_10_1_1 - 1.20000000000001*G0_0_1_12_1_1 + 0.6*G0_0_1_13_1_0 - 3.00000000000001*G0_0_1_14_1_0 - 1.20000000000001*G0_0_1_14_1_1 - 1.80000000000001*G0_0_1_15_1_0 + 1.19999999999998*G0_0_1_15_1_1 + 3.00000000000001*G0_0_1_16_1_0 + 1.20000000000002*G0_0_1_16_1_1 + 1.79999999999999*G0_0_1_17_1_0 - 1.2*G0_0_1_17_1_1 - 0.599999999999998*G0_0_1_18_1_0 + 1.20000000000001*G0_0_1_19_1_0 + 2.40000000000001*G0_0_1_19_1_1; + A[64] = A[142]; + A[28] = A[106]; + A[100] = 0.0; + A[69] = 0.0; + A[55] = 0.0; + A[131] = A[53]; + A[109] = 0.0; + A[78] = -A[79] - 0.966666666666665*G0_0_0_0_0_0 - 0.966666666666665*G0_0_0_0_0_1 + 0.366666666666669*G0_0_0_1_0_0 + 0.0666666666666663*G0_0_0_2_0_1 + 0.3*G0_0_0_3_0_0 + 0.450000000000005*G0_0_0_3_0_1 + 0.149999999999999*G0_0_0_4_0_1 - 0.9*G0_0_0_5_0_0 + 1.05*G0_0_0_5_0_1 - 0.149999999999997*G0_0_0_6_0_1 + 1.5*G0_0_0_7_0_0 - 0.449999999999998*G0_0_0_7_0_1 - 0.900000000000002*G0_0_0_8_0_0 - 0.450000000000005*G0_0_0_8_0_1 + 0.6*G0_0_0_9_0_0 + 0.299999999999998*G0_0_0_9_0_1 - 0.966666666666665*G0_0_0_10_1_0 - 0.966666666666665*G0_0_0_10_1_1 + 0.366666666666669*G0_0_0_11_1_0 + 0.0666666666666663*G0_0_0_12_1_1 + 0.3*G0_0_0_13_1_0 + 0.450000000000005*G0_0_0_13_1_1 + 0.149999999999999*G0_0_0_14_1_1 - 0.9*G0_0_0_15_1_0 + 1.05*G0_0_0_15_1_1 - 0.149999999999997*G0_0_0_16_1_1 + 1.5*G0_0_0_17_1_0 - 0.449999999999998*G0_0_0_17_1_1 - 0.900000000000002*G0_0_0_18_1_0 - 0.450000000000005*G0_0_0_18_1_1 + 0.6*G0_0_0_19_1_0 + 0.299999999999998*G0_0_0_19_1_1 - 0.724999999999998*G0_0_1_0_0_0 - 0.724999999999998*G0_0_1_0_0_1 + 0.125*G0_0_1_1_0_0 + 0.125*G0_0_1_2_0_1 + 0.0749999999999997*G0_0_1_3_0_0 + 0.0750000000000018*G0_0_1_3_0_1 + 0.0750000000000014*G0_0_1_4_0_0 + 0.0749999999999997*G0_0_1_4_0_1 - 0.674999999999999*G0_0_1_5_0_0 + 0.899999999999997*G0_0_1_5_0_1 - 0.0750000000000014*G0_0_1_6_0_0 - 0.3*G0_0_1_6_0_1 + 0.899999999999997*G0_0_1_7_0_0 - 0.675*G0_0_1_7_0_1 - 0.3*G0_0_1_8_0_0 - 0.0750000000000017*G0_0_1_8_0_1 + 0.6*G0_0_1_9_0_0 + 0.6*G0_0_1_9_0_1 - 0.724999999999998*G0_0_1_10_1_0 - 0.724999999999998*G0_0_1_10_1_1 + 0.125*G0_0_1_11_1_0 + 0.125*G0_0_1_12_1_1 + 0.0749999999999997*G0_0_1_13_1_0 + 0.0750000000000018*G0_0_1_13_1_1 + 0.0750000000000014*G0_0_1_14_1_0 + 0.0749999999999997*G0_0_1_14_1_1 - 0.674999999999999*G0_0_1_15_1_0 + 0.899999999999997*G0_0_1_15_1_1 - 0.0750000000000014*G0_0_1_16_1_0 - 0.3*G0_0_1_16_1_1 + 0.899999999999997*G0_0_1_17_1_0 - 0.675*G0_0_1_17_1_1 - 0.3*G0_0_1_18_1_0 - 0.0750000000000017*G0_0_1_18_1_1 + 0.6*G0_0_1_19_1_0 + 0.6*G0_0_1_19_1_1 - 0.966666666666665*G0_1_0_0_0_0 - 0.966666666666665*G0_1_0_0_0_1 + 0.366666666666669*G0_1_0_1_0_0 + 0.0666666666666663*G0_1_0_2_0_1 + 0.3*G0_1_0_3_0_0 + 0.450000000000005*G0_1_0_3_0_1 + 0.149999999999999*G0_1_0_4_0_1 - 0.9*G0_1_0_5_0_0 + 1.05*G0_1_0_5_0_1 - 0.149999999999997*G0_1_0_6_0_1 + 1.5*G0_1_0_7_0_0 - 0.449999999999998*G0_1_0_7_0_1 - 0.900000000000002*G0_1_0_8_0_0 - 0.450000000000005*G0_1_0_8_0_1 + 0.6*G0_1_0_9_0_0 + 0.299999999999999*G0_1_0_9_0_1 - 0.966666666666665*G0_1_0_10_1_0 - 0.966666666666665*G0_1_0_10_1_1 + 0.366666666666669*G0_1_0_11_1_0 + 0.0666666666666663*G0_1_0_12_1_1 + 0.3*G0_1_0_13_1_0 + 0.450000000000005*G0_1_0_13_1_1 + 0.149999999999999*G0_1_0_14_1_1 - 0.9*G0_1_0_15_1_0 + 1.05*G0_1_0_15_1_1 - 0.149999999999997*G0_1_0_16_1_1 + 1.5*G0_1_0_17_1_0 - 0.449999999999998*G0_1_0_17_1_1 - 0.900000000000002*G0_1_0_18_1_0 - 0.450000000000005*G0_1_0_18_1_1 + 0.6*G0_1_0_19_1_0 + 0.299999999999999*G0_1_0_19_1_1 - 0.724999999999998*G0_1_1_0_0_0 - 0.724999999999998*G0_1_1_0_0_1 + 0.125*G0_1_1_1_0_0 + 0.125*G0_1_1_2_0_1 + 0.0749999999999997*G0_1_1_3_0_0 + 0.0750000000000019*G0_1_1_3_0_1 + 0.0750000000000014*G0_1_1_4_0_0 + 0.0749999999999997*G0_1_1_4_0_1 - 0.675*G0_1_1_5_0_0 + 0.899999999999997*G0_1_1_5_0_1 - 0.0750000000000014*G0_1_1_6_0_0 - 0.3*G0_1_1_6_0_1 + 0.899999999999997*G0_1_1_7_0_0 - 0.675*G0_1_1_7_0_1 - 0.3*G0_1_1_8_0_0 - 0.0750000000000018*G0_1_1_8_0_1 + 0.6*G0_1_1_9_0_0 + 0.6*G0_1_1_9_0_1 - 0.724999999999998*G0_1_1_10_1_0 - 0.724999999999998*G0_1_1_10_1_1 + 0.125*G0_1_1_11_1_0 + 0.125*G0_1_1_12_1_1 + 0.0749999999999997*G0_1_1_13_1_0 + 0.0750000000000019*G0_1_1_13_1_1 + 0.0750000000000014*G0_1_1_14_1_0 + 0.0749999999999997*G0_1_1_14_1_1 - 0.675*G0_1_1_15_1_0 + 0.899999999999997*G0_1_1_15_1_1 - 0.0750000000000014*G0_1_1_16_1_0 - 0.3*G0_1_1_16_1_1 + 0.899999999999997*G0_1_1_17_1_0 - 0.675*G0_1_1_17_1_1 - 0.3*G0_1_1_18_1_0 - 0.0750000000000018*G0_1_1_18_1_1 + 0.6*G0_1_1_19_1_0 + 0.6*G0_1_1_19_1_1; + A[66] = 0.0; + A[134] = 0.0; + A[126] = A[48]; + A[91] = A[13]; + A[3] = A[81]; + A[14] = A[92]; + A[57] = 0.0; + A[39] = A[117]; + A[33] = 0.0; + A[97] = 0.0; + A[52] = A[130]; + A[75] = 0.0; + A[133] = 0.0; + A[94] = A[16]; + A[0] = A[78]; + A[107] = A[29]; + A[34] = 0.0; + A[118] = A[40]; + A[121] = 0.0; + A[93] = A[15]; + A[44] = 0.0; + A[24] = A[102]; + A[20] = 0.0; + A[104] = A[26]; + A[51] = A[129]; + A[113] = 0.0; + A[62] = A[140]; + A[138] = A[60]; + A[122] = 0.0; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p3_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q2_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q2_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q2_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q3_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q3_excafe.h new file mode 100644 index 0000000..9afe78d --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q3_excafe.h @@ -0,0 +1,1505 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 115 minutes and 45.85 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = w[0][18] + -w[0][13]; + const double var_5 = w[0][3] + -w[0][8]; + const double var_6 = var_1*var_5 + var_3*var_4; + const double var_7 = x[1][0] + var_2; + const double var_8 = x[1][1] + var_0; + const double var_9 = var_7*w[0][9] + -var_8*w[0][19]; + const double var_10 = var_8*w[0][17] + -var_7*w[0][7]; + const double var_11 = var_8*w[0][15]; + const double var_12 = -var_7*w[0][5] + var_11; + const double var_13 = w[0][6] + -w[0][4]; + const double var_14 = w[0][14] + -w[0][16]; + const double var_15 = var_14*var_8 + var_13*var_7; + const double var_16 = 44.2500000000000000000000000*var_15 + 29.5000000000000000000000000*var_10 + 28.5000000000000000000000000*var_9 + 27.0000000000000000000000000*var_12; + const double var_17 = -var_1 + var_8; + const double var_18 = var_3 + -var_7; + const double var_19 = var_1*var_8; + const double var_20 = var_3*var_7; + const double var_21 = var_1*var_17*var_8*w[0][0] + var_18*var_3*var_7*w[0][10]; + const double var_22 = var_7*var_7 + var_8*var_8; + const double var_23 = var_7*w[0][10] + -var_8*w[0][0]; + const double var_24 = var_22*var_23; + const double var_25 = -var_3*var_8*var_8*w[0][10] + var_1*var_7*var_7*w[0][0] + var_24; + const double var_26 = var_3*var_3 + var_1*var_1; + const double var_27 = var_1*w[0][0] + -var_3*w[0][10]; + const double var_28 = var_26*var_27; + const double var_29 = var_1*var_1*var_7*w[0][10] + -var_3*var_3*var_8*w[0][0] + var_28; + const double var_30 = var_25 + var_29; + const double var_31 = 1.5000000000000000000000000*var_21 + var_18*var_19*w[0][10] + var_17*var_20*w[0][0] + 0.5000000000000000000000000*var_30; + const double var_32 = var_3*w[0][4] + -var_1*w[0][14]; + const double var_33 = var_32*var_7*var_8; + const double var_34 = var_8*w[0][13] + -var_7*w[0][3]; + const double var_35 = var_1*var_3*var_34; + const double var_36 = var_33 + var_35; + const double var_37 = var_7*w[0][14] + -var_8*w[0][4]; + const double var_38 = var_22*var_37; + const double var_39 = var_1*w[0][3] + -var_3*w[0][13]; + const double var_40 = var_26*var_39; + const double var_41 = var_38 + var_40; + const double var_42 = -var_1*var_1*var_8*w[0][3]; + const double var_43 = var_3*var_3*var_7*w[0][13] + var_42; + const double var_44 = -var_3*var_7*var_7*w[0][14]; + const double var_45 = var_1*var_8*var_8*w[0][4] + var_44; + const double var_46 = var_45 + var_43; + const double var_47 = -var_1*var_8*var_8*w[0][8]; + const double var_48 = var_3*var_7*var_7*w[0][18] + var_47; + const double var_49 = -var_3*var_3*var_7*w[0][16]; + const double var_50 = var_1*var_1*var_8*w[0][6] + var_49; + const double var_51 = var_48 + var_50; + const double var_52 = -var_1*var_8*var_8*w[0][9]; + const double var_53 = var_3*var_7*var_7*w[0][19] + var_52; + const double var_54 = -var_3*var_3*var_7*w[0][19]; + const double var_55 = var_1*var_1*var_8*w[0][9] + var_54; + const double var_56 = var_53 + var_55; + const double var_57 = var_3*var_3*var_8*w[0][9] + -var_1*var_1*var_7*w[0][19]; + const double var_58 = var_3*var_8*var_8*w[0][19] + -var_1*var_7*var_7*w[0][9]; + const double var_59 = var_57 + var_58; + const double var_60 = var_1*var_15*var_3; + const double var_61 = var_1*var_4 + var_3*var_5; + const double var_62 = var_61*var_7*var_8; + const double var_63 = var_60 + var_62; + const double var_64 = -var_3*var_7*var_7*w[0][13]; + const double var_65 = var_1*var_8*var_8*w[0][3] + var_64; + const double var_66 = -var_1*var_1*var_8*w[0][4]; + const double var_67 = var_3*var_3*var_7*w[0][14] + var_66; + const double var_68 = var_67 + var_65; + const double var_69 = w[0][16] + -w[0][14]; + const double var_70 = -w[0][6] + w[0][4]; + const double var_71 = var_3*var_69*var_8*var_8 + var_1*var_7*var_7*var_70; + const double var_72 = w[0][8] + -w[0][3]; + const double var_73 = -w[0][18] + w[0][13]; + const double var_74 = var_3*var_3*var_72*var_8 + var_1*var_1*var_7*var_73; + const double var_75 = var_71 + var_74; + const double var_76 = var_3*var_3*var_8*w[0][6] + -var_1*var_1*var_7*w[0][16]; + const double var_77 = -var_1*var_7*var_7*w[0][8] + var_3*var_8*var_8*w[0][18]; + const double var_78 = var_77 + var_76; + const double var_79 = var_19*var_7*w[0][16]; + const double var_80 = -var_20*var_8*w[0][6] + var_79; + const double var_81 = var_1*var_20*w[0][8]; + const double var_82 = -var_19*var_3*w[0][18] + var_81; + const double var_83 = var_80 + var_82; + const double var_84 = -var_3*var_7*var_7*w[0][17]; + const double var_85 = var_1*var_8*var_8*w[0][7] + var_84; + const double var_86 = -var_1*var_1*var_8*w[0][5]; + const double var_87 = var_3*var_3*var_7*w[0][15] + var_86; + const double var_88 = var_85 + var_87; + const double var_89 = var_3*w[0][19] + -var_1*w[0][9]; + const double var_90 = var_26*var_89; + const double var_91 = var_8*w[0][9] + -var_7*w[0][19]; + const double var_92 = var_22*var_91; + const double var_93 = var_92 + var_90; + const double var_94 = var_1*var_3*var_9; + const double var_95 = var_1*w[0][19] + -var_3*w[0][9]; + const double var_96 = var_7*var_8*var_95; + const double var_97 = var_94 + var_96; + const double var_98 = var_1*var_12*var_3; + const double var_99 = var_3*w[0][7]; + const double var_100 = -var_1*w[0][17] + var_99; + const double var_101 = var_100*var_7*var_8; + const double var_102 = var_101 + var_98; + const double var_103 = -var_8*w[0][7]; + const double var_104 = var_7*w[0][17]; + const double var_105 = var_103 + var_104; + const double var_106 = var_105*var_22; + const double var_107 = -var_3*w[0][15]; + const double var_108 = var_1*w[0][5]; + const double var_109 = var_107 + var_108; + const double var_110 = var_109*var_26; + const double var_111 = var_110 + var_106; + const double var_112 = var_7*w[0][7] + -var_8*w[0][17]; + const double var_113 = var_1*var_112*var_3; + const double var_114 = -var_3*w[0][5] + var_1*w[0][15]; + const double var_115 = var_114*var_7*var_8; + const double var_116 = var_115 + var_113; + const double var_117 = -var_3*var_3*var_7*w[0][17]; + const double var_118 = var_1*var_19*w[0][7]; + const double var_119 = var_117 + var_118; + const double var_120 = -var_1*var_8*var_8*w[0][5]; + const double var_121 = var_20*var_7*w[0][15]; + const double var_122 = var_120 + var_121; + const double var_123 = var_119 + var_122; + const double var_124 = var_1*w[0][8] + -var_3*w[0][18]; + const double var_125 = var_124*var_26; + const double var_126 = var_7*w[0][16] + -var_8*w[0][6]; + const double var_127 = var_126*var_22; + const double var_128 = var_127 + var_125; + const double var_129 = var_1*w[0][1] + -var_3*w[0][11]; + const double var_130 = var_129*var_22; + const double var_131 = var_7*w[0][12] + -var_8*w[0][2]; + const double var_132 = var_131*var_26; + const double var_133 = var_130 + var_132; + const double var_134 = var_19 + var_20; + const double var_135 = var_3*w[0][11] + -var_1*w[0][1]; + const double var_136 = -var_7*w[0][12] + var_8*w[0][2]; + const double var_137 = var_135 + var_136; + const double var_138 = var_134*var_137; + const double var_139 = var_133 + var_138; + const double var_140 = var_139 + var_128; + const double var_141 = var_1*var_1*var_7*w[0][14] + -var_3*var_3*var_8*w[0][4]; + const double var_142 = var_1*var_7*var_7*w[0][3] + -var_3*var_8*var_8*w[0][13]; + const double var_143 = var_141 + var_142; + const double var_144 = var_1*var_7*var_7*w[0][5] + -var_3*var_8*var_8*w[0][15]; + const double var_145 = var_1*var_1*var_7*w[0][17] + -var_3*var_3*var_8*w[0][7]; + const double var_146 = var_144 + var_145; + const double var_147 = var_146 + var_143; + const double var_148 = var_8*w[0][5] + -var_7*w[0][15]; + const double var_149 = var_148*var_22; + const double var_150 = var_3*w[0][17] + -var_1*w[0][7]; + const double var_151 = var_150*var_26; + const double var_152 = var_149 + var_151; + const double var_153 = var_72*var_8 + var_7*var_73; + const double var_154 = var_153*var_22; + const double var_155 = var_3*var_69 + var_1*var_70; + const double var_156 = var_155*var_26; + const double var_157 = var_156 + var_154; + const double var_158 = var_157 + var_152; + const double var_159 = -var_1*var_1*var_7*w[0][15] + var_3*var_3*var_8*w[0][5]; + const double var_160 = -var_1*var_7*var_7*w[0][7] + var_3*var_8*var_8*w[0][17]; + const double var_161 = var_159 + var_160; + const double var_162 = var_3*var_7*var_7*w[0][16] + -var_1*var_8*var_8*w[0][6]; + const double var_163 = -var_3*var_3*var_7*w[0][18] + var_1*var_1*var_8*w[0][8]; + const double var_164 = var_163 + var_162; + const double var_165 = var_161 + var_164; + const double var_166 = 0.0857142857142857150787307*var_31 + 0.0678571428571428519882502*var_147 + 0.1571428571428571396850771*var_68 + 0.0535714285714285684547598*var_158 + 0.4142857142857142571656937*var_56 + 0.0035714285714285713170535*var_83 + 0.0892857142857142876968268*var_63 + 0.1428571428571428492126927*var_93 + 0.1500000000000000222044605*var_102 + 0.0607142857142857136909520*var_41 + 0.1285714285714285587403083*var_36 + 0.1357142857142857039765005*var_59 + 0.0142857142857142852682140*var_78 + 0.0107142857142857143848413*var_140 + 0.0392857142857142849212693*var_165 + 0.0357142857142857123031732*var_75 + 0.0928571428571428603149229*var_116 + 0.1035714285714285642914234*var_51 + 0.1642857142857142849212693*var_46 + 0.2785714285714285809447688*var_97 + 0.0250000000000000013877788*var_123 + 0.1107142857142857095276156*var_88 + 0.0821428571428571424606346*var_111; + const double var_167 = var_7*w[0][0] + -var_8*w[0][10]; + const double var_168 = var_1*var_167*var_3; + const double var_169 = var_1*w[0][10] + -var_3*w[0][0]; + const double var_170 = var_169*var_7*var_8; + const double var_171 = var_168 + var_170; + const double var_172 = var_19*var_7*w[0][19] + -var_20*var_8*w[0][9]; + const double var_173 = var_1*var_20*w[0][9]; + const double var_174 = -var_19*var_3*w[0][19] + var_173; + const double var_175 = var_172 + var_174; + const double var_176 = 0.7500000000000000000000000*var_3*var_7 + var_19; + const double var_177 = 0.2500000000000000000000000*var_3*var_3*var_8 + var_1*var_176; + const double var_178 = 0.7500000000000000000000000*var_1*var_8 + var_20; + const double var_179 = 0.2500000000000000000000000*var_1*var_1*var_7 + var_178*var_3; + const double var_180 = var_177*var_70 + var_179*var_69; + const double var_181 = var_3*w[0][13] + -var_1*w[0][3]; + const double var_182 = var_181*var_26; + const double var_183 = var_1*w[0][9] + -var_3*w[0][19]; + const double var_184 = var_183*var_26; + const double var_185 = 1.3500000000000000888178420*var_180 + 0.5875000000000000222044605*var_131*var_134 + 0.5625000000000000000000000*var_182 + 1.1250000000000000000000000*var_184; + const double var_186 = 0.2500000000000000000000000*var_3*var_8*var_8 + var_178*var_7; + const double var_187 = 0.2500000000000000000000000*var_1*var_7*var_7 + var_176*var_8; + const double var_188 = var_186*var_73 + var_187*var_72; + const double var_189 = -var_7*w[0][14] + var_8*w[0][4]; + const double var_190 = var_189*var_22; + const double var_191 = -var_8*w[0][9] + var_7*w[0][19]; + const double var_192 = var_191*var_22; + const double var_193 = 1.1250000000000000000000000*var_192 + 0.5625000000000000000000000*var_190 + 0.5875000000000000222044605*var_129*var_134 + 1.3500000000000000888178420*var_188; + const double var_194 = var_19*var_8*w[0][6]; + const double var_195 = -var_20*var_7*w[0][16] + var_194; + const double var_196 = var_20*var_3*w[0][18]; + const double var_197 = -var_1*var_19*w[0][8] + var_196; + const double var_198 = var_19*var_3*w[0][13]; + const double var_199 = -var_1*var_20*w[0][3] + var_198; + const double var_200 = var_20*var_8*w[0][4]; + const double var_201 = -var_19*var_7*w[0][14] + var_200; + const double var_202 = var_195 + var_128 + var_201 + var_197 + var_199; + const double var_203 = -var_3*var_8*var_8*w[0][19] + var_1*var_7*var_7*w[0][9]; + const double var_204 = -var_3*var_3*var_8*w[0][9] + var_1*var_1*var_7*w[0][19]; + const double var_205 = var_203 + var_204; + const double var_206 = -var_1*var_1*var_7*w[0][17] + var_3*var_3*var_8*w[0][7]; + const double var_207 = var_3*w[0][15] + -var_1*w[0][5]; + const double var_208 = var_207*var_26; + const double var_209 = -var_1*var_7*var_7*w[0][5] + var_3*var_8*var_8*w[0][15]; + const double var_210 = var_8*w[0][7] + -var_7*w[0][17]; + const double var_211 = var_210*var_22; + const double var_212 = var_211 + var_209; + const double var_213 = var_206 + var_208 + var_212; + const double var_214 = var_8*w[0][18] + -var_7*w[0][8]; + const double var_215 = var_1*var_214*var_3; + const double var_216 = var_3*w[0][6] + -var_1*w[0][16]; + const double var_217 = var_216*var_7*var_8; + const double var_218 = var_135*var_26; + const double var_219 = var_136*var_22; + const double var_220 = var_219 + var_218; + const double var_221 = var_1*var_17*var_8*w[0][7] + var_18*var_3*var_7*w[0][17]; + const double var_222 = var_18*var_3*var_7*w[0][15] + var_1*var_17*var_8*w[0][5]; + const double var_223 = var_221 + var_222; + const double var_224 = var_220 + var_46 + var_223 + var_217 + var_215; + const double var_225 = var_14*var_3*var_8*var_8 + var_1*var_13*var_7*var_7; + const double var_226 = var_3*var_3*var_5*var_8 + var_1*var_1*var_4*var_7; + const double var_227 = var_226 + var_225; + const double var_228 = var_213 + 0.6000000000000000888178420*var_227 + 0.2000000000000000111022302*var_224 + var_161 + var_152; + const double var_229 = var_56 + var_30; + const double var_230 = w[0][17] + w[0][15]; + const double var_231 = w[0][5] + w[0][7]; + const double var_232 = var_17*var_231*var_3*var_7 + var_1*var_18*var_230*var_8; + const double var_233 = 0.2250000000000000055511151*var_229 + 0.9000000000000000222044605*var_205 + 0.0250000000000000013877788*var_21 + var_193 + 0.2000000000000000111022302*var_171 + 1.1250000000000000000000000*var_175 + var_185 + 0.4500000000000000111022302*var_202 + 0.5625000000000000000000000*var_228 + 0.6750000000000000444089210*var_232; + A[268] = 0.0000000000000000000000000; + const double var_234 = var_1*var_7; + const double var_235 = -var_3*var_8 + var_234; + const double var_236 = var_235; + const double var_237 = std::abs(var_236); + const double var_238 = var_235; + const double var_239 = var_3*w[0][10] + -var_1*w[0][0]; + const double var_240 = var_239*var_26; + const double var_241 = -var_1*var_1*var_7*w[0][10] + var_240 + var_3*var_3*var_8*w[0][0]; + const double var_242 = -var_3*var_3*var_7*w[0][10]; + const double var_243 = var_1*var_1*var_8*w[0][0] + var_242; + const double var_244 = -var_1*var_1*var_7*w[0][14] + var_3*var_3*var_8*w[0][4]; + const double var_245 = -var_3*var_3*var_7*w[0][14]; + const double var_246 = var_1*var_1*var_8*w[0][4] + var_245; + const double var_247 = -var_1*var_1*var_8*w[0][7]; + const double var_248 = var_3*var_3*var_7*w[0][17] + var_247; + const double var_249 = var_1*var_10*var_3; + const double var_250 = var_3*w[0][18] + -var_1*w[0][8]; + const double var_251 = var_1*w[0][7] + -var_3*w[0][17]; + const double var_252 = var_1*var_13 + var_14*var_3; + const double var_253 = 8.8714285714285718853489016*var_89 + 4.0499999999999998223643161*var_251 + 1.5928571428571427492926205*var_136 + 4.9000000000000003552713679*var_129 + 5.3357142857142854097673990*var_252 + 8.0999999999999996447286321*var_250 + 6.4285714285714279370154145*var_39; + const double var_254 = var_3*var_8 + var_234; + const double var_255 = var_1*w[0][13] + -var_3*w[0][3]; + const double var_256 = var_3*var_3*var_8*w[0][8] + var_254*var_255 + -var_1*var_1*var_7*w[0][18]; + const double var_257 = var_7*w[0][8] + -var_8*w[0][18]; + const double var_258 = 51.0000000000000000000000000*var_9 + 120.5000000000000000000000000*var_257; + const double var_259 = -var_1*var_1*var_8*w[0][6] + var_3*var_3*var_7*w[0][16]; + const double var_260 = var_87 + var_259; + const double var_261 = var_1*var_1*var_7*w[0][15] + -var_3*var_3*var_8*w[0][5]; + const double var_262 = -var_3*var_3*var_8*w[0][6] + var_1*var_1*var_7*w[0][16]; + const double var_263 = var_261 + var_262; + const double var_264 = var_7*var_70 + var_69*var_8; + const double var_265 = var_1*var_264*var_3; + const double var_266 = var_19*var_3*w[0][15]; + const double var_267 = -var_1*var_20*w[0][5] + var_266; + const double var_268 = var_265 + var_267; + const double var_269 = var_134*var_23 + var_168; + const double var_270 = var_134*var_136; + const double var_271 = var_270 + var_269; + const double var_272 = var_4*var_7 + var_5*var_8; + const double var_273 = var_37 + var_210; + const double var_274 = 423.0000000000000000000000000*var_272 + 216.1428571428571387968986528*var_135 + 140.1428571428571387968986528*var_273; + const double var_275 = 0.1928571428571428381104624*var_57; + const double var_276 = 0.0125000000000000006938894*var_134*var_274 + 0.6910714285714285587403083*var_246 + 0.2250000000000000055511151*var_268 + 0.3776785714285714190552312*var_260 + 0.1250000000000000000000000*var_253*var_26 + 0.1062500000000000111022302*var_241 + 2.8285714285714282922867824*var_43 + 0.3553571428571428714171532*var_271 + 1.4142857142857141461433912*var_256 + 0.3053571428571428270082322*var_110 + 1.8321428571428570730716956*var_55 + 1.5267857142857141905523122*var_249 + 0.6589285714285714190552312*var_145 + 2.1857142857142854985852409*var_248 + 5.2875000000000005329070518*var_163 + 0.4660714285714285809447688*var_244 + 0.1526785714285714135041161*var_263 + 0.4616071428571428270082322*var_243 + 0.0321428571428571396850771*var_1*var_258*var_3 + var_275; + A[23] = 0.7500000000000000000000000*var_237*var_276/(var_238*var_238*var_238); + const double var_277 = var_1*var_7*var_7*w[0][8] + -var_3*var_8*var_8*w[0][18]; + const double var_278 = -var_3*var_7*var_7*w[0][19]; + const double var_279 = var_1*var_8*var_8*w[0][9] + var_278; + const double var_280 = var_39 + var_109; + const double var_281 = var_89 + 0.5000000000000000000000000*var_280; + const double var_282 = 9.5000000000000000000000000*var_3*var_7 + var_19; + const double var_283 = 9.5000000000000000000000000*var_1*var_8 + var_20; + const double var_284 = var_134*var_135; + const double var_285 = var_17*w[0][0] + var_18*w[0][10]; + const double var_286 = var_285 + var_124 + var_251; + const double var_287 = var_149 + var_134*var_286 + var_284; + const double var_288 = var_20*var_8*w[0][7]; + const double var_289 = -var_19*var_7*w[0][17] + var_288; + const double var_290 = var_254*var_9; + const double var_291 = var_290 + var_289; + const double var_292 = 8.5000000000000000000000000*var_225 + 5.7500000000000000000000000*var_189*var_22 + var_279 + 0.2500000000000000000000000*var_48 + 0.7500000000000000000000000*var_287 + var_277 + 4.2500000000000000000000000*var_210*var_22 + 3.0000000000000000000000000*var_219 + 2.7500000000000000000000000*var_142 + var_13*var_283*var_8 + var_134*var_281 + 3.2500000000000000000000000*var_209 + var_14*var_282*var_7 + 0.5000000000000000000000000*var_291; + const double var_293 = -var_1*var_1*var_8*w[0][9]; + const double var_294 = var_3*var_3*var_7*w[0][19] + var_293; + const double var_295 = var_37 + var_105; + const double var_296 = var_91 + 0.5000000000000000000000000*var_295; + const double var_297 = var_7*w[0][15] + -var_8*w[0][5]; + const double var_298 = var_285 + var_126 + var_297; + const double var_299 = var_134*var_298 + var_270 + var_151; + const double var_300 = var_254*var_95; + const double var_301 = var_267 + var_300; + const double var_302 = 0.7500000000000000000000000*var_299 + 4.2500000000000000000000000*var_207*var_26 + var_1*var_283*var_5 + var_134*var_296 + 0.2500000000000000000000000*var_50 + 8.5000000000000000000000000*var_226 + 5.7500000000000000000000000*var_181*var_26 + 3.2500000000000000000000000*var_206 + 2.7500000000000000000000000*var_141 + var_282*var_3*var_4 + 3.0000000000000000000000000*var_218 + var_294 + var_262 + 0.5000000000000000000000000*var_301; + const double var_303 = -var_3*var_3*var_7*w[0][15]; + const double var_304 = var_1*var_19*w[0][5]; + const double var_305 = var_303 + var_304; + const double var_306 = var_305 + var_60; + const double var_307 = var_1*var_20*w[0][7]; + const double var_308 = -var_1*var_3*var_8*w[0][17] + var_307; + const double var_309 = var_159 + var_308; + const double var_310 = 0.2000000000000000111022302*var_131*var_26 + var_156; + const double var_311 = var_310 + var_125; + const double var_312 = 0.0357142857142857123031732*var_119 + 0.0285714285714285705364279*var_67 + 0.0125000000000000006938894*var_309 + 0.0267857142857142842273799*var_311 + 0.0714285714285714246063463*var_184 + 0.0071428571428571426341070*var_302 + 0.0089285714285714280757933*var_306; + A[29] = 20.2500000000000000000000000*var_237*var_312/(var_238*var_238*var_238); + A[181] = A[29]; + const double var_313 = var_1*var_19*w[0][9]; + const double var_314 = -var_20*var_3*w[0][19] + var_313; + const double var_315 = 0.5000000000000000000000000*var_1*var_12*var_3; + const double var_316 = var_315 + var_57; + const double var_317 = var_22*var_297; + const double var_318 = var_141 + var_317 + var_106; + A[15] = 0.0000000000000000000000000; + A[366] = 0.0000000000000000000000000; + const double var_319 = var_3*w[0][9] + -var_1*w[0][19]; + const double var_320 = var_319*var_7*var_8; + const double var_321 = 0.5000000000000000000000000*var_204; + const double var_322 = var_320 + var_321; + const double var_323 = var_129*var_26; + const double var_324 = var_1*var_20*w[0][3]; + const double var_325 = var_7*w[0][5] + -var_8*w[0][15]; + A[39] = 0.0000000000000000000000000; + A[263] = 0.0000000000000000000000000; + A[194] = 0.0000000000000000000000000; + const double var_326 = -var_1*var_3*var_7*w[0][5] + var_266; + const double var_327 = var_326 + var_110; + A[327] = 0.0000000000000000000000000; + const double var_328 = -var_3*var_7*var_7*w[0][16]; + const double var_329 = var_1*var_8*var_8*w[0][6] + var_328; + const double var_330 = var_189 + var_210; + const double var_331 = -var_3*var_7*var_7*w[0][15]; + const double var_332 = var_1*var_8*var_8*w[0][5] + var_331; + const double var_333 = var_162 + var_19*var_3*w[0][14] + 0.5000000000000000000000000*var_332 + -var_1*var_20*w[0][4] + var_216*var_254 + 1.5000000000000000000000000*var_67; + const double var_334 = 19.0000000000000000000000000*var_3*var_7 + 47.0000000000000000000000000*var_1*var_8; + const double var_335 = 19.0000000000000000000000000*var_1*var_8 + 47.0000000000000000000000000*var_3*var_7; + const double var_336 = var_335*var_69*var_7 + var_334*var_70*var_8; + const double var_337 = var_207 + var_181; + const double var_338 = var_183 + 0.5000000000000000000000000*var_337; + const double var_339 = 0.0040178571428571424606346*var_336 + 0.0723214285714285642914234*var_134*var_338 + 0.1125000000000000027755576*var_71 + 0.0169642857142857129970626*var_219; + const double var_340 = var_22*var_272; + const double var_341 = 0.0272321428571428575393654*var_129*var_22 + 0.0281250000000000006938894*var_340; + const double var_342 = -var_3*var_8*w[0][9] + var_19*w[0][19]; + const double var_343 = var_134*var_27 + var_170; + const double var_344 = var_124*var_134 + var_48 + 1.2285714285714284255135453*var_77 + 0.8857142857142856762209249*var_343; + const double var_345 = var_3*w[0][8] + -var_1*w[0][18]; + const double var_346 = -var_1*var_8*var_8*w[0][3]; + const double var_347 = var_3*var_7*var_7*w[0][13] + var_346; + const double var_348 = var_347 + 0.5000000000000000000000000*var_254*var_34; + const double var_349 = 0.5000000000000000000000000*var_345*var_7*var_8 + var_348; + const double var_350 = var_85 + 0.5000000000000000000000000*var_112*var_254; + const double var_351 = var_332 + var_350; + const double var_352 = var_134*var_150 + 0.7187500000000000000000000*var_351 + var_106 + 0.0625000000000000000000000*var_209 + 0.0312500000000000000000000*var_284 + 0.2500000000000000000000000*var_349 + 0.1875000000000000000000000*var_203; + const double var_353 = var_20*var_7*w[0][19]; + const double var_354 = var_52 + var_353; + const double var_355 = var_20*var_7*w[0][10]; + const double var_356 = 1.8000000000000000444089210*var_126 + 2.2500000000000000000000000*var_148 + 1.9000000000000001332267630*var_37 + 5.1000000000000005329070518*var_91; + const double var_357 = var_3*w[0][5] + -var_1*w[0][15]; + const double var_358 = 2.8125000000000000000000000*var_357*var_7 + -var_19*w[0][0]; + const double var_359 = 1.1250000000000000000000000*var_22*var_356 + var_358*var_8 + 1.6875000000000000000000000*var_354 + var_355; + const double var_360 = 0.1687500000000000111022302*var_342*var_7 + 0.0531250000000000055511151*var_25 + var_341 + var_339 + 0.2571428571428571174806166*var_352 + 0.1406250000000000000000000*var_344 + 0.0714285714285714246063463*var_359; + const double var_361 = -var_1*var_1*var_8*w[0][0]; + const double var_362 = var_3*var_3*var_7*w[0][10] + var_361; + const double var_363 = -var_3*var_7*var_7*w[0][10]; + const double var_364 = var_1*var_8*var_8*w[0][0] + var_363; + const double var_365 = var_250*var_26; + const double var_366 = var_365 + var_151; + const double var_367 = 0.0250000000000000013877788*var_206 + 0.0062500000000000003469447*var_74 + 0.2250000000000000055511151*var_183*var_26 + 0.0312500000000000000000000*var_366; + const double var_368 = var_20*var_3*w[0][19]; + const double var_369 = var_293 + var_368; + const double var_370 = var_131*var_134; + const double var_371 = var_7*w[0][3] + -var_8*w[0][13]; + const double var_372 = 0.5000000000000000000000000*var_1*var_3*var_371; + const double var_373 = var_1*w[0][17] + -var_3*w[0][7]; + const double var_374 = var_373*var_7*var_8; + const double var_375 = var_135*var_22; + const double var_376 = var_1*var_18*var_8*w[0][10] + var_17*var_3*var_7*w[0][0]; + const double var_377 = var_17*var_3*var_7*w[0][9] + var_1*var_18*var_8*w[0][19]; + const double var_378 = 0.0258928571428571410728559*var_376 + 0.2089285714285714357085766*var_377; + const double var_379 = -var_1*var_7*var_7*w[0][3] + var_3*var_8*var_8*w[0][13]; + const double var_380 = -var_3*var_7*var_7*w[0][18] + var_1*var_8*var_8*w[0][8]; + const double var_381 = var_3*var_7*var_7*w[0][15] + var_120; + const double var_382 = -var_1*var_8*var_8*w[0][4]; + const double var_383 = var_3*var_7*var_7*w[0][14] + var_382; + const double var_384 = var_1*var_1*var_8*w[0][5] + var_303; + const double var_385 = -var_1*var_8*var_8*w[0][7]; + const double var_386 = var_20*var_7*w[0][17]; + const double var_387 = var_385 + var_386; + const double var_388 = 0.2500000000000000000000000*w[0][18] + w[0][17]; + const double var_389 = 1.0625000000000000000000000*var_148*var_22 + 1.1250000000000000000000000*var_208; + const double var_390 = w[0][7] + 0.2500000000000000000000000*w[0][8]; + const double var_391 = var_1*var_73 + var_3*var_72; + const double var_392 = var_391*var_7*var_8; + const double var_393 = 0.2500000000000000000000000*var_77 + 0.3750000000000000000000000*var_392; + const double var_394 = var_182 + var_340; + const double var_395 = var_1*var_3*var_325; + const double var_396 = var_395 + var_217; + const double var_397 = -var_3*var_3*var_7*w[0][13]; + const double var_398 = var_1*var_1*var_8*w[0][3] + var_397; + const double var_399 = var_347 + var_398; + const double var_400 = var_192 + var_321; + const double var_401 = var_400 + var_190; + const double var_402 = var_127 + var_159; + const double var_403 = 2.2500000000000000000000000*var_401 + 1.1250000000000000000000000*var_394 + 0.0625000000000000000000000*var_160 + var_389 + 2.0625000000000000000000000*var_396 + 0.1250000000000000000000000*var_380 + var_1*var_176*var_390 + 3.3750000000000000000000000*var_203 + var_209 + 5.3750000000000000000000000*var_383 + var_393 + 2.7500000000000000000000000*var_399 + 1.4375000000000000000000000*var_225 + var_387 + 8.2500000000000000000000000*var_279 + 2.8750000000000000000000000*var_381 + 2.3750000000000000000000000*var_379 + -var_178*var_3*var_388 + 3.2500000000000000000000000*var_384 + 1.1875000000000000000000000*var_402; + const double var_404 = var_29 + var_323; + const double var_405 = var_1*w[0][14] + -var_3*w[0][4]; + const double var_406 = 0.5000000000000000000000000*var_405*var_7*var_8; + const double var_407 = 2.2500000000000000000000000*var_406 + var_195 + var_180; + const double var_408 = 0.0133928571428571421136899*var_404 + 0.0205357142857142856151587*var_219 + 0.0339285714285714259941251*var_370 + var_378 + 0.0142857142857142852682140*var_284 + 0.0151785714285714284227380*var_25 + 0.0017857142857142856585267*var_375 + 0.0428571428571428575393654*var_403 + 0.0410714285714285712303173*var_364 + 0.2410714285714285476380780*var_372 + 0.2571428571428571174806166*var_369 + 0.4285714285714285476380780*var_367 + 0.0803571428571428492126927*var_115 + 0.0392857142857142849212693*var_362 + 0.1500000000000000222044605*var_407 + 0.0401785714285714246063463*var_374; + A[89] = 40.5000000000000000000000000*var_237*var_408/(var_238*var_238*var_238); + A[184] = A[89]; + const double var_409 = var_3*var_7*var_7*w[0][17] + var_385; + const double var_410 = var_20*var_7*w[0][14]; + const double var_411 = var_382 + var_410; + const double var_412 = var_18*var_3*var_7*w[0][13] + var_1*var_17*var_8*w[0][3]; + const double var_413 = var_252*var_26; + const double var_414 = 0.5000000000000000000000000*var_1*var_3*var_34; + const double var_415 = var_1*var_1*var_8*w[0][7] + var_117; + const double var_416 = -var_19*var_3*w[0][17] + var_307; + const double var_417 = 0.0562500000000000013877788*var_416 + 0.0883928571428571341339619*var_415 + 1.2857142857142855874030829*var_367; + const double var_418 = 6.1428571428571423496123316*var_405 + 7.0000000000000000000000000*var_216 + 2.7142857142857139685077072*var_114; + const double var_419 = var_129*var_134; + const double var_420 = var_419 + var_375; + const double var_421 = 0.0482142857142857095276156*var_277 + 0.0312500000000000000000000*var_420; + const double var_422 = var_154 + var_62; + const double var_423 = var_25 + var_219; + const double var_424 = var_18*var_3*var_7*w[0][19] + var_1*var_17*var_8*w[0][9]; + const double var_425 = 0.0714285714285714246063463*var_376 + 0.1607142857142856984253854*var_424; + const double var_426 = 0.4017857142857142460634634*var_384; + const double var_427 = var_190 + var_106; + const double var_428 = 0.1687500000000000111022302*var_427; + const double var_429 = var_144 + var_395; + const double var_430 = var_19*var_3*w[0][18]; + const double var_431 = -var_1*var_3*var_7*w[0][8] + var_430; + const double var_432 = var_94 + var_431; + const double var_433 = var_19*var_7*w[0][17]; + const double var_434 = -var_20*var_8*w[0][7] + var_433; + const double var_435 = var_1*var_17*var_8*w[0][8] + var_18*var_3*var_7*w[0][18]; + const double var_436 = var_434 + var_435; + const double var_437 = 0.1928571428571428381104624*var_58; + const double var_438 = 0.0482142857142857095276156*var_381 + 0.2571428571428571174806166*var_389 + 0.7071428571428570730716956*var_265 + 0.0160714285714285698425385*var_432 + 0.2089285714285714357085766*var_160 + var_426 + 0.3776785714285714190552312*var_225 + var_428 + var_437 + 0.0883928571428571341339619*var_142 + var_417 + 0.7232142857142856984253854*var_411 + 0.3375000000000000222044605*var_413 + 0.0741071428571428575393654*var_29 + 0.0562500000000000013877788*var_418*var_7*var_8 + 0.1946428571428571452361922*var_136*var_26 + 0.4178571428571428714171532*var_262 + 0.1446428571428571285828468*var_244 + 0.2973214285714285698425385*var_159 + 0.1455357142857142682679239*var_362 + 0.2169642857142857206298459*var_409 + 0.7714285714285713524418497*var_329 + 0.1285714285714285587403083*var_412 + 0.1044642857142857178542883*var_429 + 0.2633928571428571507873073*var_364 + var_421 + 0.8517857142857142571656937*var_246 + 0.0080357142857142849212693*var_436 + 1.1250000000000000000000000*var_259 + 0.0401785714285714246063463*var_422 + 0.1919642857142856984253854*var_423 + 0.0062500000000000003469447*var_323 + 0.2732142857142856873231551*var_126*var_22 + var_425 + 0.2410714285714285476380780*var_414 + 0.3125000000000000000000000*var_370 + 0.3535714285714285365358478*var_322; + const double var_439 = 0.7383928571428570730716956*var_376; + A[128] = 0.4821428571428570952761561*var_233*var_237/(var_238*var_238*var_238); + const double var_440 = var_19*var_8*w[0][7]; + const double var_441 = -var_20*var_7*w[0][17] + var_440; + const double var_442 = var_20*var_3*w[0][15]; + const double var_443 = -var_1*var_19*w[0][5] + var_442; + const double var_444 = -var_7*w[0][6] + var_8*w[0][16]; + const double var_445 = var_1*var_7*var_7*w[0][4]; + const double var_446 = var_254*var_444 + -var_3*var_8*var_8*w[0][14] + var_445; + const double var_447 = var_1*var_1*var_7*w[0][13]; + const double var_448 = var_254*var_345 + -var_3*var_3*var_8*w[0][3] + var_447; + const double var_449 = var_161 + var_51 + var_146; + const double var_450 = var_277 + var_262; + const double var_451 = 0.5000000000000000000000000*var_449 + 9.0000000000000000000000000*var_56 + var_446 + var_441 + var_450 + var_448 + var_443; + const double var_452 = 0.5000000000000000000000000*var_32*var_7*var_8; + const double var_453 = var_58 + var_452; + A[139] = 0.0000000000000000000000000; + A[244] = 0.0000000000000000000000000; + A[382] = 0.0000000000000000000000000; + const double var_454 = var_18*var_3*var_7*w[0][14] + var_1*var_17*var_8*w[0][4]; + const double var_455 = var_412 + var_454; + const double var_456 = 0.4500000000000000111022302*var_41 + 0.7250000000000000888178420*var_46; + const double var_457 = var_103 + var_108; + const double var_458 = var_107 + var_104; + const double var_459 = var_148 + var_150; + const double var_460 = var_78 + var_157 + var_220; + const double var_461 = var_59 + var_143; + const double var_462 = var_54 + var_313; + const double var_463 = var_354 + var_462; + const double var_464 = 0.5500000000000000444089210*var_51 + var_83 + 3.0000000000000000000000000*var_134*var_459 + 0.0500000000000000027755576*var_133 + var_111 + 0.5000000000000000000000000*var_461 + 1.9000000000000001332267630*var_93 + 0.3000000000000000444089210*var_63 + 1.3500000000000000888178420*var_164 + 0.1000000000000000055511151*var_463 + 1.1000000000000000888178420*var_36 + 1.5000000000000000000000000*var_152 + 0.2500000000000000000000000*var_460; + const double var_465 = var_178*var_458 + var_456 + 0.2000000000000000111022302*var_377 + var_176*var_457 + 0.5000000000000000000000000*var_464; + const double var_466 = var_8*w[0][0] + -var_7*w[0][10]; + const double var_467 = var_22*var_466; + const double var_468 = -var_1*var_7*var_7*w[0][0] + var_3*var_8*var_8*w[0][10] + var_467; + const double var_469 = var_8*w[0][6] + -var_7*w[0][16]; + const double var_470 = var_22*var_469; + const double var_471 = 0.2214285714285714190552312*var_136 + 0.0642857142857142793701541*var_155; + const double var_472 = 0.2571428571428571174806166*var_181 + 0.6428571428571427937015414*var_89 + 2.9000000000000003552713679*var_150 + 1.5357142857142855874030829*var_124 + 0.4928571428571428270082322*var_135 + var_471; + const double var_473 = 0.5000000000000000000000000*var_254*var_32 + var_246; + const double var_474 = var_405*var_7*var_8; + const double var_475 = var_1*var_7*var_7*w[0][7] + -var_3*var_8*var_8*w[0][17]; + const double var_476 = var_475 + var_98 + var_145; + const double var_477 = var_19*var_3*w[0][19]; + const double var_478 = -var_1*var_3*var_7*w[0][9] + var_477; + const double var_479 = 0.0964285714285714190552312*var_478; + const double var_480 = var_317 + var_110; + const double var_481 = -var_19*var_8*w[0][5] + var_121; + const double var_482 = -var_20*var_3*w[0][15] + var_304; + const double var_483 = var_481 + var_482; + const double var_484 = var_20*var_8*w[0][6]; + const double var_485 = -var_19*var_7*w[0][16] + var_484; + const double var_486 = var_379 + var_485; + const double var_487 = var_340 + var_329; + const double var_488 = var_1*var_3*var_371; + const double var_489 = var_488 + var_211; + const double var_490 = -var_1*var_1*var_8*w[0][8]; + const double var_491 = var_3*var_3*var_7*w[0][18] + var_490; + const double var_492 = var_192 + var_392; + const double var_493 = 16.3000000000000007105427358*var_380 + 6.6000000000000005329070518*var_57 + 5.5000000000000000000000000*var_226 + 6.7000000000000001776356839*var_383 + 15.5000000000000000000000000*var_398 + 23.0000000000000000000000000*var_115 + 2.5000000000000000000000000*var_277 + 3.8000000000000002664535259*var_190 + 29.5000000000000000000000000*var_491 + 13.8000000000000007105427358*var_492 + 20.2000000000000028421709430*var_347 + 18.6000000000000014210854715*var_279 + -var_1*var_20*w[0][6] + 25.4000000000000021316282073*var_415 + 1.9000000000000001332267630*var_225 + var_19*var_3*w[0][16] + 11.4000000000000003552713679*var_203 + 13.7000000000000010658141036*var_259 + 33.0000000000000000000000000*var_113 + 5.0000000000000000000000000*var_209 + 12.7000000000000010658141036*var_262; + const double var_494 = 1.4303571428571428825193834*var_159 + var_439 + 0.5625000000000000000000000*var_26*var_472 + 0.9642857142857141905523122*var_215 + 0.1687500000000000111022302*var_314 + 1.7830357142857142793701541*var_362 + 1.1250000000000000000000000*var_483 + 1.0446428571428569842538536*var_29 + 0.2089285714285714357085766*var_85 + 0.0531250000000000055511151*var_131*var_22 + 0.0995535714285714218307888*var_135*var_22 + 0.2571428571428571174806166*var_486 + 0.1928571428571428381104624*var_474 + 0.3062500000000000222044605*var_468 + 0.3334821428571428381104624*var_487 + 0.0803571428571428492126927*var_473 + 0.5062499999999999777955395*var_480 + 0.3767857142857142793701541*var_129*var_134 + 0.4321428571428571063783863*var_364 + var_479 + 0.4017857142857142460634634*var_489 + 0.0964285714285714190552312*var_374 + 0.0714285714285714246063463*var_370 + 0.2531249999999999888977698*var_470 + 0.2892857142857142571656937*var_320 + 0.3053571428571428270082322*var_476 + 0.0401785714285714246063463*var_493; + const double var_495 = -var_1*var_3*var_8*w[0][18] + var_81; + A[209] = 0.0000000000000000000000000; + const double var_496 = var_134*var_469; + const double var_497 = var_159 + var_496; + const double var_498 = var_357*var_7*var_8; + const double var_499 = var_498 + var_249; + A[79] = 0.0000000000000000000000000; + A[325] = 0.0000000000000000000000000; + const double var_500 = var_134*var_250; + const double var_501 = var_500 + var_160; + const double var_502 = 0.2214285714285714190552312*var_135 + 0.0642857142857142793701541*var_153; + const double var_503 = 0.6428571428571427937015414*var_191 + 0.9000000000000000222044605*var_189 + 1.5357142857142855874030829*var_148 + 2.9000000000000003552713679*var_126 + 1.8571428571428569842538536*var_136 + 0.2571428571428571174806166*var_105 + var_502; + const double var_504 = -var_8*w[0][16]; + const double var_505 = var_7*w[0][6] + var_504; + const double var_506 = -var_445 + var_3*var_8*var_8*w[0][14] + var_254*var_505; + const double var_507 = var_329 + 0.5000000000000000000000000*var_506; + const double var_508 = var_48 + var_409; + const double var_509 = 11.0000000000000000000000000*var_405 + 12.7500000000000000000000000*var_319; + const double var_510 = var_3*w[0][0] + -var_1*w[0][10]; + const double var_511 = var_134*var_239 + var_510*var_7*var_8; + const double var_512 = var_511 + var_419; + const double var_513 = var_434 + var_62; + const double var_514 = var_77 + var_160; + const double var_515 = var_181 + var_109; + const double var_516 = 216.1428571428571387968986528*var_131 + 140.1428571428571387968986528*var_515 + 423.0000000000000000000000000*var_155; + const double var_517 = 0.5544642857142857428343063*var_25 + 1.0928571428571427492926205*var_142 + 0.3553571428571428714171532*var_512 + 1.1250000000000000000000000*var_22*var_503 + 0.9098214285714285587403083*var_364 + 1.8321428571428570730716956*var_279 + 7.7464285714285709971704819*var_507 + 2.8125000000000000000000000*var_381 + 5.2875000000000005329070518*var_383 + 0.1526785714285714135041161*var_514 + 0.1928571428571428381104624*var_203 + 1.2857142857142855874030829*var_209 + 0.2250000000000000055511151*var_513 + 0.1285714285714285587403083*var_509*var_7*var_8 + 1.3178571428571428381104624*var_65 + 1.5267857142857141905523122*var_115 + 0.0125000000000000006938894*var_134*var_516 + 0.3776785714285714190552312*var_508; + A[46] = 0.7500000000000000000000000*var_237*var_517/(var_238*var_238*var_238); + A[256] = A[46]; + const double var_518 = var_251*var_26; + const double var_519 = var_518 + var_142 + var_110; + const double var_520 = var_90 + var_452; + const double var_521 = var_94 + var_62; + const double var_522 = 5.1250000000000000000000000*var_8*var_95 + -var_178*w[0][15]; + const double var_523 = var_40 + 3.2500000000000000000000000*var_77 + 4.5000000000000000000000000*var_65 + 1.8125000000000000000000000*var_87 + var_522*var_7 + var_176*var_8*w[0][5] + 0.6875000000000000000000000*var_50 + 0.2500000000000000000000000*var_241 + var_454 + 2.3125000000000000000000000*var_475 + 6.5000000000000000000000000*var_53 + 3.6250000000000000000000000*var_249 + 5.7500000000000000000000000*var_55 + 0.7500000000000000000000000*var_141 + 1.6250000000000000000000000*var_145 + 2.1250000000000000000000000*var_520 + 3.3750000000000000000000000*var_521 + 6.6250000000000000000000000*var_48 + 1.3750000000000000000000000*var_58 + 6.3750000000000000000000000*var_85 + 2.2500000000000000000000000*var_106 + 1.1250000000000000000000000*var_519 + 2.3750000000000000000000000*var_316; + A[338] = A[128]; + A[9] = 10.1250000000000000000000000*var_166*var_237/(var_238*var_238*var_238); + A[365] = 0.0000000000000000000000000; + A[37] = 0.0000000000000000000000000; + const double var_524 = -var_1*var_8*var_8*w[0][0]; + const double var_525 = var_3*var_7*var_7*w[0][10] + var_524; + const double var_526 = var_19*var_8*w[0][4]; + const double var_527 = var_44 + var_526; + const double var_528 = var_13*var_177 + var_14*var_179; + const double var_529 = 0.0419642857142857109153944*var_134*var_136 + 0.0964285714285714190552312*var_528 + 0.0178571428571428561515866*var_243 + 0.0803571428571428492126927*var_26*var_281; + const double var_530 = var_86 + var_442; + const double var_531 = var_469 + var_297; + const double var_532 = var_39 + var_124 + 1.1250000000000000000000000*var_531; + const double var_533 = var_96 + var_151; + const double var_534 = -var_3*w[0][6] + var_1*w[0][16]; + const double var_535 = 17.0000000000000000000000000*var_357 + 19.0000000000000000000000000*var_534; + const double var_536 = var_206 + 29.0000000000000000000000000*var_332 + var_29 + var_535*var_7*var_8; + const double var_537 = var_38 + var_211; + const double var_538 = var_144 + var_537; + const double var_539 = var_71 + var_160; + const double var_540 = var_57 + var_218; + const double var_541 = 0.3750000000000000000000000*var_539 + var_387 + var_500 + 0.7500000000000000000000000*var_538 + 0.0625000000000000000000000*var_536 + var_134*var_181 + var_530 + 0.2500000000000000000000000*var_533 + 0.5000000000000000000000000*var_119 + var_22*var_532 + 0.1250000000000000000000000*var_540; + const double var_542 = 0.0258928571428571410728559*var_171; + const double var_543 = -var_19*var_8*w[0][9] + var_353; + const double var_544 = var_543 + var_55; + const double var_545 = var_131*var_22; + const double var_546 = var_545 + var_468; + const double var_547 = 0.2410714285714285476380780*var_94 + 0.1125000000000000027755576*var_326 + 0.1607142857142856984253854*var_527 + 0.0401785714285714246063463*var_125 + 0.2008928571428571230317317*var_162 + 0.0803571428571428492126927*var_374 + var_542 + 0.0160714285714285698425385*var_261 + 0.1285714285714285587403083*var_541 + 0.0339285714285714259941251*var_546 + var_529 + 0.0464285714285714301574615*var_420 + 0.0562500000000000013877788*var_113 + 0.0598214285714285670669810*var_525 + 0.2250000000000000055511151*var_453 + 0.2571428571428571174806166*var_544; + A[87] = 6.7500000000000000000000000*var_237*var_547/(var_238*var_238*var_238); + const double var_548 = 0.4017857142857142460634634*var_409; + const double var_549 = var_99 + var_11; + const double var_550 = var_20*var_8*w[0][5]; + const double var_551 = var_19*var_3*w[0][17]; + const double var_552 = var_550 + -var_1*var_549*var_7 + var_551; + const double var_553 = var_243 + var_525; + const double var_554 = var_241 + var_468; + const double var_555 = var_157 + var_41 + var_75 + var_143; + const double var_556 = var_184 + var_192 + var_205; + const double var_557 = var_475 + var_261; + const double var_558 = var_317 + var_557 + var_518; + const double var_559 = -var_1*var_7*var_8*w[0][14] + var_200; + const double var_560 = -var_1*var_3*var_7*w[0][3] + var_198; + const double var_561 = var_63 + var_560 + var_559; + const double var_562 = var_365 + var_78 + var_470; + const double var_563 = var_248 + var_332; + const double var_564 = -var_3*var_7*var_8*w[0][6] + var_79; + const double var_565 = var_564 + var_495; + const double var_566 = -var_3*var_7*var_8*w[0][7] + var_433; + const double var_567 = var_1*var_20*w[0][5]; + const double var_568 = -var_1*var_3*var_8*w[0][15] + var_567; + const double var_569 = var_566 + var_568; + const double var_570 = var_545 + var_323; + const double var_571 = var_133 + var_570; + const double var_572 = var_17*var_20*w[0][9] + var_18*var_19*w[0][19] + 1.5000000000000000000000000*var_424; + const double var_573 = 10.6982142857142861203101347*var_563 + 2.7000000000000001776356839*var_562 + 0.2035714285714285698425385*var_561 + 4.2982142857142857650387668*var_554 + 2.9035714285714284699224663*var_51 + 6.2678571428571423496123316*var_558 + 1.8375000000000001332267630*var_213 + 0.7303571428571428159060019*var_571 + 1.7357142857142857650387668*var_556 + 12.8946428571428572951163005*var_553 + 8.5964285714285715300775337*var_171 + 1.4607142857142856318120039*var_138 + 5.4000000000000003552713679*var_565 + 12.5357142857142846992246632*var_552 + 3.4714285714285715300775337*var_572 + 0.1017857142857142849212693*var_555 + 3.6750000000000002664535259*var_569 + 2.5928571428571429713372254*var_88 + 5.5017857142857140573255492*var_164 + 0.3053571428571428270082322*var_455; + A[0] = 0.2500000000000000000000000*var_237*var_573/(var_238*var_238*var_238); + A[210] = A[0]; + const double var_574 = var_317 + var_113; + A[7] = 1.5000000000000000000000000*var_237*var_494/(var_238*var_238*var_238); + const double var_575 = var_20*var_7*w[0][16] + -var_19*var_8*w[0][6]; + const double var_576 = var_285 + var_129; + const double var_577 = var_153 + var_210; + const double var_578 = 5.4000000000000003552713679*var_297 + 8.5964285714285715300775337*var_131 + 5.1964285714285711748061658*var_515 + 1.4607142857142856318120039*var_576 + 3.4714285714285715300775337*var_91 + 16.2107142857142854097673990*var_155 + 12.5357142857142846992246632*var_469 + 3.6750000000000002664535259*var_37 + 0.2035714285714285698425385*var_577; + A[42] = 0.1250000000000000000000000*var_22*var_237*var_578/(var_238*var_238*var_238); + const double var_579 = -var_19*var_3*w[0][15] + var_567; + const double var_580 = var_136*var_26; + const double var_581 = var_370 + var_580; + const double var_582 = 1.8000000000000000444089210*var_424 + 0.2428571428571428547638078*var_376; + const double var_583 = 0.0160714285714285698425385*var_380; + const double var_584 = 0.2000000000000000111022302*var_129*var_22 + var_154; + const double var_585 = 0.0803571428571428492126927*var_584; + const double var_586 = var_583 + var_585; + const double var_587 = var_29 + var_218; + const double var_588 = var_246 + 0.2500000000000000000000000*var_244; + const double var_589 = 0.2142857142857142738190390*var_127 + var_406; + const double var_590 = var_203 + var_209; + const double var_591 = var_265 + var_413; + const double var_592 = var_591 + var_329; + const double var_593 = var_43 + var_190; + const double var_594 = var_411 + var_262; + const double var_595 = var_25 + var_277; + const double var_596 = var_40 + var_208; + const double var_597 = var_560 + var_566 + var_219; + const double var_598 = var_100*var_254; + const double var_599 = var_448 + var_598; + const double var_600 = 2.7142857142857139685077072*var_191 + 1.2857142857142855874030829*var_210 + 1.5000000000000000000000000*var_148; + const double var_601 = 3.0000000000000000000000000*var_596 + var_22*var_600 + 0.4285714285714285476380780*var_599 + 7.5714285714285711748061658*var_384 + var_597; + const double var_602 = -var_3*w[0][8]; + const double var_603 = 15.5000000000000000000000000*var_114 + var_602; + const double var_604 = var_19*w[0][18] + -var_134*w[0][13] + var_603*var_8; + const double var_605 = var_163 + var_415; + const double var_606 = 2.7500000000000000000000000*var_160 + var_604*var_7 + 3.0000000000000000000000000*var_605 + var_134*var_8*w[0][3]; + const double var_607 = var_582 + 1.4464285714285713968507707*var_381 + 1.9285714285714283811046243*var_485 + 1.6071428571428569842538536*var_594 + 2.2500000000000000000000000*var_589 + 1.3500000000000000888178420*var_320 + var_548 + 1.1250000000000000000000000*var_579 + 0.0642857142857142793701541*var_606 + 0.9000000000000000222044605*var_300 + 0.4821428571428570952761561*var_225 + 0.1464285714285714357085766*var_587 + 4.0178571428571423496123316*var_259 + 0.2250000000000000055511151*var_601 + 3.2142857142857139685077072*var_588 + 0.5785714285714285143313873*var_159 + 0.3232142857142857317320761*var_364 + 0.0500000000000000027755576*var_419 + 1.1750000000000000444089210*var_581 + 2.4107142857142855874030829*var_592 + 0.0803571428571428492126927*var_595 + 0.4500000000000000111022302*var_590 + 0.3892857142857142904723844*var_362 + var_586 + 0.3214285714285713968507707*var_593; + A[86] = 3.3750000000000000000000000*var_237*var_607/(var_238*var_238*var_238); + A[201] = 0.0000000000000000000000000; + const double var_608 = 0.5000000000000000000000000*var_203; + const double var_609 = var_184 + var_608; + const double var_610 = var_182 + var_609; + const double var_611 = 0.0848214285714285615158659*var_171; + const double var_612 = var_20*var_7*w[0][13]; + const double var_613 = -var_1*var_20*w[0][8] + var_430; + const double var_614 = var_186*var_4 + var_187*var_5; + const double var_615 = 0.0803571428571428492126927*var_22*var_296 + 0.0419642857142857109153944*var_134*var_135 + 0.0178571428571428561515866*var_525 + 0.0964285714285714190552312*var_614; + const double var_616 = 0.5000000000000000000000000*var_244 + 0.2500000000000000000000000*var_144 + var_67 + 1.5000000000000000000000000*var_60; + const double var_617 = 0.2892857142857142571656937*var_182 + 0.0160714285714285698425385*var_468; + const double var_618 = 0.3892857142857142904723844*var_131*var_26 + 0.6750000000000000444089210*var_156; + const double var_619 = var_159 + var_566 + var_491 + var_545; + const double var_620 = -var_20*var_7*w[0][14] + var_526; + const double var_621 = var_441 + var_470; + const double var_622 = 0.7500000000000000000000000*var_71 + var_369 + var_620 + 0.5000000000000000000000000*var_452 + var_621; + const double var_623 = 0.0017857142857142856585267*var_171; + const double var_624 = var_317 + var_475; + const double var_625 = var_204 + var_372; + const double var_626 = 0.1928571428571428381104624*var_76 + 0.4339285714285714412596917*var_50 + 0.0080357142857142849212693*var_619 + var_615 + 0.0321428571428571396850771*var_622 + var_417 + 0.1607142857142856984253854*var_616 + 0.0642857142857142793701541*var_22*var_89 + 0.0160714285714285698425385*var_613 + 0.1464285714285714357085766*var_134*var_136 + 0.0482142857142857095276156*var_398 + 0.2571428571428571174806166*var_575 + 0.1366071428571428436615776*var_1*var_12*var_3 + 0.0803571428571428492126927*var_94 + 0.0062500000000000003469447*var_29 + 0.0044642857142857140378966*var_362 + 0.0741071428571428575393654*var_129*var_26 + 0.5000000000000000000000000*var_618 + 0.0883928571428571341339619*var_498 + 0.0401785714285714246063463*var_624 + var_623 + var_617 + 0.1285714285714285587403083*var_222 + 0.1125000000000000027755576*var_625 + 0.2330357142857142904723844*var_534*var_7*var_8; + A[66] = 6.7500000000000000000000000*var_237*var_626/(var_238*var_238*var_238); + A[333] = A[66]; + A[241] = 0.0000000000000000000000000; + const double var_627 = var_1*var_19*w[0][4]; + const double var_628 = var_245 + var_627; + const double var_629 = 28.5000000000000000000000000*var_95 + 27.0000000000000000000000000*var_100 + 44.2500000000000000000000000*var_61 + 29.5000000000000000000000000*var_357; + const double var_630 = 1.3178571428571428381104624*var_154 + 0.7107142857142857428343063*var_129*var_22; + const double var_631 = var_74 + var_77; + const double var_632 = var_184 + var_127 + var_413; + const double var_633 = 1.8678571428571428825193834*var_171; + const double var_634 = var_18*var_3*var_7*w[0][16] + var_1*var_17*var_8*w[0][6]; + const double var_635 = var_634 + var_132; + const double var_636 = 8.9000000000000003552713679*var_257 + 9.0000000000000000000000000*var_10; + const double var_637 = var_365 + var_414; + const double var_638 = var_87 + var_106; + const double var_639 = var_144 + var_265; + const double var_640 = 17.0000000000000000000000000*var_76 + 163.0000000000000000000000000*var_85 + 69.0000000000000000000000000*var_129*var_26 + 41.0000000000000000000000000*var_142 + var_506 + 9.0000000000000000000000000*var_148*var_22 + 181.0000000000000000000000000*var_43 + 19.0000000000000000000000000*var_639 + 127.0000000000000000000000000*var_261 + 137.0000000000000000000000000*var_332 + var_244 + 83.0000000000000000000000000*var_638; + const double var_641 = var_630 + 1.0607142857142857206298459*var_55 + 1.4464285714285713968507707*var_92 + 0.4821428571428570952761561*var_1*var_3*var_636 + 3.5035714285714285587403083*var_65 + 0.7071428571428570730716956*var_395 + 0.3857142857142856762209249*var_57 + 0.6750000000000000444089210*var_174 + 5.8178571428571430601550674*var_163 + 0.2892857142857142571656937*var_632 + 4.3714285714285709971704819*var_48 + 0.0767857142857142765945966*var_136*var_22 + 1.9357142857142857206298459*var_525 + 1.0124999999999999555910790*var_208 + 0.3214285714285713968507707*var_628 + 0.4017857142857142460634634*var_145 + 0.0678571428571428519882502*var_468 + 1.5267857142857141905523122*var_631 + 0.7232142857142856984253854*var_40 + 3.6678571428571427048836995*var_243 + 0.1928571428571428381104624*var_452 + 1.8196428571428571174806166*var_134*var_135 + 0.9642857142857141905523122*var_58 + 0.0321428571428571396850771*var_635 + 1.8000000000000000444089210*var_241 + var_633 + 2.7642857142857142349612332*var_637 + 0.8839285714285713968507707*var_475 + 2.7964285714285712636240078*var_53 + 0.0446428571428571438484134*var_370 + 0.0803571428571428492126927*var_620 + 3.4553571428571427937015414*var_251*var_26 + 0.1125000000000000027755576*var_38 + 4.7410714285714279370154145*var_248 + 0.0642857142857142793701541*var_629*var_7*var_8 + 0.0160714285714285698425385*var_640; + A[8] = 0.3750000000000000000000000*var_237*var_641/(var_238*var_238*var_238); + A[218] = A[8]; + const double var_642 = 0.6250000000000000000000000*var_43 + 1.1250000000000000000000000*var_163; + A[385] = 0.0000000000000000000000000; + const double var_643 = -var_1*var_7*var_8*w[0][16] + var_484; + A[332] = A[46]; + A[193] = 0.0000000000000000000000000; + A[229] = 0.0000000000000000000000000; + A[47] = 1.5000000000000000000000000*var_237*var_360/(var_238*var_238*var_238); + A[352] = A[47]; + const double var_644 = var_19*var_7*w[0][15]; + const double var_645 = -var_20*var_8*w[0][5] + var_644; + const double var_646 = var_379 + var_162; + const double var_647 = var_182 + var_192; + const double var_648 = 0.3000000000000000444089210*var_37 + var_251; + const double var_649 = var_317 + var_208; + const double var_650 = 1.5000000000000000000000000*var_381 + var_22*var_648 + 0.5000000000000000000000000*var_212 + var_645 + 1.7000000000000001776356839*var_67 + 0.6000000000000000888178420*var_156 + 0.1000000000000000055511151*var_646 + var_305 + 0.2000000000000000111022302*var_647 + var_649; + const double var_651 = var_248 + 0.5000000000000000000000000*var_254*var_373; + A[34] = 0.0000000000000000000000000; + const double var_652 = var_39 + var_37; + const double var_653 = var_19*var_8*w[0][5]; + A[137] = 0.0000000000000000000000000; + A[110] = 0.0000000000000000000000000; + A[221] = 0.0000000000000000000000000; + const double var_654 = var_145 + var_596; + const double var_655 = var_340 + var_192 + var_125; + const double var_656 = var_20*var_8*w[0][9]; + const double var_657 = -var_1*var_7*var_8*w[0][19] + var_656; + const double var_658 = var_110 + var_657 + var_90 + 0.5000000000000000000000000*var_413 + var_400; + const double var_659 = 0.0281250000000000006938894*var_413 + 0.0272321428571428575393654*var_131*var_26; + A[341] = 0.0000000000000000000000000; + const double var_660 = 0.0160714285714285698425385*var_259; + const double var_661 = 0.0803571428571428492126927*var_310; + const double var_662 = var_660 + var_661; + const double var_663 = var_545 + var_443 + var_203 + var_160; + const double var_664 = var_317 + var_323; + const double var_665 = var_57 + var_616 + var_664; + const double var_666 = 0.2500000000000000000000000*var_211; + const double var_667 = var_279 + var_215; + const double var_668 = var_184 + var_372; + const double var_669 = 0.2500000000000000000000000*var_470; + const double var_670 = var_409 + var_134*var_37 + 3.0000000000000000000000000*var_1*var_112*var_3; + const double var_671 = 1.3500000000000000888178420*var_415 + var_481 + var_669 + 0.2000000000000000111022302*var_665 + 0.3000000000000000444089210*var_145 + 0.1000000000000000055511151*var_663 + var_666 + 1.2500000000000000000000000*var_398 + var_656 + 0.0500000000000000027755576*var_497 + 0.5000000000000000000000000*var_369 + 0.1500000000000000222044605*var_98 + -var_19*var_7*w[0][19] + 1.7000000000000001776356839*var_668 + 1.5000000000000000000000000*var_197 + 1.1000000000000000888178420*var_667 + 0.5500000000000000444089210*var_670 + 0.9000000000000000222044605*var_365 + 0.4500000000000000111022302*var_566; + const double var_672 = 0.2607142857142857317320761*var_376; + const double var_673 = var_241 + var_262; + const double var_674 = var_518 + var_115; + const double var_675 = 0.3214285714285713968507707*var_671 + 0.0607142857142857136909520*var_270 + 0.1125000000000000027755576*var_673 + 0.2250000000000000055511151*var_478 + 0.1482142857142857150787307*var_362 + 0.1285714285714285587403083*var_226 + 0.2571428571428571174806166*var_208 + 0.1428571428571428492126927*var_193 + 0.2446428571428571341339619*var_364 + var_672 + var_662 + var_617 + 0.3375000000000000222044605*var_674; + A[108] = 3.3750000000000000000000000*var_237*var_675/(var_238*var_238*var_238); + A[375] = A[108]; + A[138] = 0.0000000000000000000000000; + A[348] = 0.0000000000000000000000000; + const double var_676 = var_354 + var_57; + const double var_677 = var_8*w[0][19] + -var_7*w[0][9]; + const double var_678 = var_1*var_3*var_677; + const double var_679 = var_678 + var_608; + const double var_680 = var_38 + var_441; + A[320] = 0.0000000000000000000000000; + A[14] = 0.0000000000000000000000000; + const double var_681 = 0.5000000000000000000000000*var_254*var_325 + var_332; + const double var_682 = var_681 + var_507; + const double var_683 = var_182 + var_110; + const double var_684 = 0.1687500000000000111022302*var_683; + const double var_685 = var_1*w[0][18] + var_602; + const double var_686 = -var_447 + var_3*var_3*var_8*w[0][3] + var_254*var_685; + const double var_687 = 0.5000000000000000000000000*var_686 + var_491; + const double var_688 = var_651 + var_687; + const double var_689 = 19.2857142857142846992246632*var_155 + 1.1714285714285714856686127*var_129 + 9.4000000000000003552713679*var_131; + const double var_690 = 0.0482142857142857095276156*var_688 + 0.0285714285714285705364279*var_130 + var_684 + 0.2008928571428571230317317*var_141 + 0.2250000000000000055511151*var_254*var_319 + 0.0312500000000000000000000*var_26*var_689; + const double var_691 = var_20*var_3*w[0][13]; + const double var_692 = -var_1*var_19*w[0][3] + var_691; + const double var_693 = var_475 + var_77; + const double var_694 = var_534*var_7*var_8; + const double var_695 = var_38 + var_694 + var_142; + const double var_696 = var_170 + var_254*var_510 + var_240; + const double var_697 = var_560 + var_144 + 0.1000000000000000055511151*var_392 + var_621; + const double var_698 = var_1*var_19*w[0][0]; + const double var_699 = var_698 + var_242; + const double var_700 = var_87 + 0.5000000000000000000000000*var_114*var_254; + const double var_701 = var_92 + var_700; + const double var_702 = -var_1*var_7*var_8*w[0][17] + var_288; + const double var_703 = var_702 + var_106; + const double var_704 = var_201 + var_58; + const double var_705 = 0.0482142857142857095276156*var_703 + 0.0732142857142857178542883*var_699 + var_690 + 0.0651785714285714329330190*var_525 + 0.8035714285714284921269268*var_50 + 0.0446428571428571438484134*var_545 + 0.6910714285714285587403083*var_53 + 0.1571428571428571396850771*var_134*var_136 + 0.0642857142857142793701541*var_317 + 0.0285714285714285705364279*var_468 + 0.2892857142857142571656937*var_701 + 0.3696428571428571063783863*var_7*var_8*var_95 + 0.1205357142857142738190390*var_498 + 0.0241071428571428547638078*var_48 + 0.0116071428571428575393654*var_129*var_134 + 0.4500000000000000111022302*var_55 + 0.0562500000000000013877788*var_692 + 0.4821428571428570952761561*var_527 + 0.1446428571428571285828468*var_154 + 0.0366071428571428589271441*var_696 + 0.1607142857142856984253854*var_71 + 0.2410714285714285476380780*var_695 + 0.2330357142857142904723844*var_65 + 0.4017857142857142460634634*var_333 + 0.0321428571428571396850771*var_693 + 0.0803571428571428492126927*var_697 + 0.3214285714285713968507707*var_704; + A[84] = 13.5000000000000000000000000*var_237*var_705/(var_238*var_238*var_238); + A[294] = A[84]; + const double var_706 = var_96 + var_60; + const double var_707 = 0.2500000000000000000000000*var_149; + const double var_708 = var_707 + 0.0500000000000000027755576*var_71 + 0.2000000000000000111022302*var_209 + 1.8000000000000000444089210*var_191*var_22 + var_669; + const double var_709 = 0.0285714285714285705364279*var_133 + 0.0678571428571428519882502*var_376; + const double var_710 = 1.5357142857142855874030829*var_126 + 0.2571428571428571174806166*var_189 + 2.9000000000000003552713679*var_148 + 0.4928571428571428270082322*var_136 + 0.6428571428571427937015414*var_91 + var_502; + const double var_711 = var_101 + var_144 + var_261; + const double var_712 = 0.0964285714285714190552312*var_657; + const double var_713 = var_265 + var_184; + const double var_714 = var_613 + var_244; + const double var_715 = -var_20*var_3*w[0][17] + var_118; + const double var_716 = -var_19*var_8*w[0][7] + var_386; + const double var_717 = var_716 + var_715; + const double var_718 = var_518 + var_106; + const double var_719 = var_474 + var_208; + const double var_720 = var_413 + var_491; + const double var_721 = 33.0000000000000000000000000*var_115 + 12.7000000000000010658141036*var_277 + 6.7000000000000001776356839*var_398 + 20.2000000000000028421709430*var_246 + 13.7000000000000010658141036*var_380 + 6.6000000000000005329070518*var_58 + var_20*var_8*w[0][8] + 11.4000000000000003552713679*var_204 + 16.3000000000000007105427358*var_259 + -var_19*var_7*w[0][18] + 29.5000000000000000000000000*var_329 + 5.0000000000000000000000000*var_206 + 3.8000000000000002664535259*var_182 + 25.4000000000000021316282073*var_381 + 23.0000000000000000000000000*var_113 + 18.6000000000000014210854715*var_294 + 5.5000000000000000000000000*var_225 + 2.5000000000000000000000000*var_262 + 15.5000000000000000000000000*var_383 + 1.9000000000000001332267630*var_226 + 8.3000000000000007105427358*var_720; + const double var_722 = 0.5544642857142857428343063*var_713 + 0.5062499999999999777955395*var_718 + 0.1928571428571428381104624*var_488 + 1.4303571428571428825193834*var_160 + 0.4017857142857142460634634*var_719 + 1.1250000000000000000000000*var_717 + 0.2531249999999999888977698*var_365 + 0.3062500000000000222044605*var_241 + 0.0531250000000000055511151*var_129*var_26 + var_439 + 0.5625000000000000000000000*var_22*var_710 + 0.9642857142857141905523122*var_217 + 1.0446428571428569842538536*var_25 + 0.2892857142857142571656937*var_678 + 0.4321428571428571063783863*var_362 + 0.2089285714285714357085766*var_87 + 0.3767857142857142793701541*var_131*var_134 + 0.0964285714285714190552312*var_395 + 0.1687500000000000111022302*var_543 + 0.0803571428571428492126927*var_348 + 0.0714285714285714246063463*var_419 + 1.7830357142857142793701541*var_364 + 0.3053571428571428270082322*var_711 + var_712 + 0.0995535714285714218307888*var_136*var_26 + 0.2571428571428571174806166*var_714 + 0.0401785714285714246063463*var_721; + A[5] = 1.5000000000000000000000000*var_237*var_722/(var_238*var_238*var_238); + A[174] = 0.0000000000000000000000000; + const double var_723 = var_1*var_257*var_3; + const double var_724 = var_113 + var_141 + var_29 + var_580 + var_579 + var_162 + var_50; + const double var_725 = var_74 + var_40 + var_475; + const double var_726 = 9.0000000000000000000000000*var_373*var_7*var_8; + const double var_727 = var_145 + var_332; + const double var_728 = var_726 + 37.0000000000000000000000000*var_1*var_3*var_34 + 17.0000000000000000000000000*var_109*var_26 + var_724 + 19.0000000000000000000000000*var_725 + 11.0000000000000000000000000*var_727; + const double var_729 = var_550 + var_723 + -var_19*var_7*w[0][15] + 0.1428571428571428492126927*var_728; + A[323] = 0.0000000000000000000000000; + const double var_730 = 23.5000000000000000000000000*var_10 + 19.0000000000000000000000000*var_9; + const double var_731 = var_347 + 0.2500000000000000000000000*var_379; + const double var_732 = var_13*var_8 + var_14*var_7; + const double var_733 = var_26*var_6 + var_267 + var_518 + 3.0000000000000000000000000*var_36 + var_157 + var_211 + var_22*var_732 + var_289 + var_649 + var_63; + const double var_734 = var_20*var_3*w[0][17]; + const double var_735 = var_653 + -var_118 + 0.6000000000000000888178420*var_733 + 2.2000000000000001776356839*var_46 + -var_121 + var_143 + var_734; + A[165] = A[108]; + A[383] = 0.0000000000000000000000000; + const double var_736 = 0.2500000000000000000000000*var_145 + var_65 + 0.5000000000000000000000000*var_379 + 1.5000000000000000000000000*var_62; + const double var_737 = 8.8714285714285718853489016*var_91 + 4.0499999999999998223643161*var_297 + 4.9000000000000003552713679*var_131 + 8.0999999999999996447286321*var_469 + 1.5928571428571427492926205*var_135 + 6.4285714285714279370154145*var_37 + 5.3357142857142854097673990*var_272; + const double var_738 = -var_8*w[0][14] + var_7*w[0][4]; + const double var_739 = var_254*var_738 + var_3*var_8*var_8*w[0][16] + -var_1*var_7*var_7*w[0][6]; + const double var_740 = 51.0000000000000000000000000*var_95 + 120.5000000000000000000000000*var_534; + const double var_741 = var_475 + var_277; + const double var_742 = var_85 + var_380; + const double var_743 = var_289 + var_392; + const double var_744 = var_343 + var_284; + const double var_745 = var_207 + var_39; + const double var_746 = 423.0000000000000000000000000*var_252 + 140.1428571428571387968986528*var_745 + 216.1428571428571387968986528*var_136; + const double var_747 = 0.0125000000000000006938894*var_134*var_746 + 0.1250000000000000000000000*var_22*var_737 + 1.5267857142857141905523122*var_498 + var_437 + 0.0321428571428571396850771*var_7*var_740*var_8 + 0.1526785714285714135041161*var_741 + 0.6589285714285714190552312*var_144 + 0.4660714285714285809447688*var_379 + 0.1062500000000000111022302*var_468 + 0.2250000000000000055511151*var_743 + 2.1857142857142854985852409*var_332 + 2.8285714285714282922867824*var_45 + 1.4142857142857141461433912*var_739 + 0.6910714285714285587403083*var_347 + 5.2875000000000005329070518*var_162 + 0.4616071428571428270082322*var_525 + 1.8321428571428570730716956*var_53 + 0.3053571428571428270082322*var_106 + 0.3776785714285714190552312*var_742 + 0.3553571428571428714171532*var_744; + const double var_748 = 9.0000000000000000000000000*var_1*var_3*var_325; + const double var_749 = var_92 + 0.5000000000000000000000000*var_57 + var_26*var_281; + const double var_750 = var_226 + var_244 + var_259; + const double var_751 = var_475 + var_206; + const double var_752 = var_127 + var_182; + const double var_753 = var_149 + var_208; + const double var_754 = 17.0000000000000000000000000*var_752 + var_109*var_134 + var_122 + 11.0000000000000000000000000*var_750 + 13.0000000000000000000000000*var_751 + var_137*var_26 + 19.0000000000000000000000000*var_753; + const double var_755 = var_29 + var_262; + A[119] = 0.0000000000000000000000000; + A[309] = 0.0000000000000000000000000; + const double var_756 = 8.9000000000000003552713679*var_534 + 9.0000000000000000000000000*var_357; + const double var_757 = 2.3571428571428572062984586*var_319*var_8 + var_20*w[0][18] + 2.0714285714285711748061658*var_405*var_8; + const double var_758 = 0.6428571428571427937015414*var_149; + const double var_759 = var_666 + 2.9642857142857139685077072*var_189*var_22 + 0.6071428571428570952761561*var_209 + 3.0714285714285711748061658*var_383 + 0.9285714285714284921269268*var_349 + 1.4642857142857141905523122*var_77 + var_225 + 5.8571428571428567622092487*var_329 + var_7*var_757 + 1.8571428571428569842538536*var_381 + 0.3214285714285713968507707*var_127 + var_758 + var_47; + const double var_760 = var_19*var_8*w[0][9]; + const double var_761 = -var_20*var_7*w[0][19] + var_760; + const double var_762 = var_250 + var_150; + const double var_763 = var_183 + 0.7500000000000000000000000*var_762; + const double var_764 = 0.0482142857142857095276156*var_134*var_763; + const double var_765 = 1.8000000000000000444089210*var_181 + 0.6968750000000000222044605*var_129 + 3.0312500000000000000000000*var_131 + 6.1312500000000005329070518*var_155 + 1.4625000000000001332267630*var_109; + const double var_766 = 0.3616071428571428492126927*var_192; + const double var_767 = 0.1125000000000000027755576*var_759 + 0.2500000000000000000000000*var_630 + 0.1406250000000000000000000*var_115 + 0.5464285714285713746463102*var_217 + 0.1428571428571428492126927*var_134*var_765 + 0.1205357142857142738190390*var_203 + 0.0169642857142857129970626*var_131*var_22 + 0.0321428571428571396850771*var_10*var_254 + 0.0642857142857142793701541*var_409 + 0.0191964285714285691486491*var_25 + 0.0464285714285714301574615*var_364 + 0.0272321428571428575393654*var_511 + 0.3857142857142856762209249*var_761 + var_764 + var_766; + A[43] = 1.5000000000000000000000000*var_237*var_767/(var_238*var_238*var_238); + A[253] = A[43]; + const double var_768 = var_278 + var_760; + const double var_769 = w[0][5] + 0.2500000000000000000000000*w[0][6]; + const double var_770 = 1.0625000000000000000000000*var_150*var_26 + 1.1250000000000000000000000*var_211; + const double var_771 = w[0][15] + 0.2500000000000000000000000*w[0][16]; + const double var_772 = 0.3750000000000000000000000*var_265 + 0.2500000000000000000000000*var_76; + const double var_773 = var_383 + var_246; + const double var_774 = var_190 + var_413; + const double var_775 = var_374 + var_215; + const double var_776 = var_125 + var_160; + const double var_777 = 0.1250000000000000000000000*var_259 + var_206 + 2.3750000000000000000000000*var_244 + 0.0625000000000000000000000*var_159 + var_305 + var_178*var_7*var_771 + var_772 + -var_176*var_769*var_8 + 1.1250000000000000000000000*var_774 + var_770 + 3.3750000000000000000000000*var_204 + 2.7500000000000000000000000*var_773 + 2.2500000000000000000000000*var_610 + 1.4375000000000000000000000*var_226 + 2.0625000000000000000000000*var_775 + 2.8750000000000000000000000*var_415 + 3.2500000000000000000000000*var_409 + 8.2500000000000000000000000*var_294 + 1.1875000000000000000000000*var_776 + 5.3750000000000000000000000*var_398; + const double var_778 = var_545 + var_25; + const double var_779 = var_197 + 2.2500000000000000000000000*var_372 + var_188; + const double var_780 = 0.0133928571428571421136899*var_778 + 0.2410714285714285476380780*var_406 + 0.0205357142857142856151587*var_218 + var_378 + 0.0803571428571428492126927*var_113 + 0.0339285714285714259941251*var_419 + 0.0428571428571428575393654*var_777 + 0.0142857142857142852682140*var_270 + 0.0410714285714285712303173*var_362 + 0.0151785714285714284227380*var_29 + 0.2571428571428571174806166*var_768 + 0.0392857142857142849212693*var_364 + 0.0401785714285714246063463*var_395 + 0.0017857142857142856585267*var_580 + 0.0535714285714285684547598*var_708 + 0.1500000000000000222044605*var_779; + A[69] = 40.5000000000000000000000000*var_237*var_780/(var_238*var_238*var_238); + A[279] = A[69]; + const double var_781 = var_241 + var_748; + const double var_782 = 0.0562500000000000013877788*var_645 + 0.0883928571428571341339619*var_381 + 0.1607142857142856984253854*var_708; + A[31] = 0.0000000000000000000000000; + A[287] = 0.0000000000000000000000000; + A[223] = 0.0000000000000000000000000; + A[243] = 0.0000000000000000000000000; + const double var_783 = var_127 + var_584; + A[367] = 0.0000000000000000000000000; + const double var_784 = 0.3294642857142857095276156*var_340 + 0.1776785714285714357085766*var_135*var_22; + const double var_785 = 0.1000000000000000055511151*var_469 + var_91 + 0.2000000000000000111022302*var_297; + const double var_786 = var_726 + var_468; + const double var_787 = 0.8857142857142856762209249*var_129 + var_251; + const double var_788 = var_716 + 0.3714285714285714412596917*var_142 + var_134*var_787 + 2.3714285714285714412596917*var_22*var_37; + const double var_789 = var_254*var_257 + var_255*var_7*var_8; + const double var_790 = var_380 + 0.5000000000000000000000000*var_789; + const double var_791 = 0.0714285714285714246063463*var_511 + 0.2142857142857142738190390*var_53 + 1.2142857142857141905523122*var_681 + 2.9285714285714283811046243*var_790 + -var_19*var_8*w[0][3] + 0.2500000000000000000000000*var_106 + var_612; + const double var_792 = 0.2571428571428571174806166*var_500 + var_712 + var_784 + 0.1205357142857142738190390*var_58 + 0.3616071428571428492126927*var_22*var_785 + 0.0111607142857142859621034*var_525 + 0.0321428571428571396850771*var_475 + 0.0191964285714285691486491*var_786 + 0.1406250000000000000000000*var_788 + var_339 + 0.1125000000000000027755576*var_791; + A[48] = 1.5000000000000000000000000*var_237*var_792/(var_238*var_238*var_238); + A[258] = A[48]; + const double var_793 = var_42 + var_691; + const double var_794 = var_84 + var_440; + const double var_795 = var_250 + var_251; + const double var_796 = var_37 + var_126 + 1.1250000000000000000000000*var_795; + const double var_797 = 19.0000000000000000000000000*var_257 + 17.0000000000000000000000000*var_10; + const double var_798 = var_1*var_3*var_797 + var_25 + 29.0000000000000000000000000*var_248 + var_209; + const double var_799 = var_159 + var_74; + const double var_800 = var_219 + var_58; + const double var_801 = 0.3750000000000000000000000*var_799 + 0.0625000000000000000000000*var_798 + var_794 + 0.2500000000000000000000000*var_94 + var_496 + var_26*var_796 + 0.5000000000000000000000000*var_122 + var_707 + var_305 + var_134*var_189 + 0.7500000000000000000000000*var_654 + 0.1250000000000000000000000*var_800; + const double var_802 = var_53 + var_314; + const double var_803 = var_241 + var_323; + const double var_804 = var_57 + var_414; + const double var_805 = var_615 + var_542 + 0.1285714285714285587403083*var_801 + 0.1607142857142856984253854*var_793 + 0.0464285714285714301574615*var_581 + 0.1125000000000000027755576*var_702 + 0.2250000000000000055511151*var_804 + 0.0339285714285714259941251*var_803 + 0.0803571428571428492126927*var_395 + 0.2410714285714285476380780*var_96 + 0.0401785714285714246063463*var_127 + 0.0598214285714285670669810*var_243 + 0.0160714285714285698425385*var_475 + 0.2008928571428571230317317*var_163 + 0.2571428571428571174806166*var_802 + 0.0562500000000000013877788*var_115; + A[65] = 6.7500000000000000000000000*var_237*var_805/(var_238*var_238*var_238); + A[103] = A[65]; + A[124] = A[86]; + A[77] = 0.0000000000000000000000000; + A[252] = A[42]; + const double var_806 = var_156 + var_60; + A[299] = A[89]; + const double var_807 = var_1*var_19*w[0][8] + -var_20*var_3*w[0][18]; + const double var_808 = 0.2892857142857142571656937*var_190 + 0.0160714285714285698425385*var_241; + const double var_809 = 0.6750000000000000444089210*var_154 + 0.3892857142857142904723844*var_129*var_22; + const double var_810 = var_160 + var_329 + var_323 + var_568; + const double var_811 = var_443 + var_365; + const double var_812 = 0.5000000000000000000000000*var_414 + 0.7500000000000000000000000*var_74 + var_811 + var_692 + var_768; + const double var_813 = var_406 + var_203; + const double var_814 = var_261 + var_518; + const double var_815 = 0.5000000000000000000000000*var_809 + 0.0160714285714285698425385*var_485 + var_782 + 0.0321428571428571396850771*var_812 + 0.0044642857142857140378966*var_364 + 0.1928571428571428381104624*var_77 + 0.0080357142857142849212693*var_810 + var_529 + 0.0062500000000000003469447*var_25 + 0.0401785714285714246063463*var_814 + 0.0642857142857142793701541*var_26*var_91 + 0.1125000000000000027755576*var_813 + 0.0741071428571428575393654*var_131*var_22 + 0.4339285714285714412596917*var_48 + 0.0482142857142857095276156*var_383 + 0.2330357142857142904723844*var_1*var_257*var_3 + 0.0803571428571428492126927*var_96 + 0.1464285714285714357085766*var_134*var_135 + 0.0883928571428571341339619*var_249 + 0.1285714285714285587403083*var_221 + 0.1607142857142856984253854*var_736 + 0.1366071428571428436615776*var_100*var_7*var_8 + 0.2571428571428571174806166*var_807 + var_623 + var_808; + A[88] = 6.7500000000000000000000000*var_237*var_815/(var_238*var_238*var_238); + A[203] = 0.0000000000000000000000000; + const double var_816 = 0.6428571428571427937015414*var_151; + const double var_817 = 0.2142857142857142738190390*var_125 + var_372; + const double var_818 = var_45 + var_182; + const double var_819 = var_204 + var_206; + const double var_820 = var_340 + var_392; + const double var_821 = var_820 + var_491; + const double var_822 = var_1*var_19*w[0][3]; + const double var_823 = var_397 + var_822; + const double var_824 = var_823 + var_277; + const double var_825 = var_568 + var_559 + var_218; + const double var_826 = var_12*var_254; + const double var_827 = var_446 + var_826; + const double var_828 = 1.2857142857142855874030829*var_207 + 1.5000000000000000000000000*var_150 + 2.7142857142857139685077072*var_183; + const double var_829 = 3.0000000000000000000000000*var_537 + var_825 + 7.5714285714285711748061658*var_409 + var_26*var_828 + 0.4285714285714285476380780*var_827; + const double var_830 = 15.5000000000000000000000000*var_112 + var_504; + const double var_831 = -var_134*w[0][4] + var_3*var_830 + var_20*w[0][6]; + const double var_832 = var_162 + var_381; + const double var_833 = var_134*var_3*w[0][14] + 2.7500000000000000000000000*var_159 + var_1*var_831 + 3.0000000000000000000000000*var_832; + const double var_834 = 0.4500000000000000111022302*var_819 + 4.0178571428571423496123316*var_380 + 1.3500000000000000888178420*var_678 + 0.2250000000000000055511151*var_829 + 1.6071428571428569842538536*var_824 + 0.3232142857142857317320761*var_362 + var_426 + 0.9000000000000000222044605*var_290 + 0.5785714285714285143313873*var_160 + 0.3214285714285713968507707*var_818 + 1.9285714285714283811046243*var_613 + 0.0500000000000000027755576*var_370 + 1.1250000000000000000000000*var_434 + var_582 + 1.4464285714285713968507707*var_415 + 1.1750000000000000444089210*var_420 + 0.3892857142857142904723844*var_364 + 2.2500000000000000000000000*var_817 + 0.4821428571428570952761561*var_226 + 0.1464285714285714357085766*var_423 + var_662 + 0.0803571428571428492126927*var_755 + 2.4107142857142855874030829*var_821 + 3.2142857142857139685077072*var_731 + 0.0642857142857142793701541*var_833; + A[68] = 3.3750000000000000000000000*var_237*var_834/(var_238*var_238*var_238); + A[163] = A[68]; + const double var_835 = var_159 + var_48 + var_598; + const double var_836 = var_207 + var_155; + A[391] = A[29]; + const double var_837 = var_346 + var_612; + const double var_838 = var_331 + var_653; + const double var_839 = var_241 + var_284; + const double var_840 = var_201 + var_470; + const double var_841 = 1.1250000000000000000000000*var_162 + 0.6250000000000000000000000*var_45; + const double var_842 = var_324 + 0.7500000000000000000000000*var_261 + 0.1250000000000000000000000*var_392 + 1.1250000000000000000000000*var_398 + 0.2500000000000000000000000*var_92 + -var_19*var_3*w[0][13] + var_608; + const double var_843 = 19.0000000000000000000000000*var_95 + 23.5000000000000000000000000*var_357; + const double var_844 = var_144 + var_77; + const double var_845 = 13.0000000000000000000000000*var_53 + var_340 + var_7*var_8*var_843 + 8.5000000000000000000000000*var_22*var_297 + 6.5000000000000000000000000*var_379 + 4.5000000000000000000000000*var_211 + 0.5000000000000000000000000*var_844; + const double var_846 = 0.2410714285714285476380780*var_840 + var_611 + 0.1812500000000000222044605*var_131*var_22 + 0.3857142857142856762209249*var_838 + 0.0366071428571428589271441*var_839 + var_690 + 0.0642857142857142793701541*var_289 + 0.4303571428571428270082322*var_134*var_136 + 0.0767857142857142765945966*var_468 + 0.5625000000000000000000000*var_530 + 0.3616071428571428492126927*var_71 + 0.1616071428571428658660381*var_525 + 1.2053571428571427937015414*var_50 + 0.8035714285714284921269268*var_60 + 0.7232142857142856984253854*var_80 + 0.1928571428571428381104624*var_842 + 0.4017857142857142460634634*var_76 + 0.1205357142857142738190390*var_680 + 0.1214285714285714273819039*var_243 + 1.0044642857142855874030829*var_67 + var_583 + 0.0562500000000000013877788*var_475 + 0.9642857142857141905523122*var_841 + 0.1285714285714285587403083*var_837 + 0.4500000000000000111022302*var_314 + 0.4178571428571428714171532*var_98 + 0.0160714285714285698425385*var_845; + A[126] = 13.5000000000000000000000000*var_237*var_846/(var_238*var_238*var_238); + const double var_847 = 2.9000000000000003552713679*var_124 + 1.8571428571428569842538536*var_135 + 0.6428571428571427937015414*var_183 + 0.2571428571428571174806166*var_109 + 0.9000000000000000222044605*var_181 + 1.5357142857142855874030829*var_150 + var_471; + const double var_848 = 11.0000000000000000000000000*var_371 + 12.7500000000000000000000000*var_677; + const double var_849 = var_384 + var_50; + const double var_850 = var_8*w[0][10] + -var_7*w[0][0]; + const double var_851 = var_134*var_466 + var_1*var_3*var_850; + const double var_852 = var_851 + var_370; + const double var_853 = var_579 + var_60; + const double var_854 = var_159 + var_76; + const double var_855 = var_189 + var_105; + const double var_856 = 423.0000000000000000000000000*var_153 + 140.1428571428571387968986528*var_855 + 216.1428571428571387968986528*var_129; + const double var_857 = 2.8125000000000000000000000*var_415 + 0.3553571428571428714171532*var_852 + 0.1285714285714285587403083*var_1*var_3*var_848 + 1.5267857142857141905523122*var_113 + 1.8321428571428570730716956*var_294 + 1.3178571428571428381104624*var_67 + 0.9098214285714285587403083*var_362 + 0.3776785714285714190552312*var_849 + 0.5544642857142857428343063*var_29 + 0.0125000000000000006938894*var_134*var_856 + 0.2250000000000000055511151*var_853 + 0.1526785714285714135041161*var_854 + 1.1250000000000000000000000*var_26*var_847 + 7.7464285714285709971704819*var_687 + 1.0928571428571427492926205*var_141 + 0.1928571428571428381104624*var_204 + 5.2875000000000005329070518*var_398 + 1.2857142857142855874030829*var_206; + A[28] = 0.7500000000000000000000000*var_237*var_857/(var_238*var_238*var_238); + A[161] = A[28]; + A[226] = 0.0000000000000000000000000; + const double var_858 = var_387 + var_62; + const double var_859 = -var_3*var_7*var_8*w[0][5] + var_644; + const double var_860 = var_859 + var_160; + const double var_861 = 0.0125000000000000006938894*var_860 + 0.0357142857142857123031732*var_122 + 0.0285714285714285705364279*var_65 + 0.0714285714285714246063463*var_192 + 0.0071428571428571426341070*var_292 + 0.0089285714285714280757933*var_858 + 0.0267857142857142842273799*var_783; + const double var_862 = 597.0000000000000000000000000*var_153 + 91.5000000000000000000000000*var_189 + 27.0000000000000000000000000*var_469 + 334.5000000000000000000000000*var_105 + 243.0000000000000000000000000*var_91 + 409.0000000000000000000000000*var_466 + 418.5000000000000000000000000*var_297; + const double var_863 = 0.0312500000000000000000000*var_581 + 0.0482142857142857095276156*var_262; + const double var_864 = var_125 + var_431 + var_308 + var_151; + const double var_865 = -var_1*var_3*var_8*w[0][13] + var_324; + const double var_866 = var_683 + var_326 + var_865; + const double var_867 = var_419 + var_28 + var_169*var_254 + var_218; + const double var_868 = 0.5000000000000000000000000*var_867 + var_20*var_3*w[0][10] + var_361; + const double var_869 = 0.1151785714285714218307888*var_806 + 1.0660714285714285587403083*var_226 + 0.5973214285714285587403083*var_206 + 2.2607142857142856762209249*var_415 + 2.7294642857142856762209249*var_491 + 0.4285714285714285476380780*var_384 + 0.0017857142857142856585267*var_134*var_862 + 0.7473214285714285809447688*var_159 + 0.0669642857142857123031732*var_50 + 0.1633928571428571452361922*var_141 + 0.4339285714285714412596917*var_191*var_26 + 0.3187500000000000333066907*var_866 + 0.2785714285714285809447688*var_67 + 1.6633928571428571174806166*var_864 + 1.3848214285714284255135453*var_398 + var_863 + 1.4607142857142856318120039*var_868; + A[1] = 0.2500000000000000000000000*var_237*var_869/(var_238*var_238*var_238); + A[211] = A[1]; + const double var_870 = 11.5714285714285711748061658*var_677 + 6.5000000000000000000000000*var_112 + 4.0714285714285711748061658*var_325; + const double var_871 = 2.1964285714285711748061658*var_391*var_7 + 2.6250000000000000000000000*var_373*var_7 + -var_19*w[0][4]; + const double var_872 = var_406 + var_204; + const double var_873 = var_71 + var_76; + const double var_874 = var_645 + var_873; + const double var_875 = var_694 + var_209; + const double var_876 = var_816 + 0.6785714285714284921269268*var_208 + 0.1250000000000000000000000*var_190 + 3.2321428571428567622092487*var_491 + 0.0178571428571428561515866*var_874 + 2.0357142857142855874030829*var_872 + 1.1964285714285713968507707*var_384 + 4.9285714285714279370154145*var_294 + 3.6071428571428567622092487*var_409 + var_246 + 2.6071428571428572062984586*var_398 + 2.9285714285714283811046243*var_731 + 0.1071428571428571369095195*var_265 + var_8*var_871 + 3.8928571428571427937015414*var_380 + 0.1607142857142856984253854*var_22*var_297 + 0.2500000000000000000000000*var_1*var_3*var_870 + 0.3214285714285713968507707*var_470 + 1.8214285714285713968507707*var_183*var_26 + var_410 + 4.7142857142857144125969171*var_279 + 1.4821428571428569842538536*var_210*var_22 + 3.6428571428571427937015414*var_320 + 0.7321428571428570952761561*var_226 + 0.3392857142857142460634634*var_875; + const double var_877 = 0.0339285714285714259941251*var_31; + const double var_878 = var_481 + 3.0000000000000000000000000*var_203; + const double var_879 = var_575 + var_878; + const double var_880 = var_182 + var_206; + const double var_881 = 0.0803571428571428492126927*var_879 + 0.3816964285714285476380780*var_277 + 0.8437500000000000000000000*var_817 + 0.2308035714285714135041161*var_129*var_134 + 0.6227678571428570952761561*var_415 + 0.0191964285714285691486491*var_131*var_22 + 0.0464285714285714301574615*var_134*var_136 + var_877 + var_659 + 0.5625000000000000000000000*var_613 + 0.0531250000000000055511151*var_135*var_26 + 0.0200892857142857123031732*var_259 + 0.2008928571428571230317317*var_244 + 0.0401785714285714246063463*var_159 + var_784 + var_766 + 0.2209821428571428492126927*var_160 + 0.2571428571428571174806166*var_880 + 0.2250000000000000055511151*var_876; + A[3] = 1.5000000000000000000000000*var_237*var_881/(var_238*var_238*var_238); + A[213] = A[3]; + A[394] = A[89]; + const double var_882 = 0.0053571428571428571924207*var_226 + 0.0214285714285714287696827*var_145 + 0.0321428571428571396850771*var_678 + 0.0267857142857142842273799*var_820; + A[380] = 0.0000000000000000000000000; + A[135] = 0.0000000000000000000000000; + A[384] = 0.0000000000000000000000000; + const double var_883 = 597.0000000000000000000000000*var_155 + 334.5000000000000000000000000*var_109 + 27.0000000000000000000000000*var_250 + 91.5000000000000000000000000*var_181 + 243.0000000000000000000000000*var_89 + 418.5000000000000000000000000*var_251 + 409.0000000000000000000000000*var_239; + const double var_884 = var_859 + var_643 + var_127 + var_149; + const double var_885 = var_19*var_7*w[0][14]; + const double var_886 = -var_3*var_7*var_8*w[0][4] + var_885; + const double var_887 = var_702 + var_427 + var_886; + const double var_888 = var_219 + var_167*var_254 + var_370 + var_24; + const double var_889 = var_19*var_8*w[0][0] + var_363 + 0.5000000000000000000000000*var_888; + const double var_890 = 0.3187500000000000333066907*var_887 + 0.0017857142857142856585267*var_134*var_883 + 2.2607142857142856762209249*var_381 + 1.0660714285714285587403083*var_225 + 0.1633928571428571452361922*var_142 + 0.0669642857142857123031732*var_48 + var_421 + 0.4285714285714285476380780*var_409 + 1.6633928571428571174806166*var_884 + 0.1151785714285714218307888*var_422 + 1.4607142857142856318120039*var_889 + 2.7294642857142856762209249*var_329 + 0.4339285714285714412596917*var_183*var_22 + 1.3848214285714284255135453*var_383 + 0.5973214285714285587403083*var_209 + 0.2785714285714285809447688*var_65 + 0.7473214285714285809447688*var_160; + A[2] = 0.2500000000000000000000000*var_237*var_890/(var_238*var_238*var_238); + A[250] = A[2]; + const double var_891 = var_145 + var_76; + const double var_892 = 0.0142857142857142852682140*var_376; + A[372] = A[48]; + A[12] = 0.0000000000000000000000000; + const double var_893 = var_1*var_334*var_72 + var_3*var_335*var_73; + const double var_894 = 0.5000000000000000000000000*var_330 + var_191; + const double var_895 = 0.0040178571428571424606346*var_893 + 0.1125000000000000027755576*var_74 + 0.0169642857142857129970626*var_218 + 0.0723214285714285642914234*var_134*var_894; + const double var_896 = 0.3294642857142857095276156*var_413 + 0.1776785714285714357085766*var_136*var_26; + const double var_897 = 0.2000000000000000111022302*var_251 + var_89 + 0.1000000000000000055511151*var_250; + const double var_898 = var_297 + 0.8857142857142856762209249*var_131; + const double var_899 = 0.3714285714285714412596917*var_141 + var_134*var_898 + 2.3714285714285714412596917*var_26*var_39 + var_482; + const double var_900 = var_1*var_3*var_738 + var_254*var_534; + const double var_901 = var_259 + 0.5000000000000000000000000*var_900; + const double var_902 = 0.0714285714285714246063463*var_851 + var_627 + 1.2142857142857141905523122*var_651 + 0.2142857142857142738190390*var_55 + 0.2500000000000000000000000*var_110 + 2.9285714285714283811046243*var_901 + -var_20*var_3*w[0][14]; + const double var_903 = var_895 + 0.1205357142857142738190390*var_57 + 0.1406250000000000000000000*var_899 + 0.0111607142857142859621034*var_243 + 0.2571428571428571174806166*var_496 + 0.0191964285714285691486491*var_781 + var_479 + var_896 + 0.3616071428571428492126927*var_26*var_897 + 0.0321428571428571396850771*var_261 + 0.1125000000000000027755576*var_902; + A[26] = 1.5000000000000000000000000*var_237*var_903/(var_238*var_238*var_238); + A[121] = A[26]; + const double var_904 = var_272 + var_252; + A[276] = A[66]; + const double var_905 = 0.0803571428571428492126927*var_518 + 0.0160714285714285698425385*var_226; + const double var_906 = var_145 + -var_1*var_176*w[0][8] + var_178*var_3*w[0][18] + var_62 + 9.0000000000000000000000000*var_26*var_89; + const double var_907 = var_905 + 0.0803571428571428492126927*var_125 + 0.0642857142857142793701541*var_906; + const double var_908 = var_92 + var_414; + const double var_909 = var_178*w[0][17] + 5.1250000000000000000000000*var_1*var_9; + const double var_910 = 0.5000000000000000000000000*var_100*var_7*var_8; + const double var_911 = var_910 + var_58; + const double var_912 = 2.1250000000000000000000000*var_908 + 4.5000000000000000000000000*var_67 + 1.8125000000000000000000000*var_85 + 1.1250000000000000000000000*var_318 + -var_1*var_176*w[0][7] + var_38 + 2.3125000000000000000000000*var_261 + 0.2500000000000000000000000*var_468 + 0.6875000000000000000000000*var_48 + 3.6250000000000000000000000*var_498 + 6.5000000000000000000000000*var_55 + 2.2500000000000000000000000*var_110 + 1.6250000000000000000000000*var_144 + 1.3750000000000000000000000*var_57 + 0.7500000000000000000000000*var_142 + 3.3750000000000000000000000*var_706 + 2.3750000000000000000000000*var_911 + var_3*var_909 + var_412 + 6.3750000000000000000000000*var_87 + 5.7500000000000000000000000*var_53 + 3.2500000000000000000000000*var_76 + 6.6250000000000000000000000*var_50; + const double var_913 = 0.2125000000000000222044605*var_171; + const double var_914 = var_545 + var_77; + const double var_915 = 0.0285714285714285705364279*var_419 + var_907 + 0.4857142857142857095276156*var_270 + var_913 + 1.2053571428571427937015414*var_534*var_7*var_8 + 0.1607142857142856984253854*var_475 + 0.1482142857142857150787307*var_241 + 0.2571428571428571174806166*var_912 + 0.3607142857142857095276156*var_243 + 2.0892857142857139685077072*var_315 + 1.1250000000000000000000000*var_452 + 0.0125000000000000006938894*var_218 + 0.2767857142857142460634634*var_525 + 0.1125000000000000027755576*var_914 + 0.2410714285714285476380780*var_71 + 0.3375000000000000222044605*var_22*var_469 + var_618 + 1.3500000000000000888178420*var_838 + var_585 + 1.2857142857142855874030829*var_841; + A[85] = 3.3750000000000000000000000*var_237*var_915/(var_238*var_238*var_238); + A[295] = A[85]; + A[44] = 0.7500000000000000000000000*var_237*var_747/(var_238*var_238*var_238); + A[292] = A[44]; + const double var_916 = var_80 + var_620; + A[130] = 0.0000000000000000000000000; + const double var_917 = 0.5000000000000000000000000*var_1*var_3*var_444 + var_473; + const double var_918 = 2.0714285714285711748061658*var_3*var_371 + var_19*w[0][6] + 2.3571428571428572062984586*var_3*var_677; + const double var_919 = 0.2500000000000000000000000*var_208; + const double var_920 = 0.3214285714285713968507707*var_125 + 1.4642857142857141905523122*var_76 + var_49 + var_1*var_918 + 3.0714285714285711748061658*var_398 + 0.9285714285714284921269268*var_917 + 5.8571428571428567622092487*var_491 + 2.9642857142857139685077072*var_181*var_26 + 0.6071428571428570952761561*var_206 + var_226 + var_919 + 1.8571428571428569842538536*var_415 + var_816; + A[230] = A[1]; + const double var_921 = 39.0000000000000000000000000*var_9 + 41.0000000000000000000000000*var_34; + const double var_922 = var_261 + var_76; + A[94] = 0.0000000000000000000000000; + const double var_923 = var_406 + var_192; + A[136] = 0.0000000000000000000000000; + A[54] = 0.0000000000000000000000000; + A[260] = 0.0000000000000000000000000; + const double var_924 = var_495 + var_197 + var_392; + const double var_925 = -var_1*var_19*w[0][9] + var_368; + const double var_926 = var_468 + var_490 + var_416 + var_498 + 0.2000000000000000111022302*var_694 + var_196; + const double var_927 = var_380 + var_379 + var_225; + const double var_928 = var_261 + var_209; + const double var_929 = var_151 + var_211; + const double var_930 = var_190 + var_125; + const double var_931 = var_105*var_134 + var_137*var_22 + var_119 + 11.0000000000000000000000000*var_927 + 17.0000000000000000000000000*var_930 + 19.0000000000000000000000000*var_929 + 13.0000000000000000000000000*var_928; + const double var_932 = var_823 + var_347; + const double var_933 = var_244 + var_87; + const double var_934 = var_317 + var_277; + const double var_935 = 0.0428571428571428575393654*var_878 + 0.0321428571428571396850771*var_934 + 0.1178571428571428547638078*var_933 + 0.1928571428571428381104624*var_658 + 0.0964285714285714190552312*var_315 + var_882 + 0.2464285714285714135041161*var_383 + var_892 + 0.0214285714285714287696827*var_431 + 0.0357142857142857123031732*var_370 + 0.0857142857142857150787307*var_932 + 0.0125000000000000006938894*var_525 + 0.1285714285714285587403083*var_925 + 0.0303571428571428568454760*var_218 + 0.0535714285714285684547598*var_634 + 0.0553571428571428547638078*var_362 + 0.3214285714285713968507707*var_761 + 0.0089285714285714280757933*var_419 + 0.0267857142857142842273799*var_926 + 0.1875000000000000000000000*var_886 + 0.0035714285714285713170535*var_580 + 0.1607142857142856984253854*var_372 + 0.4285714285714285476380780*var_772 + 0.0053571428571428571924207*var_931 + 0.2785714285714285809447688*var_246 + 0.0410714285714285712303173*var_29; + A[109] = 20.2500000000000000000000000*var_237*var_935/(var_238*var_238*var_238); + A[96] = 0.0000000000000000000000000; + const double var_936 = 6.1312500000000005329070518*var_252 + 1.8000000000000000444089210*var_207 + 3.0312500000000000000000000*var_136 + 1.4625000000000001332267630*var_39 + 0.1906250000000000166533454*var_135; + const double var_937 = 41.0000000000000000000000000*var_32 + 39.0000000000000000000000000*var_95; + const double var_938 = var_92 + var_340; + const double var_939 = var_130 + 34.5000000000000000000000000*var_468 + 9.0000000000000000000000000*var_938 + 23.0000000000000000000000000*var_85 + 17.0000000000000000000000000*var_790 + var_7*var_8*var_937; + const double var_940 = 0.1428571428571428492126927*var_134*var_936 + var_764 + 0.1687500000000000111022302*var_58 + 0.6428571428571427937015414*var_564 + 0.7633928571428570952761561*var_71 + 1.4062500000000000000000000*var_162 + 0.6187500000000000222044605*var_681 + 0.4821428571428570952761561*var_543 + 0.3767857142857142793701541*var_525 + 0.0160714285714285698425385*var_566 + 0.1406250000000000000000000*var_379 + 1.0928571428571427492926205*var_45 + 0.6910714285714285587403083*var_22*var_297 + 0.2089285714285714357085766*var_347 + 0.2008928571428571230317317*var_475 + 0.4500000000000000111022302*var_545 + 0.0995535714285714218307888*var_343 + 0.1808035714285714246063463*var_211 + 0.8638392857142856984253854*var_22*var_469 + 0.2531249999999999888977698*var_38 + 0.0080357142857142849212693*var_939; + A[45] = 1.5000000000000000000000000*var_237*var_940/(var_238*var_238*var_238); + const double var_941 = var_163 + var_25 + var_142 + var_48 + var_434 + var_375 + var_115; + const double var_942 = var_38 + var_71 + var_261; + const double var_943 = var_144 + var_248; + const double var_944 = 11.0000000000000000000000000*var_943 + 19.0000000000000000000000000*var_942 + var_941 + var_748 + 37.0000000000000000000000000*var_32*var_7*var_8 + 17.0000000000000000000000000*var_105*var_22; + const double var_945 = -var_1*var_20*w[0][7] + var_694 + var_551 + 0.1428571428571428492126927*var_944; + A[280] = 0.0000000000000000000000000; + A[254] = A[44]; + A[312] = A[45]; + const double var_946 = var_469 + var_148; + const double var_947 = 0.7500000000000000000000000*var_946 + var_191; + A[62] = A[43]; + A[56] = 0.0000000000000000000000000; + A[393] = A[69]; + const double var_948 = 1.9000000000000001332267630*var_39 + 1.8000000000000000444089210*var_124 + 5.1000000000000005329070518*var_89 + 2.2500000000000000000000000*var_150; + const double var_949 = -var_20*w[0][10] + 2.8125000000000000000000000*var_1*var_10; + const double var_950 = 1.6875000000000000000000000*var_462 + var_698 + var_3*var_949 + 1.1250000000000000000000000*var_26*var_948; + const double var_951 = var_145 + var_392; + const double var_952 = var_85 + var_110; + const double var_953 = 9.0000000000000000000000000*var_150*var_26 + 69.0000000000000000000000000*var_131*var_22 + 19.0000000000000000000000000*var_951 + 137.0000000000000000000000000*var_248 + var_686 + 17.0000000000000000000000000*var_77 + 163.0000000000000000000000000*var_87 + var_379 + 127.0000000000000000000000000*var_475 + 41.0000000000000000000000000*var_141 + 181.0000000000000000000000000*var_45 + 83.0000000000000000000000000*var_952; + A[262] = 0.0000000000000000000000000; + A[284] = 0.0000000000000000000000000; + const double var_954 = 0.8857142857142856762209249*var_269 + var_126*var_134 + var_50 + 1.2285714285714284255135453*var_76; + const double var_955 = 0.0803571428571428492126927*var_317 + 0.0160714285714285698425385*var_225; + const double var_956 = 9.0000000000000000000000000*var_22*var_91 + var_176*var_8*w[0][6] + var_60 + var_144 + -var_178*var_7*w[0][16]; + const double var_957 = var_955 + 0.0803571428571428492126927*var_127 + 0.0642857142857142793701541*var_956; + const double var_958 = var_247 + var_734; + const double var_959 = var_323 + var_76; + const double var_960 = 0.1125000000000000027755576*var_959 + 0.2571428571428571174806166*var_523 + 1.2053571428571427937015414*var_1*var_257*var_3 + var_913 + 0.4857142857142857095276156*var_284 + 0.1482142857142857150787307*var_468 + 0.3375000000000000222044605*var_250*var_26 + 1.2857142857142855874030829*var_642 + var_957 + 1.1250000000000000000000000*var_414 + 0.2767857142857142460634634*var_243 + 0.0285714285714285705364279*var_370 + 0.0125000000000000006938894*var_219 + 1.3500000000000000888178420*var_958 + 0.2410714285714285476380780*var_74 + 0.1607142857142856984253854*var_261 + 2.0892857142857139685077072*var_910 + var_809 + 0.3607142857142857095276156*var_525 + var_661; + A[67] = 3.3750000000000000000000000*var_237*var_960/(var_238*var_238*var_238); + A[353] = A[67]; + const double var_961 = var_470 + var_452; + A[322] = 0.0000000000000000000000000; + A[222] = 0.0000000000000000000000000; + A[150] = 0.0000000000000000000000000; + A[301] = 0.0000000000000000000000000; + A[112] = 0.0000000000000000000000000; + A[227] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[199] = 0.0000000000000000000000000; + const double var_962 = var_204 + var_159 + var_323 + var_441; + const double var_963 = var_545 + var_518; + const double var_964 = var_736 + var_58 + var_963; + const double var_965 = var_217 + var_294; + const double var_966 = 3.0000000000000000000000000*var_114*var_7*var_8 + var_134*var_39 + var_384; + const double var_967 = 0.0500000000000000027755576*var_501 + var_477 + var_715 + var_919 + 0.1000000000000000055511151*var_962 + 1.5000000000000000000000000*var_195 + 1.7000000000000001776356839*var_923 + 1.2500000000000000000000000*var_383 + 0.5500000000000000444089210*var_966 + 1.3500000000000000888178420*var_381 + 1.1000000000000000888178420*var_965 + 0.2500000000000000000000000*var_365 + 0.2000000000000000111022302*var_964 + 0.4500000000000000111022302*var_568 + 0.3000000000000000444089210*var_144 + 0.5000000000000000000000000*var_768 + 0.1500000000000000222044605*var_101 + -var_1*var_20*w[0][9] + 0.9000000000000000222044605*var_470; + const double var_968 = var_277 + var_468; + const double var_969 = var_808 + 0.0607142857142857136909520*var_284 + 0.1428571428571428492126927*var_185 + 0.1285714285714285587403083*var_225 + 0.2250000000000000055511151*var_657 + 0.2446428571428571341339619*var_362 + 0.3214285714285713968507707*var_967 + 0.1482142857142857150787307*var_364 + 0.1125000000000000027755576*var_968 + 0.2571428571428571174806166*var_211 + var_586 + var_672 + 0.3375000000000000222044605*var_574; + A[127] = 3.3750000000000000000000000*var_237*var_969/(var_238*var_238*var_238); + A[337] = A[127]; + A[179] = 0.0000000000000000000000000; + const double var_970 = var_794 + var_218 + var_125 + var_241 + var_963; + const double var_971 = 0.0250000000000000013877788*var_171; + const double var_972 = 0.7500000000000000000000000*var_19 + var_20; + const double var_973 = var_470 + var_693 + var_414; + const double var_974 = var_462 + var_58; + const double var_975 = 0.2500000000000000000000000*var_974 + var_7*var_972*w[0][19] + 0.1250000000000000000000000*var_973 + -var_176*var_8*w[0][9]; + const double var_976 = var_692 + var_82; + const double var_977 = 0.6428571428571427937015414*var_749 + 0.4642857142857142460634634*var_162 + 0.0714285714285714246063463*var_347 + 0.0357142857142857123031732*var_976 + 0.1250000000000000000000000*var_945 + var_528 + var_620; + const double var_978 = 0.0267857142857142842273799*var_970 + 0.0517857142857142821457117*var_243 + var_882 + 0.0678571428571428519882502*var_270 + 0.0196428571428571424606346*var_525 + 0.2571428571428571174806166*var_975 + 0.0535714285714285684547598*var_222 + var_971 + 0.3000000000000000444089210*var_977 + 0.0017857142857142856585267*var_419; + const double var_979 = 3.0000000000000000000000000*var_204 + var_715; + A[265] = 0.0000000000000000000000000; + const double var_980 = var_807 + var_575 + var_552; + A[166] = A[128]; + A[180] = A[9]; + const double var_981 = var_66 + 0.7500000000000000000000000*var_59 + var_64 + 1.5000000000000000000000000*var_175 + var_19*var_8*w[0][3] + 0.2500000000000000000000000*var_451 + var_20*var_3*w[0][14] + 0.5000000000000000000000000*var_980; + const double var_982 = var_554 + var_570; + const double var_983 = 0.7250000000000000888178420*var_553 + 0.0250000000000000013877788*var_139 + 1.8000000000000000444089210*var_981 + 0.4750000000000000333066907*var_171 + 1.1250000000000000000000000*var_735 + 0.2500000000000000000000000*var_982; + A[189] = 5.7857142857142855874030829*var_237*var_983/(var_238*var_238*var_238); + A[399] = A[189]; + const double var_984 = 0.2000000000000000111022302*var_723 + var_645 + var_194 + var_241 + var_249 + var_328; + const double var_985 = var_131 + var_285; + const double var_986 = 1.4607142857142856318120039*var_985 + 8.5964285714285715300775337*var_129 + 3.4714285714285715300775337*var_89 + 5.4000000000000003552713679*var_251 + 5.1964285714285711748061658*var_855 + 3.6750000000000002664535259*var_39 + 0.2035714285714285698425385*var_836 + 16.2107142857142854097673990*var_153 + 12.5357142857142846992246632*var_250; + const double var_987 = 0.0053571428571428571924207*var_225 + 0.0267857142857142842273799*var_591 + 0.0321428571428571396850771*var_320 + 0.0214285714285714287696827*var_144; + const double var_988 = var_468 + var_127 + var_530 + var_664 + var_219; + const double var_989 = var_19 + 0.7500000000000000000000000*var_20; + const double var_990 = var_922 + var_365 + var_452; + const double var_991 = var_1*var_989*w[0][9] + 0.2500000000000000000000000*var_676 + -var_178*var_3*w[0][19] + 0.1250000000000000000000000*var_990; + const double var_992 = var_90 + 0.5000000000000000000000000*var_58 + var_22*var_296; + const double var_993 = 0.0714285714285714246063463*var_246 + 0.0357142857142857123031732*var_916 + 0.4642857142857142460634634*var_163 + var_692 + 0.1250000000000000000000000*var_729 + 0.6428571428571427937015414*var_992 + var_614; + const double var_994 = 0.0267857142857142842273799*var_988 + var_987 + 0.2571428571428571174806166*var_991 + 0.0017857142857142856585267*var_370 + 0.0196428571428571424606346*var_243 + 0.0517857142857142821457117*var_525 + 0.0535714285714285684547598*var_221 + 0.0678571428571428519882502*var_284 + 0.3000000000000000444089210*var_993 + var_971; + A[169] = 20.2500000000000000000000000*var_237*var_994/(var_238*var_238*var_238); + A[398] = A[169]; + A[71] = 0.0000000000000000000000000; + A[155] = 0.0000000000000000000000000; + A[370] = A[8]; + const double var_995 = var_131 + var_129; + const double var_996 = 0.0482142857142857095276156*var_134*var_947; + A[306] = 0.0000000000000000000000000; + const double var_997 = var_50 + var_826 + var_160; + const double var_998 = var_90 + var_413; + const double var_999 = var_132 + 17.0000000000000000000000000*var_901 + 23.0000000000000000000000000*var_87 + var_1*var_3*var_921 + 34.5000000000000000000000000*var_241 + 9.0000000000000000000000000*var_998; + A[350] = A[7]; + A[349] = 0.0000000000000000000000000; + const double var_1000 = -var_178*w[0][13] + 4.6250000000000000000000000*var_1*var_15; + A[257] = A[47]; + const double var_1001 = var_145 + var_374; + A[255] = A[45]; + A[73] = 0.0000000000000000000000000; + A[346] = 0.0000000000000000000000000; + A[275] = A[65]; + A[343] = 0.0000000000000000000000000; + const double var_1002 = 0.1607142857142856984253854*var_161 + 0.3375000000000000222044605*var_128 + 0.2250000000000000055511151*var_30 + 0.0821428571428571424606346*var_134*var_137 + 0.7250000000000000888178420*var_171 + 0.1125000000000000027755576*var_75 + 0.5000000000000000000000000*var_553 + 0.2571428571428571174806166*var_68 + 0.6428571428571427937015414*var_465; + const double var_1003 = var_643 + var_96; + const double var_1004 = 0.7107142857142857428343063*var_131*var_26 + 1.3178571428571428381104624*var_156; + const double var_1005 = var_435 + var_130; + const double var_1006 = 0.0321428571428571396850771*var_1005 + 2.7642857142857142349612332*var_961 + 0.2892857142857142571656937*var_655 + 0.3214285714285713968507707*var_837 + 1.0124999999999999555910790*var_211 + 0.8839285714285713968507707*var_261 + 1.8000000000000000444089210*var_468 + 0.1125000000000000027755576*var_40 + 1.8196428571428571174806166*var_134*var_136 + 1.0607142857142857206298459*var_53 + 0.0678571428571428519882502*var_241 + var_633 + var_1004 + 4.7410714285714279370154145*var_332 + 0.0642857142857142793701541*var_1*var_16*var_3 + 3.5035714285714285587403083*var_67 + 1.9357142857142857206298459*var_243 + 0.0767857142857142765945966*var_135*var_26 + 3.6678571428571427048836995*var_525 + 0.4017857142857142460634634*var_144 + 4.3714285714285709971704819*var_50 + 0.7232142857142856984253854*var_38 + 3.4553571428571427937015414*var_22*var_297 + 0.7071428571428570730716956*var_374 + 0.3857142857142856762209249*var_58 + 0.1928571428571428381104624*var_414 + 0.0446428571428571438484134*var_419 + 1.5267857142857141905523122*var_873 + 2.7964285714285712636240078*var_55 + 1.4464285714285713968507707*var_90 + 0.9642857142857141905523122*var_57 + 0.0803571428571428492126927*var_692 + 0.6750000000000000444089210*var_172 + 5.8178571428571430601550674*var_162 + 0.4821428571428570952761561*var_7*var_756*var_8 + 0.0160714285714285698425385*var_953; + A[6] = 0.3750000000000000000000000*var_1006*var_237/(var_238*var_238*var_238); + A[120] = A[6]; + A[360] = 0.0000000000000000000000000; + A[40] = A[2]; + const double var_1007 = var_355 + var_524; + A[330] = A[6]; + A[51] = 0.0000000000000000000000000; + A[171] = 0.0000000000000000000000000; + A[114] = 0.0000000000000000000000000; + const double var_1008 = -var_1*var_3*var_8*w[0][19] + var_173; + const double var_1009 = var_248 + var_700; + const double var_1010 = 0.7187500000000000000000000*var_1009 + 0.2500000000000000000000000*var_917 + 0.0625000000000000000000000*var_206 + var_134*var_148 + var_110 + 0.1875000000000000000000000*var_204 + 0.0312500000000000000000000*var_270; + const double var_1011 = 0.1687500000000000111022302*var_1008 + var_895 + 0.2571428571428571174806166*var_1010 + var_659 + 0.0531250000000000055511151*var_29 + 0.1406250000000000000000000*var_954 + 0.0714285714285714246063463*var_950; + A[25] = 1.5000000000000000000000000*var_1011*var_237/(var_238*var_238*var_238); + A[235] = A[25]; + A[334] = A[86]; + A[240] = 0.0000000000000000000000000; + const double var_1012 = 2.7142857142857139685077072*var_112 + 6.1428571428571423496123316*var_371 + 7.0000000000000000000000000*var_214; + const double var_1013 = var_634 + var_579; + const double var_1014 = 0.4178571428571428714171532*var_277 + 0.0562500000000000013877788*var_1*var_1012*var_3 + 0.2089285714285714357085766*var_159 + 0.3375000000000000222044605*var_340 + 0.0401785714285714246063463*var_806 + var_782 + 0.2410714285714285476380780*var_452 + 0.3535714285714285365358478*var_679 + var_863 + 0.1446428571428571285828468*var_379 + 0.2732142857142856873231551*var_124*var_26 + 0.0062500000000000003469447*var_545 + 0.1919642857142856984253854*var_587 + 0.2973214285714285698425385*var_160 + 0.0883928571428571341339619*var_141 + 0.2633928571428571507873073*var_362 + 0.3776785714285714190552312*var_226 + 0.2571428571428571174806166*var_770 + var_684 + 0.1946428571428571452361922*var_135*var_22 + 0.7232142857142856984253854*var_823 + 1.1250000000000000000000000*var_380 + 0.7071428571428570730716956*var_392 + 0.0741071428571428575393654*var_25 + 0.0080357142857142849212693*var_1013 + var_548 + 0.2169642857142857206298459*var_384 + 0.3125000000000000000000000*var_419 + 0.8517857142857142571656937*var_347 + 0.1455357142857142682679239*var_364 + 0.7714285714285713524418497*var_491 + 0.0482142857142857095276156*var_415 + var_275 + 0.1285714285714285587403083*var_454 + var_425 + 0.1044642857142857178542883*var_1001 + 0.0160714285714285698425385*var_1003; + A[148] = 6.7500000000000000000000000*var_1014*var_237/(var_238*var_238*var_238); + A[129] = 20.2500000000000000000000000*var_237*var_978/(var_238*var_238*var_238); + A[186] = A[129]; + A[178] = 0.0000000000000000000000000; + A[296] = A[86]; + A[78] = 0.0000000000000000000000000; + const double var_1015 = 6.1312500000000005329070518*var_272 + 0.1906250000000000166533454*var_136 + 1.8000000000000000444089210*var_210 + 1.4625000000000001332267630*var_37 + 3.0312500000000000000000000*var_135; + const double var_1016 = 0.4500000000000000111022302*var_323 + 0.7633928571428570952761561*var_74 + 0.6428571428571427937015414*var_495 + 0.2089285714285714357085766*var_246 + 1.4062500000000000000000000*var_163 + 0.1687500000000000111022302*var_57 + 0.6910714285714285587403083*var_251*var_26 + 0.3767857142857142793701541*var_243 + 0.1406250000000000000000000*var_244 + 0.1428571428571428492126927*var_1015*var_134 + 1.0928571428571427492926205*var_43 + 0.0160714285714285698425385*var_568 + 0.8638392857142856984253854*var_250*var_26 + var_996 + 0.0995535714285714218307888*var_269 + 0.4821428571428570952761561*var_314 + 0.0080357142857142849212693*var_999 + 0.1808035714285714246063463*var_208 + 0.2008928571428571230317317*var_261 + 0.2531249999999999888977698*var_40 + 0.6187500000000000222044605*var_651; + A[27] = 1.5000000000000000000000000*var_1016*var_237/(var_238*var_238*var_238); + A[351] = A[27]; + const double var_1017 = var_124 + var_126; + const double var_1018 = var_17*w[0][9] + var_18*w[0][19]; + const double var_1019 = var_207 + var_210; + const double var_1020 = var_23 + 19.1142857142857138796898653*var_652 + var_27 + 5.2285714285714286475581503*var_1019; + const double var_1021 = 6.9428571428571430601550674*var_1018 + 11.9571428571428572951163005*var_1017 + 11.6857142857142850544960311*var_137 + 0.7714285714285713524418497*var_459 + 17.0571428571428569398449326*var_904 + 0.5000000000000000000000000*var_1020; + A[162] = A[48]; + A[264] = 0.0000000000000000000000000; + A[289] = 0.0000000000000000000000000; + A[158] = 0.0000000000000000000000000; + A[132] = 0.0000000000000000000000000; + const double var_1022 = 0.6968750000000000222044605*var_131 + 3.0312500000000000000000000*var_129 + 1.8000000000000000444089210*var_189 + 6.1312500000000005329070518*var_153 + 1.4625000000000001332267630*var_105; + const double var_1023 = 0.5000000000000000000000000*var_206 + var_211; + const double var_1024 = var_163 + var_244; + const double var_1025 = var_184 + var_190; + const double var_1026 = 0.3000000000000000444089210*var_39 + var_297; + const double var_1027 = 0.6000000000000000888178420*var_154 + 0.2000000000000000111022302*var_1025 + var_518 + var_416 + 1.5000000000000000000000000*var_415 + var_1026*var_26 + 0.5000000000000000000000000*var_208 + var_387 + 0.1000000000000000055511151*var_1024 + 1.7000000000000001776356839*var_65 + var_1023; + const double var_1028 = var_35 + var_94 + var_320; + const double var_1029 = var_265 + var_564 + var_195; + const double var_1030 = var_246 + var_58; + const double var_1031 = -var_176*w[0][4] + 4.6250000000000000000000000*var_61*var_7; + const double var_1032 = 0.5000000000000000000000000*var_1030 + 2.7500000000000000000000000*var_279 + 3.2500000000000000000000000*var_1028 + 0.2500000000000000000000000*var_413 + var_314 + 1.3750000000000000000000000*var_76 + 1.6250000000000000000000000*var_1*var_214*var_3 + 1.5000000000000000000000000*var_277 + 4.5000000000000000000000000*var_400 + 2.1250000000000000000000000*var_365 + 0.1250000000000000000000000*var_1029 + var_470 + var_7*var_972*w[0][14] + var_1031*var_8; + const double var_1033 = var_481 + var_434; + const double var_1034 = 0.2008928571428571230317317*var_48 + 0.0446428571428571438484134*var_468 + 0.0687500000000000055511151*var_284 + 0.1125000000000000027755576*var_142 + 0.0767857142857142765945966*var_129*var_26 + 0.0803571428571428492126927*var_997 + 0.1133928571428571424606346*var_243 + var_955 + 0.1285714285714285587403083*var_74 + 0.2410714285714285476380780*var_1027 + 0.0232142857142857150787307*var_364 + 0.3375000000000000222044605*var_793 + 0.0205357142857142856151587*var_134*var_136 + 0.1812500000000000222044605*var_241 + 0.0285714285714285705364279*var_545 + var_709 + 0.0642857142857142793701541*var_1032 + 0.1607142857142856984253854*var_1033; + A[192] = 0.0000000000000000000000000; + const double var_1035 = 0.7500000000000000000000000*var_475 + var_885 + 0.1250000000000000000000000*var_265 + -var_20*var_8*w[0][4] + 1.1250000000000000000000000*var_383 + 0.2500000000000000000000000*var_90 + var_321; + A[21] = 0.1250000000000000000000000*var_237*var_26*var_986/(var_238*var_238*var_238); + A[231] = A[21]; + const double var_1036 = var_518 + var_262; + const double var_1037 = 9.4000000000000003552713679*var_129 + 1.1714285714285714856686127*var_131 + 19.2857142857142846992246632*var_153; + const double var_1038 = 0.0482142857142857095276156*var_682 + 0.0285714285714285705364279*var_132 + var_428 + 0.2008928571428571230317317*var_142 + 0.2250000000000000055511151*var_254*var_677 + 0.0312500000000000000000000*var_1037*var_22; + const double var_1039 = var_40 + var_443; + const double var_1040 = var_270 + var_468; + const double var_1041 = var_365 + var_199; + const double var_1042 = 13.0000000000000000000000000*var_55 + var_413 + 8.5000000000000000000000000*var_251*var_26 + 0.5000000000000000000000000*var_891 + 6.5000000000000000000000000*var_244 + var_1*var_3*var_730 + 4.5000000000000000000000000*var_208; + const double var_1043 = 0.4017857142857142460634634*var_77 + 1.0044642857142855874030829*var_65 + 0.0642857142857142793701541*var_267 + 0.1205357142857142738190390*var_1039 + 0.0160714285714285698425385*var_1042 + var_611 + 0.5625000000000000000000000*var_794 + 0.8035714285714284921269268*var_62 + 0.7232142857142856984253854*var_82 + 0.9642857142857141905523122*var_642 + 0.0767857142857142765945966*var_241 + 0.1928571428571428381104624*var_1035 + 0.0562500000000000013877788*var_261 + 0.4303571428571428270082322*var_134*var_135 + var_1038 + 0.3857142857142856762209249*var_958 + 0.1812500000000000222044605*var_129*var_26 + 0.2410714285714285476380780*var_1041 + 0.4500000000000000111022302*var_543 + 0.0366071428571428589271441*var_1040 + 0.1616071428571428658660381*var_243 + 0.3616071428571428492126927*var_74 + var_660 + 0.1214285714285714273819039*var_525 + 0.4178571428571428714171532*var_101 + 1.2053571428571427937015414*var_48 + 0.1285714285714285587403083*var_628; + A[168] = 13.5000000000000000000000000*var_1043*var_237/(var_238*var_238*var_238); + A[363] = 0.0000000000000000000000000; + const double var_1044 = 6.5000000000000000000000000*var_114 + 11.5714285714285711748061658*var_319 + 4.0714285714285711748061658*var_373; + const double var_1045 = 2.1964285714285711748061658*var_1*var_264 + -var_20*w[0][13] + 2.6250000000000000000000000*var_1*var_325; + const double var_1046 = var_203 + var_372; + const double var_1047 = var_416 + var_631; + const double var_1048 = 0.3214285714285713968507707*var_365 + 4.9285714285714279370154145*var_279 + 2.0357142857142855874030829*var_1046 + 0.3392857142857142460634634*var_723 + 1.1964285714285713968507707*var_409 + 0.1071428571428571369095195*var_392 + 0.7321428571428570952761561*var_225 + var_1045*var_3 + 4.7142857142857144125969171*var_294 + 2.6071428571428572062984586*var_383 + var_822 + 3.6071428571428567622092487*var_384 + 3.6428571428571427937015414*var_678 + var_347 + 0.6785714285714284921269268*var_1023 + 0.2500000000000000000000000*var_1044*var_7*var_8 + 1.8214285714285713968507707*var_191*var_22 + 1.4821428571428569842538536*var_207*var_26 + 2.9285714285714283811046243*var_588 + 3.2321428571428567622092487*var_329 + 3.8928571428571427937015414*var_259 + var_758 + 0.1250000000000000000000000*var_182 + 0.1607142857142856984253854*var_251*var_26 + 0.0178571428571428561515866*var_1047; + const double var_1049 = 0.3616071428571428492126927*var_184; + const double var_1050 = var_807 + var_979; + const double var_1051 = var_190 + var_209; + const double var_1052 = 0.0803571428571428492126927*var_1050 + 0.2571428571428571174806166*var_1051 + 0.6227678571428570952761561*var_381 + 0.2008928571428571230317317*var_379 + var_896 + var_1049 + 0.0401785714285714246063463*var_160 + 0.8437500000000000000000000*var_589 + 0.2308035714285714135041161*var_131*var_134 + 0.0464285714285714301574615*var_134*var_135 + 0.0531250000000000055511151*var_136*var_22 + var_877 + 0.0191964285714285691486491*var_129*var_26 + var_341 + 0.5625000000000000000000000*var_485 + 0.0200892857142857123031732*var_380 + 0.2209821428571428492126927*var_159 + 0.3816964285714285476380780*var_262 + 0.2250000000000000055511151*var_1048; + A[321] = 0.0000000000000000000000000; + A[19] = 0.0000000000000000000000000; + A[206] = 0.0000000000000000000000000; + A[340] = 0.0000000000000000000000000; + A[98] = 0.0000000000000000000000000; + const double var_1053 = var_168 + var_254*var_850 + var_467; + A[147] = 13.5000000000000000000000000*var_1034*var_237/(var_238*var_238*var_238); + const double var_1054 = var_411 + var_246; + A[204] = 0.0000000000000000000000000; + A[307] = 0.0000000000000000000000000; + A[154] = 0.0000000000000000000000000; + A[160] = A[8]; + A[215] = A[5]; + A[113] = 0.0000000000000000000000000; + A[364] = 0.0000000000000000000000000; + A[60] = A[3]; + A[329] = 0.0000000000000000000000000; + A[38] = 0.0000000000000000000000000; + A[377] = A[148]; + A[140] = A[7]; + const double var_1055 = var_90 + var_350; + A[278] = A[68]; + A[378] = A[168]; + const double var_1056 = var_33 + var_678 + var_96; + const double var_1057 = var_347 + var_57; + const double var_1058 = 2.7500000000000000000000000*var_294 + 1.3750000000000000000000000*var_77 + 1.5000000000000000000000000*var_262 + 0.1250000000000000000000000*var_924 + 0.5000000000000000000000000*var_1057 + var_1000*var_3 + var_543 + 2.1250000000000000000000000*var_470 + 1.6250000000000000000000000*var_216*var_7*var_8 + 3.2500000000000000000000000*var_1056 + 0.2500000000000000000000000*var_340 + 4.5000000000000000000000000*var_609 + var_365 + var_1*var_989*w[0][3]; + const double var_1059 = var_579 + var_715; + const double var_1060 = 0.1125000000000000027755576*var_141 + 0.0687500000000000055511151*var_270 + 0.1133928571428571424606346*var_525 + 0.2008928571428571230317317*var_50 + 0.1812500000000000222044605*var_468 + 0.2410714285714285476380780*var_650 + 0.0205357142857142856151587*var_134*var_135 + var_709 + 0.0285714285714285705364279*var_323 + var_905 + 0.1285714285714285587403083*var_71 + 0.0803571428571428492126927*var_835 + 0.0446428571428571438484134*var_241 + 0.0767857142857142765945966*var_131*var_22 + 0.3375000000000000222044605*var_527 + 0.0232142857142857150787307*var_362 + 0.0642857142857142793701541*var_1058 + 0.1607142857142856984253854*var_1059; + A[237] = A[27]; + A[4] = 1.5000000000000000000000000*var_1052*var_237/(var_238*var_238*var_238); + A[214] = A[4]; + A[49] = 20.2500000000000000000000000*var_237*var_861/(var_238*var_238*var_238); + A[207] = 0.0000000000000000000000000; + A[106] = 6.7500000000000000000000000*var_237*var_438/(var_238*var_238*var_238); + A[144] = A[87]; + A[107] = 3.3750000000000000000000000*var_1002*var_237/(var_238*var_238*var_238); + A[355] = A[107]; + A[344] = 0.0000000000000000000000000; + A[267] = 0.0000000000000000000000000; + A[277] = A[67]; + A[305] = 0.0000000000000000000000000; + A[395] = A[109]; + A[396] = A[129]; + const double var_1061 = var_20*var_8*w[0][3] + -var_19*var_7*w[0][13] + var_214*var_254 + var_163 + 1.5000000000000000000000000*var_65 + 0.5000000000000000000000000*var_248; + const double var_1062 = var_723 + var_40 + var_141; + const double var_1063 = var_559 + var_811 + var_145 + 0.1000000000000000055511151*var_265; + const double var_1064 = var_57 + var_199; + const double var_1065 = 0.0482142857142857095276156*var_327 + 0.2892857142857142571656937*var_1055 + 0.0241071428571428547638078*var_50 + 0.6910714285714285587403083*var_55 + 0.1205357142857142738190390*var_249 + 0.4821428571428570952761561*var_793 + 0.0321428571428571396850771*var_922 + 0.4017857142857142460634634*var_1061 + 0.0446428571428571438484134*var_323 + 0.0642857142857142793701541*var_518 + 0.8035714285714284921269268*var_48 + 0.1571428571428571396850771*var_134*var_135 + var_1038 + 0.0285714285714285705364279*var_241 + 0.4500000000000000111022302*var_53 + 0.0366071428571428589271441*var_1053 + 0.1607142857142856984253854*var_74 + 0.0803571428571428492126927*var_1063 + 0.0562500000000000013877788*var_620 + 0.2410714285714285476380780*var_1062 + 0.0732142857142857178542883*var_1007 + 0.2330357142857142904723844*var_67 + 0.0651785714285714329330190*var_243 + 0.3696428571428571063783863*var_1*var_3*var_9 + 0.1446428571428571285828468*var_156 + 0.0116071428571428575393654*var_131*var_134 + 0.3214285714285713968507707*var_1064; + A[63] = 13.5000000000000000000000000*var_1065*var_237/(var_238*var_238*var_238); + A[281] = 0.0000000000000000000000000; + A[336] = A[126]; + A[273] = A[63]; + A[319] = A[109]; + A[247] = 0.0000000000000000000000000; + A[173] = 0.0000000000000000000000000; + A[123] = A[66]; + A[358] = A[148]; + A[22] = 0.0156250000000000000000000*var_1021*var_134*var_237/(var_238*var_238*var_238); + A[251] = A[22]; + A[195] = 0.0000000000000000000000000; + A[361] = 0.0000000000000000000000000; + A[52] = 0.0000000000000000000000000; + A[75] = 0.0000000000000000000000000; + const double var_1066 = var_609 + var_478 + var_92 + var_106 + 0.5000000000000000000000000*var_340; + const double var_1067 = var_85 + var_379; + const double var_1068 = 0.1178571428571428547638078*var_1067 + 0.0428571428571428575393654*var_979 + 0.0857142857142857150787307*var_1054 + 0.0267857142857142842273799*var_984 + var_892 + 0.0035714285714285713170535*var_375 + 0.1285714285714285587403083*var_761 + 0.1607142857142856984253854*var_406 + 0.0535714285714285684547598*var_435 + 0.4285714285714285476380780*var_393 + 0.0553571428571428547638078*var_364 + 0.0357142857142857123031732*var_419 + 0.1875000000000000000000000*var_865 + 0.2464285714285714135041161*var_398 + 0.0321428571428571396850771*var_1036 + 0.2785714285714285809447688*var_347 + 0.0410714285714285712303173*var_25 + 0.0214285714285714287696827*var_643 + var_987 + 0.0089285714285714280757933*var_370 + 0.0303571428571428568454760*var_219 + 0.3214285714285713968507707*var_925 + 0.0053571428571428571924207*var_754 + 0.0964285714285714190552312*var_910 + 0.0125000000000000006938894*var_243 + 0.1928571428571428381104624*var_1066; + A[149] = 20.2500000000000000000000000*var_1068*var_237/(var_238*var_238*var_238); + A[187] = A[149]; + A[10] = 0.0000000000000000000000000; + A[30] = 0.0000000000000000000000000; + A[308] = 0.0000000000000000000000000; + A[91] = 0.0000000000000000000000000; + A[167] = A[148]; + A[41] = A[22]; + A[245] = 0.0000000000000000000000000; + A[390] = A[9]; + A[266] = 0.0000000000000000000000000; + const double var_1069 = var_68 + var_59; + A[53] = 0.0000000000000000000000000; + A[17] = 0.0000000000000000000000000; + A[219] = A[9]; + const double var_1070 = 0.2500000000000000000000000*var_1004 + 0.1406250000000000000000000*var_113 + var_1049 + 0.1125000000000000027755576*var_920 + 0.0321428571428571396850771*var_254*var_357 + 0.5464285714285713746463102*var_215 + 0.0642857142857142793701541*var_384 + 0.0169642857142857129970626*var_129*var_26 + 0.0272321428571428575393654*var_851 + 0.1205357142857142738190390*var_204 + 0.0191964285714285691486491*var_29 + 0.0464285714285714301574615*var_362 + 0.3857142857142856762209249*var_925 + var_996 + 0.1428571428571428492126927*var_1022*var_134; + A[24] = 1.5000000000000000000000000*var_1070*var_237/(var_238*var_238*var_238); + A[234] = A[24]; + A[331] = A[26]; + A[153] = 0.0000000000000000000000000; + A[185] = A[109]; + A[216] = A[6]; + A[156] = 0.0000000000000000000000000; + A[225] = 0.0000000000000000000000000; + A[177] = 0.0000000000000000000000000; + A[354] = A[87]; + A[310] = A[5]; + A[157] = 0.0000000000000000000000000; + A[33] = 0.0000000000000000000000000; + A[104] = A[85]; + A[271] = A[23]; + A[55] = 0.0000000000000000000000000; + A[362] = 0.0000000000000000000000000; + A[105] = 13.5000000000000000000000000*var_1060*var_237/(var_238*var_238*var_238); + const double var_1071 = var_380 + var_259; + const double var_1072 = var_340 + var_413; + const double var_1073 = var_580 + var_375; + const double var_1074 = 0.3892857142857142904723844*var_1073 + 1.2857142857142855874030829*var_456 + 0.0125000000000000006938894*var_554 + var_907 + 0.3214285714285713968507707*var_1071 + var_957 + 0.9482142857142856762209249*var_36 + 1.4142857142857141461433912*var_56 + 0.6750000000000000444089210*var_1072 + 0.1482142857142857150787307*var_220 + 0.0160714285714285698425385*var_557 + 0.1607142857142856984253854*var_143 + 0.2571428571428571174806166*var_223 + 0.3857142857142856762209249*var_450 + 0.2410714285714285476380780*var_102 + 1.1892857142857142793701541*var_97 + 0.0875000000000000083266727*var_171 + 0.1000000000000000055511151*var_553 + 0.1535714285714285531891932*var_134*var_995 + 0.2250000000000000055511151*var_1069 + 0.1928571428571428381104624*var_499; + A[239] = A[29]; + A[57] = 0.0000000000000000000000000; + A[64] = 3.3750000000000000000000000*var_1074*var_237/(var_238*var_238*var_238); + A[274] = A[64]; + A[345] = 0.0000000000000000000000000; + A[228] = 0.0000000000000000000000000; + A[387] = 0.0000000000000000000000000; + A[217] = A[7]; + A[389] = 0.0000000000000000000000000; + A[291] = A[24]; + A[131] = 0.0000000000000000000000000; + A[318] = A[108]; + A[80] = A[4]; + A[151] = 0.0000000000000000000000000; + A[379] = A[169]; + A[122] = A[46]; + A[76] = 0.0000000000000000000000000; + A[212] = A[2]; + A[314] = A[85]; + A[342] = 0.0000000000000000000000000; + A[356] = A[127]; + A[200] = 0.0000000000000000000000000; + A[290] = A[4]; + A[324] = 0.0000000000000000000000000; + A[297] = A[87]; + A[99] = 0.0000000000000000000000000; + A[249] = 0.0000000000000000000000000; + A[93] = 0.0000000000000000000000000; + A[190] = 0.0000000000000000000000000; + A[282] = 0.0000000000000000000000000; + A[175] = 0.0000000000000000000000000; + A[371] = A[28]; + A[13] = 0.0000000000000000000000000; + A[248] = 0.0000000000000000000000000; + A[397] = A[149]; + A[373] = A[68]; + A[182] = A[49]; + A[97] = 0.0000000000000000000000000; + A[116] = 0.0000000000000000000000000; + A[92] = 0.0000000000000000000000000; + A[283] = 0.0000000000000000000000000; + A[133] = 0.0000000000000000000000000; + A[242] = 0.0000000000000000000000000; + A[70] = 0.0000000000000000000000000; + A[35] = 0.0000000000000000000000000; + A[170] = 0.0000000000000000000000000; + A[196] = 0.0000000000000000000000000; + A[118] = 0.0000000000000000000000000; + A[339] = A[129]; + A[259] = A[49]; + A[59] = 0.0000000000000000000000000; + A[95] = 0.0000000000000000000000000; + A[359] = A[149]; + A[32] = 0.0000000000000000000000000; + A[100] = A[5]; + A[198] = 0.0000000000000000000000000; + A[152] = 0.0000000000000000000000000; + A[176] = 0.0000000000000000000000000; + A[302] = 0.0000000000000000000000000; + A[72] = 0.0000000000000000000000000; + A[197] = 0.0000000000000000000000000; + A[232] = A[22]; + A[61] = A[23]; + A[83] = A[64]; + A[141] = A[27]; + A[304] = 0.0000000000000000000000000; + A[224] = 0.0000000000000000000000000; + A[164] = A[88]; + A[311] = A[25]; + A[233] = A[23]; + A[347] = 0.0000000000000000000000000; + A[272] = A[43]; + A[288] = 0.0000000000000000000000000; + A[238] = A[28]; + A[369] = 0.0000000000000000000000000; + A[81] = A[24]; + A[269] = 0.0000000000000000000000000; + A[202] = 0.0000000000000000000000000; + A[74] = 0.0000000000000000000000000; + A[381] = 0.0000000000000000000000000; + A[328] = 0.0000000000000000000000000; + A[374] = A[88]; + A[335] = A[106]; + A[205] = 0.0000000000000000000000000; + A[117] = 0.0000000000000000000000000; + A[82] = A[44]; + A[386] = 0.0000000000000000000000000; + A[300] = 0.0000000000000000000000000; + A[270] = A[3]; + A[145] = A[107]; + A[16] = 0.0000000000000000000000000; + A[20] = A[1]; + A[11] = 0.0000000000000000000000000; + A[388] = 0.0000000000000000000000000; + A[220] = 0.0000000000000000000000000; + A[368] = 0.0000000000000000000000000; + A[326] = 0.0000000000000000000000000; + A[315] = A[105]; + A[159] = 0.0000000000000000000000000; + A[90] = 0.0000000000000000000000000; + A[316] = A[106]; + A[115] = 0.0000000000000000000000000; + A[261] = 0.0000000000000000000000000; + A[236] = A[26]; + A[172] = 0.0000000000000000000000000; + A[125] = A[106]; + A[191] = 0.0000000000000000000000000; + A[246] = 0.0000000000000000000000000; + A[58] = 0.0000000000000000000000000; + A[285] = 0.0000000000000000000000000; + A[188] = A[169]; + A[102] = A[45]; + A[286] = 0.0000000000000000000000000; + A[317] = A[107]; + A[208] = 0.0000000000000000000000000; + A[142] = A[47]; + A[36] = 0.0000000000000000000000000; + A[183] = A[69]; + A[376] = A[128]; + A[357] = A[147]; + A[293] = A[64]; + A[392] = A[49]; + A[50] = 0.0000000000000000000000000; + A[143] = A[67]; + A[313] = A[65]; + A[134] = 0.0000000000000000000000000; + A[303] = 0.0000000000000000000000000; + A[298] = A[88]; + A[111] = 0.0000000000000000000000000; + A[146] = A[127]; + A[101] = A[25]; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q3_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q3_quadrature.h new file mode 100644 index 0000000..d1fb4ea --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q3_quadrature.h @@ -0,0 +1,9149 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P3_Q3_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P3_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q3_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q3_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q3_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q3_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p3_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W12[12] = {0.0254224531851035, 0.0254224531851035, 0.0254224531851035, 0.0583931378631895, 0.0583931378631895, 0.0583931378631895, 0.041425537809187, 0.041425537809187, 0.041425537809187, 0.041425537809187, 0.041425537809187, 0.041425537809187}; + // Quadrature points on the UFC reference element: (0.873821971016996, 0.063089014491502), (0.063089014491502, 0.873821971016996), (0.063089014491502, 0.063089014491502), (0.501426509658179, 0.24928674517091), (0.24928674517091, 0.501426509658179), (0.24928674517091, 0.24928674517091), (0.636502499121399, 0.310352451033785), (0.636502499121399, 0.053145049844816), (0.310352451033785, 0.636502499121399), (0.310352451033785, 0.053145049844816), (0.053145049844816, 0.636502499121399), (0.053145049844816, 0.310352451033785) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[12][9] = \ + {{-0.485931890194853, 0.485931890194852, 6.37592643035589, -2.44372756077941, -0.0537330206183708, 0.0537330206183713, 2.44372756077941, -6.37592643035589, 0.0}, + {-0.485931890194854, 3.44372756077941, -0.230167544593386, 1.20457074358531, 2.21356001618603, -5.17135568677059, 0.176434523975019, 0.230167544593386, -1.38100526756033}, + {-3.44372756077941, 0.485931890194852, -0.230167544593387, -0.17643452397502, 5.17135568677058, -2.21356001618602, -1.20457074358531, 0.230167544593386, 1.38100526756034}, + {0.404638308746458, -0.404638308746456, 1.13786605847598, 1.11855323498582, -0.838942397791738, 0.838942397791737, -1.11855323498583, -1.13786605847598, 1.19348975147204e-14}, + {0.404638308746458, -0.118553234985829, -0.28284795547736, 2.25318217517853, -1.40140119046319, 1.11531611670256, -0.556094442314379, 0.282847955477361, -1.69708773286415}, + {0.118553234985824, -0.404638308746456, -0.28284795547736, 0.556094442314372, -1.11531611670255, 1.40140119046319, -2.25318217517854, 0.282847955477361, 1.69708773286417}, + {-0.559823901757263, -0.492870367157913, 2.60506707768882, 2.46932174262301, 0.750232850760382, 0.302461418154795, 1.95093340590806, -2.60506707768882, -4.42025514853108}, + {0.492870367157913, 0.559823901757263, 2.60506707768882, -1.95093340590806, -0.302461418154795, -0.750232850760382, -2.46932174262301, -2.60506707768882, 4.42025514853108}, + {-0.559823901757264, 0.740805831642528, -0.0962843375058819, 3.93699695901727, 1.749910031967, -1.93089196185226, 0.951256224701445, 0.096284337505882, -4.88825318371872}, + {-0.740805831642527, 0.559823901757263, -0.0962843375058788, -0.951256224701449, 1.93089196185226, -1.749910031967, -3.93699695901728, 0.09628433750588, 4.88825318371872}, + {0.492870367157913, 0.740805831642527, -0.201023373941063, 0.674175115836558, -2.56560608012889, 1.33192988132845, -0.206177080648912, 0.201023373941063, -0.467998035187647}, + {-0.740805831642527, -0.492870367157913, -0.201023373941065, 0.206177080648914, -1.33192988132845, 2.56560608012889, -0.674175115836559, 0.201023373941066, 0.467998035187645}}; + + // Array of non-zero columns + static const unsigned int nzc4[9] = {10, 12, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc1[9] = {0, 2, 3, 4, 5, 6, 7, 8, 9}; + + static const double FE0_C0_D10[12][9] = \ + {{-0.485931890194853, 3.44372756077941, 1.20457074358531, -0.230167544593389, 0.176434523975015, 0.230167544593389, 2.21356001618602, -5.17135568677058, -1.38100526756033}, + {-0.485931890194854, 0.485931890194854, -2.44372756077941, 6.3759264303559, 2.44372756077941, -6.3759264303559, -0.0537330206183701, 0.0537330206183679, 0.0}, + {-3.44372756077941, 0.485931890194852, -0.176434523975019, -0.23016754459339, -1.20457074358531, 0.230167544593389, 5.17135568677058, -2.21356001618602, 1.38100526756033}, + {0.404638308746458, -0.118553234985828, 2.25318217517853, -0.28284795547736, -0.556094442314379, 0.282847955477361, -1.40140119046319, 1.11531611670256, -1.69708773286415}, + {0.404638308746458, -0.404638308746456, 1.11855323498582, 1.13786605847598, -1.11855323498584, -1.13786605847598, -0.838942397791738, 0.838942397791735, 1.45710757386118e-14}, + {0.118553234985824, -0.404638308746456, 0.556094442314372, -0.282847955477361, -2.25318217517854, 0.282847955477361, -1.11531611670255, 1.40140119046318, 1.69708773286417}, + {-0.559823901757263, 0.740805831642528, 3.93699695901727, -0.0962843375058778, 0.951256224701447, 0.0962843375058791, 1.749910031967, -1.93089196185226, -4.88825318371872}, + {0.492870367157913, 0.740805831642527, 0.674175115836558, -0.201023373941065, -0.206177080648914, 0.201023373941066, -2.56560608012889, 1.33192988132845, -0.467998035187644}, + {-0.559823901757263, -0.492870367157914, 2.46932174262301, 2.60506707768883, 1.95093340590806, -2.60506707768882, 0.750232850760382, 0.302461418154794, -4.42025514853107}, + {-0.740805831642527, -0.492870367157913, 0.206177080648913, -0.201023373941065, -0.674175115836559, 0.201023373941066, -1.33192988132845, 2.56560608012889, 0.467998035187646}, + {0.492870367157913, 0.559823901757263, -1.95093340590806, 2.60506707768882, -2.46932174262301, -2.60506707768882, -0.302461418154794, -0.750232850760383, 4.42025514853107}, + {-0.740805831642527, 0.559823901757263, -0.951256224701447, -0.0962843375058804, -3.93699695901727, 0.0962843375058801, 1.93089196185226, -1.749910031967, 4.88825318371872}}; + + // Array of non-zero columns + static const unsigned int nzc5[9] = {10, 11, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc2[9] = {0, 1, 3, 4, 5, 6, 7, 8, 9}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 400; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 60. + double G[12]; + G[0] = K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 24480 + for (unsigned int ip = 0; ip < 12; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 72 + for (unsigned int r = 0; r < 9; r++) + { + F0 += FE0_C0_D10[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D10[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 24 + double I[3]; + // Number of operations: 8 + I[0] = W12[ip]*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 8 + I[1] = W12[ip]*(F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 8 + I[2] = W12[ip]*(F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 1944 + for (unsigned int j = 0; j < 9; j++) + { + for (unsigned int k = 0; k < 9; k++) + { + // Number of operations to compute entry: 3 + A[nzc1[j]*20 + nzc1[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc1[j]*20 + nzc2[k]] += FE0_C0_D01[ip][j]*FE0_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*20 + nzc1[k]] += FE0_C0_D01[ip][k]*FE0_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*20 + nzc2[k]] += FE0_C0_D10[ip][j]*FE0_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc4[j]*20 + nzc4[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc4[j]*20 + nzc5[k]] += FE0_C0_D01[ip][j]*FE0_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*20 + nzc4[k]] += FE0_C0_D01[ip][k]*FE0_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*20 + nzc5[k]] += FE0_C0_D10[ip][j]*FE0_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p3_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q3_quadrature_finite_element_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q3_quadrature_finite_element_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q3_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q3_quadrature_dofmap_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q3_quadrature_dofmap_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q3_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q3_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q3_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q3_tensor.h new file mode 100644 index 0000000..9d43562 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q3_tensor.h @@ -0,0 +1,9570 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P3_Q3_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P3_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q3_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q3_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q3_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q3_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p3_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 432 + // Number of operations (multiply-add pairs) for tensor contraction: 7491 + // Total number of operations (multiply-add pairs): 7934 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0 = det*(w[0][3]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1 = det*(w[0][3]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0 = det*(w[0][4]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1 = det*(w[0][4]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0 = det*(w[0][5]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1 = det*(w[0][5]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_0_0 = det*(w[0][6]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_0_1 = det*(w[0][6]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_0_0 = det*(w[0][7]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_0_1 = det*(w[0][7]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_0_0 = det*(w[0][8]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_0_1 = det*(w[0][8]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_0_0 = det*(w[0][9]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_0_1 = det*(w[0][9]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0 = det*(w[0][10]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1 = det*(w[0][10]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0 = det*(w[0][11]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_12_1_1 = det*(w[0][12]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_13_1_0 = det*(w[0][13]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_13_1_1 = det*(w[0][13]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_14_1_0 = det*(w[0][14]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_14_1_1 = det*(w[0][14]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_15_1_0 = det*(w[0][15]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_15_1_1 = det*(w[0][15]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_16_1_0 = det*(w[0][16]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_16_1_1 = det*(w[0][16]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_17_1_0 = det*(w[0][17]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_17_1_1 = det*(w[0][17]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_18_1_0 = det*(w[0][18]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_18_1_1 = det*(w[0][18]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_19_1_0 = det*(w[0][19]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_19_1_1 = det*(w[0][19]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0 = det*(w[0][3]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1 = det*(w[0][3]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0 = det*(w[0][4]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1 = det*(w[0][4]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0 = det*(w[0][5]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1 = det*(w[0][5]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_0_0 = det*(w[0][6]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_0_1 = det*(w[0][6]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_0_0 = det*(w[0][7]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_0_1 = det*(w[0][7]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_0_0 = det*(w[0][8]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_0_1 = det*(w[0][8]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_0_0 = det*(w[0][9]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_0_1 = det*(w[0][9]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0 = det*(w[0][10]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1 = det*(w[0][10]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0 = det*(w[0][11]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_12_1_1 = det*(w[0][12]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_13_1_0 = det*(w[0][13]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_13_1_1 = det*(w[0][13]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_14_1_0 = det*(w[0][14]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_14_1_1 = det*(w[0][14]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_15_1_0 = det*(w[0][15]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_15_1_1 = det*(w[0][15]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_16_1_0 = det*(w[0][16]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_16_1_1 = det*(w[0][16]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_17_1_0 = det*(w[0][17]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_17_1_1 = det*(w[0][17]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_18_1_0 = det*(w[0][18]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_18_1_1 = det*(w[0][18]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_19_1_0 = det*(w[0][19]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_19_1_1 = det*(w[0][19]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0 = det*(w[0][3]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1 = det*(w[0][3]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0 = det*(w[0][4]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1 = det*(w[0][4]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0 = det*(w[0][5]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1 = det*(w[0][5]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_0_0 = det*(w[0][6]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_0_1 = det*(w[0][6]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_0_0 = det*(w[0][7]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_0_1 = det*(w[0][7]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_0_0 = det*(w[0][8]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_0_1 = det*(w[0][8]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_0_0 = det*(w[0][9]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_0_1 = det*(w[0][9]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0 = det*(w[0][10]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1 = det*(w[0][10]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0 = det*(w[0][11]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_12_1_1 = det*(w[0][12]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_13_1_0 = det*(w[0][13]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_13_1_1 = det*(w[0][13]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_14_1_0 = det*(w[0][14]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_14_1_1 = det*(w[0][14]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_15_1_0 = det*(w[0][15]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_15_1_1 = det*(w[0][15]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_16_1_0 = det*(w[0][16]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_16_1_1 = det*(w[0][16]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_17_1_0 = det*(w[0][17]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_17_1_1 = det*(w[0][17]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_18_1_0 = det*(w[0][18]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_18_1_1 = det*(w[0][18]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_19_1_0 = det*(w[0][19]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_19_1_1 = det*(w[0][19]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0 = det*(w[0][3]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1 = det*(w[0][3]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0 = det*(w[0][4]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1 = det*(w[0][4]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0 = det*(w[0][5]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1 = det*(w[0][5]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_0_0 = det*(w[0][6]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_0_1 = det*(w[0][6]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_0_0 = det*(w[0][7]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_0_1 = det*(w[0][7]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_0_0 = det*(w[0][8]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_0_1 = det*(w[0][8]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_0_0 = det*(w[0][9]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_0_1 = det*(w[0][9]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0 = det*(w[0][10]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1 = det*(w[0][10]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0 = det*(w[0][11]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_12_1_1 = det*(w[0][12]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_13_1_0 = det*(w[0][13]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_13_1_1 = det*(w[0][13]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_14_1_0 = det*(w[0][14]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_14_1_1 = det*(w[0][14]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_15_1_0 = det*(w[0][15]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_15_1_1 = det*(w[0][15]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_16_1_0 = det*(w[0][16]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_16_1_1 = det*(w[0][16]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_17_1_0 = det*(w[0][17]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_17_1_1 = det*(w[0][17]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_18_1_0 = det*(w[0][18]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_18_1_1 = det*(w[0][18]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_19_1_0 = det*(w[0][19]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_19_1_1 = det*(w[0][19]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[143] = -0.216964285714289*G0_0_0_0_0_0 - 0.216964285714289*G0_0_0_0_0_1 + 0.379687500000003*G0_0_0_1_0_0 + 0.0542410714285704*G0_0_0_2_0_1 + 0.86785714285718*G0_0_0_3_0_0 + 0.81361607142859*G0_0_0_3_0_1 + 0.271205357142863*G0_0_0_4_0_0 + 0.650892857142885*G0_0_0_4_0_1 + 0.976339285714305*G0_0_0_5_0_0 + 0.542410714285726*G0_0_0_5_0_1 - 0.271205357142863*G0_0_0_6_0_0 - 0.379687500000007*G0_0_0_6_0_1 + 0.976339285714295*G0_0_0_7_0_0 + 1.41026785714287*G0_0_0_7_0_1 - 1.13906250000001*G0_0_0_8_0_0 - 0.81361607142859*G0_0_0_8_0_1 - 1.84419642857148*G0_0_0_9_0_0 - 2.06116071428576*G0_0_0_9_0_1 - 0.216964285714289*G0_0_0_10_1_0 - 0.216964285714289*G0_0_0_10_1_1 + 0.379687500000003*G0_0_0_11_1_0 + 0.0542410714285704*G0_0_0_12_1_1 + 0.86785714285718*G0_0_0_13_1_0 + 0.81361607142859*G0_0_0_13_1_1 + 0.271205357142863*G0_0_0_14_1_0 + 0.650892857142885*G0_0_0_14_1_1 + 0.976339285714305*G0_0_0_15_1_0 + 0.542410714285726*G0_0_0_15_1_1 - 0.271205357142863*G0_0_0_16_1_0 - 0.379687500000007*G0_0_0_16_1_1 + 0.976339285714295*G0_0_0_17_1_0 + 1.41026785714287*G0_0_0_17_1_1 - 1.13906250000001*G0_0_0_18_1_0 - 0.81361607142859*G0_0_0_18_1_1 - 1.84419642857148*G0_0_0_19_1_0 - 2.06116071428576*G0_0_0_19_1_1 - 0.331473214285721*G0_0_1_0_0_0 - 0.33147321428572*G0_0_1_0_0_1 + 1.1450892857143*G0_0_1_1_0_0 - 0.0482142857142896*G0_0_1_2_0_1 + 0.81361607142859*G0_0_1_3_0_0 + 1.95267857142859*G0_0_1_3_0_1 + 0.0542410714285858*G0_0_1_4_0_1 + 0.379687500000006*G0_0_1_5_0_0 + 0.108482142857147*G0_0_1_5_0_1 + 0.271205357142863*G0_0_1_6_0_1 + 1.73571428571431*G0_0_1_7_0_0 + 2.00691964285717*G0_0_1_7_0_1 - 2.54933035714289*G0_0_1_8_0_0 - 1.95267857142859*G0_0_1_8_0_1 - 1.1933035714286*G0_0_1_9_0_0 - 2.06116071428576*G0_0_1_9_0_1 - 0.331473214285721*G0_0_1_10_1_0 - 0.33147321428572*G0_0_1_10_1_1 + 1.1450892857143*G0_0_1_11_1_0 - 0.0482142857142896*G0_0_1_12_1_1 + 0.81361607142859*G0_0_1_13_1_0 + 1.95267857142859*G0_0_1_13_1_1 + 0.0542410714285858*G0_0_1_14_1_1 + 0.379687500000006*G0_0_1_15_1_0 + 0.108482142857147*G0_0_1_15_1_1 + 0.271205357142863*G0_0_1_16_1_1 + 1.73571428571431*G0_0_1_17_1_0 + 2.00691964285717*G0_0_1_17_1_1 - 2.54933035714289*G0_0_1_18_1_0 - 1.95267857142859*G0_0_1_18_1_1 - 1.1933035714286*G0_0_1_19_1_0 - 2.06116071428576*G0_0_1_19_1_1 - 0.385714285714292*G0_1_0_0_0_0 - 0.385714285714292*G0_1_0_0_0_1 + 0.494196428571433*G0_1_0_1_0_0 - 0.0482142857142882*G0_1_0_2_0_1 + 1.08482142857146*G0_1_0_3_0_0 + 0.976339285714303*G0_1_0_3_0_1 + 0.21696428571429*G0_1_0_4_0_0 + 0.86785714285717*G0_1_0_4_0_1 + 0.650892857142867*G0_1_0_5_0_0 + 0.542410714285725*G0_1_0_5_0_1 - 0.21696428571429*G0_1_0_6_0_0 - 0.108482142857145*G0_1_0_6_0_1 + 1.41026785714287*G0_1_0_7_0_0 + 1.51875000000002*G0_1_0_7_0_1 - 1.51875000000002*G0_1_0_8_0_0 - 0.976339285714303*G0_1_0_8_0_1 - 1.73571428571433*G0_1_0_9_0_0 - 2.38660714285719*G0_1_0_9_0_1 - 0.385714285714292*G0_1_0_10_1_0 - 0.385714285714292*G0_1_0_10_1_1 + 0.494196428571433*G0_1_0_11_1_0 - 0.0482142857142882*G0_1_0_12_1_1 + 1.08482142857146*G0_1_0_13_1_0 + 0.976339285714303*G0_1_0_13_1_1 + 0.21696428571429*G0_1_0_14_1_0 + 0.86785714285717*G0_1_0_14_1_1 + 0.650892857142867*G0_1_0_15_1_0 + 0.542410714285725*G0_1_0_15_1_1 - 0.21696428571429*G0_1_0_16_1_0 - 0.108482142857145*G0_1_0_16_1_1 + 1.41026785714287*G0_1_0_17_1_0 + 1.51875000000002*G0_1_0_17_1_1 - 1.51875000000002*G0_1_0_18_1_0 - 0.976339285714303*G0_1_0_18_1_1 - 1.73571428571433*G0_1_0_19_1_0 - 2.38660714285719*G0_1_0_19_1_1 - 0.500223214285721*G0_1_1_0_0_0 - 0.500223214285721*G0_1_1_0_0_1 + 1.3138392857143*G0_1_1_1_0_0 - 0.0421875000000041*G0_1_1_2_0_1 + 0.976339285714303*G0_1_1_3_0_0 + 2.27812500000002*G0_1_1_3_0_1 - 0.0542410714285713*G0_1_1_4_0_0 + 0.216964285714292*G0_1_1_5_0_0 + 0.271205357142861*G0_1_1_5_0_1 + 0.0542410714285715*G0_1_1_6_0_0 + 0.271205357142863*G0_1_1_6_0_1 + 2.00691964285717*G0_1_1_7_0_0 + 1.9526785714286*G0_1_1_7_0_1 - 2.82053571428575*G0_1_1_8_0_0 - 2.27812500000002*G0_1_1_8_0_1 - 1.19330357142859*G0_1_1_9_0_0 - 1.95267857142862*G0_1_1_9_0_1 - 0.500223214285721*G0_1_1_10_1_0 - 0.500223214285721*G0_1_1_10_1_1 + 1.3138392857143*G0_1_1_11_1_0 - 0.0421875000000041*G0_1_1_12_1_1 + 0.976339285714303*G0_1_1_13_1_0 + 2.27812500000002*G0_1_1_13_1_1 - 0.0542410714285713*G0_1_1_14_1_0 + 0.216964285714292*G0_1_1_15_1_0 + 0.271205357142861*G0_1_1_15_1_1 + 0.0542410714285715*G0_1_1_16_1_0 + 0.271205357142863*G0_1_1_16_1_1 + 2.00691964285717*G0_1_1_17_1_0 + 1.9526785714286*G0_1_1_17_1_1 - 2.82053571428575*G0_1_1_18_1_0 - 2.27812500000002*G0_1_1_18_1_1 - 1.19330357142859*G0_1_1_19_1_0 - 1.95267857142862*G0_1_1_19_1_1; + A[329] = 0.0; + A[384] = 0.0; + A[207] = 0.0; + A[17] = 0.0; + A[281] = 0.0; + A[304] = 0.0; + A[320] = 0.0; + A[353] = A[143]; + A[172] = 0.0; + A[178] = 0.0; + A[199] = 0.0; + A[288] = 0.0; + A[248] = 0.0; + A[58] = 0.0; + A[14] = 0.0; + A[71] = 0.0; + A[35] = 0.0; + A[92] = 0.0; + A[52] = 0.0; + A[77] = 0.0; + A[327] = 0.0; + A[134] = 0.0; + A[346] = 0.0; + A[155] = 0.0; + A[365] = 0.0; + A[209] = 0.0; + A[224] = 0.0; + A[247] = 0.0; + A[266] = 0.0; + A[91] = 0.0; + A[110] = 0.0; + A[97] = 0.0; + A[381] = 0.0; + A[239] = -0.433928571428571*G0_0_0_1_0_0 + 0.108482142857146*G0_0_0_2_0_1 - 0.831696428571444*G0_0_0_3_0_0 - 1.22946428571429*G0_0_0_3_0_1 + 0.542410714285724*G0_0_0_4_0_0 + 0.397767857142856*G0_0_0_4_0_1 - 0.61473214285716*G0_0_0_5_0_0 - 0.25312500000001*G0_0_0_5_0_1 - 0.542410714285724*G0_0_0_6_0_0 + 0.144642857142864*G0_0_0_6_0_1 - 0.108482142857142*G0_0_0_7_0_0 - 0.470089285714292*G0_0_0_7_0_1 + 0.542410714285712*G0_0_0_8_0_0 + 1.22946428571429*G0_0_0_8_0_1 + 1.4464285714286*G0_0_0_9_0_0 + 0.0723214285714358*G0_0_0_9_0_1 - 0.433928571428571*G0_0_0_11_1_0 + 0.108482142857146*G0_0_0_12_1_1 - 0.831696428571444*G0_0_0_13_1_0 - 1.22946428571429*G0_0_0_13_1_1 + 0.542410714285724*G0_0_0_14_1_0 + 0.397767857142856*G0_0_0_14_1_1 - 0.61473214285716*G0_0_0_15_1_0 - 0.25312500000001*G0_0_0_15_1_1 - 0.542410714285724*G0_0_0_16_1_0 + 0.144642857142864*G0_0_0_16_1_1 - 0.108482142857142*G0_0_0_17_1_0 - 0.470089285714292*G0_0_0_17_1_1 + 0.542410714285712*G0_0_0_18_1_0 + 1.22946428571429*G0_0_0_18_1_1 + 1.4464285714286*G0_0_0_19_1_0 + 0.0723214285714358*G0_0_0_19_1_1 + 0.108482142857145*G0_0_1_0_0_0 + 0.108482142857145*G0_0_1_0_0_1 + 0.108482142857145*G0_0_1_2_0_1 - 0.144642857142863*G0_0_1_3_0_0 + 0.180803571428572*G0_0_1_4_0_0 - 0.0723214285714366*G0_0_1_4_0_1 + 0.0723214285714277*G0_0_1_5_0_0 - 0.108482142857146*G0_0_1_5_0_1 - 0.180803571428572*G0_0_1_6_0_0 - 0.108482142857145*G0_0_1_6_0_1 - 0.253125000000008*G0_0_1_7_0_0 - 0.0723214285714344*G0_0_1_7_0_1 + 0.144642857142861*G0_0_1_8_0_0 + 0.0723214285714358*G0_0_1_9_0_0 + 0.144642857142871*G0_0_1_9_0_1 + 0.108482142857145*G0_0_1_10_1_0 + 0.108482142857145*G0_0_1_10_1_1 + 0.108482142857145*G0_0_1_12_1_1 - 0.144642857142863*G0_0_1_13_1_0 + 0.180803571428572*G0_0_1_14_1_0 - 0.0723214285714366*G0_0_1_14_1_1 + 0.0723214285714277*G0_0_1_15_1_0 - 0.108482142857146*G0_0_1_15_1_1 - 0.180803571428572*G0_0_1_16_1_0 - 0.108482142857145*G0_0_1_16_1_1 - 0.253125000000008*G0_0_1_17_1_0 - 0.0723214285714344*G0_0_1_17_1_1 + 0.144642857142861*G0_0_1_18_1_0 + 0.0723214285714358*G0_0_1_19_1_0 + 0.144642857142871*G0_0_1_19_1_1; + A[180] = A[239] + 0.433928571428572*G0_0_0_0_0_0 + 0.433928571428572*G0_0_0_0_0_1 + 0.433928571428571*G0_0_0_1_0_0 + 1.44642857142861*G0_0_0_3_0_0 + 1.59107142857144*G0_0_0_3_0_1 + 0.289285714285734*G0_0_0_4_0_1 + 1.4464285714286*G0_0_0_5_0_0 - 0.144642857142842*G0_0_0_5_0_1 - 0.28928571428573*G0_0_0_6_0_1 - 0.433928571428572*G0_0_0_7_0_0 + 1.15714285714287*G0_0_0_7_0_1 - 0.43392857142857*G0_0_0_8_0_0 - 1.59107142857144*G0_0_0_8_0_1 - 2.89285714285721*G0_0_0_9_0_0 - 1.44642857142861*G0_0_0_9_0_1 + 0.433928571428572*G0_0_0_10_1_0 + 0.433928571428572*G0_0_0_10_1_1 + 0.433928571428571*G0_0_0_11_1_0 + 1.44642857142861*G0_0_0_13_1_0 + 1.59107142857144*G0_0_0_13_1_1 + 0.289285714285734*G0_0_0_14_1_1 + 1.4464285714286*G0_0_0_15_1_0 - 0.144642857142842*G0_0_0_15_1_1 - 0.28928571428573*G0_0_0_16_1_1 - 0.433928571428572*G0_0_0_17_1_0 + 1.15714285714287*G0_0_0_17_1_1 - 0.43392857142857*G0_0_0_18_1_0 - 1.59107142857144*G0_0_0_18_1_1 - 2.89285714285721*G0_0_0_19_1_0 - 1.44642857142861*G0_0_0_19_1_1 + 0.325446428571427*G0_0_1_0_0_0 + 0.325446428571427*G0_0_1_0_0_1 + 0.759375000000025*G0_0_1_3_0_0 + 0.361607142857149*G0_0_1_3_0_1 + 0.361607142857153*G0_0_1_4_0_0 + 0.759375000000027*G0_0_1_4_0_1 + 0.759375000000016*G0_0_1_5_0_0 - 0.289285714285706*G0_0_1_5_0_1 - 0.361607142857153*G0_0_1_6_0_0 - 0.0361607142857207*G0_0_1_6_0_1 - 0.289285714285707*G0_0_1_7_0_0 + 0.759375000000016*G0_0_1_7_0_1 - 0.0361607142857192*G0_0_1_8_0_0 - 0.361607142857149*G0_0_1_8_0_1 - 1.51875000000004*G0_0_1_9_0_0 - 1.51875000000004*G0_0_1_9_0_1 + 0.325446428571427*G0_0_1_10_1_0 + 0.325446428571427*G0_0_1_10_1_1 + 0.759375000000025*G0_0_1_13_1_0 + 0.361607142857149*G0_0_1_13_1_1 + 0.361607142857153*G0_0_1_14_1_0 + 0.759375000000027*G0_0_1_14_1_1 + 0.759375000000016*G0_0_1_15_1_0 - 0.289285714285706*G0_0_1_15_1_1 - 0.361607142857153*G0_0_1_16_1_0 - 0.0361607142857207*G0_0_1_16_1_1 - 0.289285714285707*G0_0_1_17_1_0 + 0.759375000000016*G0_0_1_17_1_1 - 0.0361607142857192*G0_0_1_18_1_0 - 0.361607142857149*G0_0_1_18_1_1 - 1.51875000000004*G0_0_1_19_1_0 - 1.51875000000004*G0_0_1_19_1_1 + 0.433928571428573*G0_1_0_0_0_0 + 0.433928571428574*G0_1_0_0_0_1 + 0.108482142857145*G0_1_0_1_0_0 + 0.68705357142859*G0_1_0_3_0_0 + 0.542410714285724*G0_1_0_3_0_1 + 0.361607142857152*G0_1_0_4_0_0 + 0.614732142857162*G0_1_0_4_0_1 + 0.687053571428583*G0_1_0_5_0_0 - 0.542410714285716*G0_1_0_5_0_1 - 0.361607142857152*G0_1_0_6_0_0 + 0.108482142857143*G0_1_0_6_0_1 - 0.397767857142853*G0_1_0_7_0_0 + 0.831696428571445*G0_1_0_7_0_1 - 0.144642857142866*G0_1_0_8_0_0 - 0.542410714285724*G0_1_0_8_0_1 - 1.37410714285717*G0_1_0_9_0_0 - 1.44642857142861*G0_1_0_9_0_1 + 0.433928571428573*G0_1_0_10_1_0 + 0.433928571428574*G0_1_0_10_1_1 + 0.108482142857145*G0_1_0_11_1_0 + 0.68705357142859*G0_1_0_13_1_0 + 0.542410714285724*G0_1_0_13_1_1 + 0.361607142857152*G0_1_0_14_1_0 + 0.614732142857162*G0_1_0_14_1_1 + 0.687053571428583*G0_1_0_15_1_0 - 0.542410714285716*G0_1_0_15_1_1 - 0.361607142857152*G0_1_0_16_1_0 + 0.108482142857143*G0_1_0_16_1_1 - 0.397767857142853*G0_1_0_17_1_0 + 0.831696428571445*G0_1_0_17_1_1 - 0.144642857142866*G0_1_0_18_1_0 - 0.542410714285724*G0_1_0_18_1_1 - 1.37410714285717*G0_1_0_19_1_0 - 1.44642857142861*G0_1_0_19_1_1 + 0.433928571428574*G0_1_1_0_0_0 + 0.433928571428574*G0_1_1_0_0_1 + 0.108482142857145*G0_1_1_1_0_0 + 0.68705357142859*G0_1_1_3_0_0 + 0.542410714285724*G0_1_1_3_0_1 + 0.361607142857152*G0_1_1_4_0_0 + 0.614732142857162*G0_1_1_4_0_1 + 0.687053571428583*G0_1_1_5_0_0 - 0.542410714285717*G0_1_1_5_0_1 - 0.361607142857152*G0_1_1_6_0_0 + 0.108482142857143*G0_1_1_6_0_1 - 0.397767857142853*G0_1_1_7_0_0 + 0.831696428571446*G0_1_1_7_0_1 - 0.144642857142866*G0_1_1_8_0_0 - 0.542410714285724*G0_1_1_8_0_1 - 1.37410714285717*G0_1_1_9_0_0 - 1.44642857142861*G0_1_1_9_0_1 + 0.433928571428574*G0_1_1_10_1_0 + 0.433928571428574*G0_1_1_10_1_1 + 0.108482142857145*G0_1_1_11_1_0 + 0.68705357142859*G0_1_1_13_1_0 + 0.542410714285724*G0_1_1_13_1_1 + 0.361607142857152*G0_1_1_14_1_0 + 0.614732142857162*G0_1_1_14_1_1 + 0.687053571428583*G0_1_1_15_1_0 - 0.542410714285717*G0_1_1_15_1_1 - 0.361607142857152*G0_1_1_16_1_0 + 0.108482142857143*G0_1_1_16_1_1 - 0.397767857142853*G0_1_1_17_1_0 + 0.831696428571446*G0_1_1_17_1_1 - 0.144642857142866*G0_1_1_18_1_0 - 0.542410714285724*G0_1_1_18_1_1 - 1.37410714285717*G0_1_1_19_1_0 - 1.44642857142861*G0_1_1_19_1_1; + A[235] = A[239] + 0.0796875000000008*G0_0_0_0_0_0 + 0.0796875000000009*G0_0_0_0_0_1 + 0.408482142857141*G0_0_0_1_0_0 - 0.0676339285714307*G0_0_0_2_0_1 + 1.06071428571431*G0_0_0_3_0_0 + 1.39821428571429*G0_0_0_3_0_1 - 0.584598214285726*G0_0_0_4_0_0 - 0.445982142857142*G0_0_0_4_0_1 + 1.00044642857146*G0_0_0_5_0_0 + 0.391741071428588*G0_0_0_5_0_1 + 0.584598214285726*G0_0_0_6_0_0 - 0.403794642857159*G0_0_0_6_0_1 - 0.162723214285719*G0_0_0_7_0_0 + 0.445982142857151*G0_0_0_7_0_1 - 0.325446428571422*G0_0_0_8_0_0 - 1.3982142857143*G0_0_0_8_0_1 - 2.06116071428577*G0_0_0_9_0_0 + 0.0796875000000008*G0_0_0_10_1_0 + 0.0796875000000009*G0_0_0_10_1_1 + 0.408482142857141*G0_0_0_11_1_0 - 0.0676339285714307*G0_0_0_12_1_1 + 1.06071428571431*G0_0_0_13_1_0 + 1.39821428571429*G0_0_0_13_1_1 - 0.584598214285726*G0_0_0_14_1_0 - 0.445982142857142*G0_0_0_14_1_1 + 1.00044642857146*G0_0_0_15_1_0 + 0.391741071428588*G0_0_0_15_1_1 + 0.584598214285726*G0_0_0_16_1_0 - 0.403794642857159*G0_0_0_16_1_1 - 0.162723214285719*G0_0_0_17_1_0 + 0.445982142857151*G0_0_0_17_1_1 - 0.325446428571422*G0_0_0_18_1_0 - 1.3982142857143*G0_0_0_18_1_1 - 2.06116071428577*G0_0_0_19_1_0 - 0.295312500000004*G0_0_1_0_0_0 - 0.295312500000004*G0_0_1_0_0_1 - 0.0964285714285741*G0_0_1_2_0_1 + 0.259151785714295*G0_0_1_3_0_0 - 0.229017857142861*G0_0_1_4_0_0 + 0.126562500000007*G0_0_1_4_0_1 + 0.0662946428571506*G0_0_1_5_0_0 + 0.494196428571438*G0_0_1_5_0_1 + 0.229017857142861*G0_0_1_6_0_0 - 0.10245535714286*G0_0_1_6_0_1 + 0.554464285714297*G0_0_1_7_0_0 + 0.12656250000001*G0_0_1_7_0_1 - 0.259151785714292*G0_0_1_8_0_0 - 0.325446428571446*G0_0_1_9_0_0 - 0.253125000000017*G0_0_1_9_0_1 - 0.295312500000004*G0_0_1_10_1_0 - 0.295312500000004*G0_0_1_10_1_1 - 0.0964285714285741*G0_0_1_12_1_1 + 0.259151785714295*G0_0_1_13_1_0 - 0.229017857142861*G0_0_1_14_1_0 + 0.126562500000007*G0_0_1_14_1_1 + 0.0662946428571506*G0_0_1_15_1_0 + 0.494196428571438*G0_0_1_15_1_1 + 0.229017857142861*G0_0_1_16_1_0 - 0.10245535714286*G0_0_1_16_1_1 + 0.554464285714297*G0_0_1_17_1_0 + 0.12656250000001*G0_0_1_17_1_1 - 0.259151785714292*G0_0_1_18_1_0 - 0.325446428571446*G0_0_1_19_1_0 - 0.253125000000017*G0_0_1_19_1_1; + A[101] = A[235] + 0.186830357142859*G0_0_1_0_0_0 + 0.186830357142859*G0_0_1_0_0_1 - 0.0120535714285714*G0_0_1_2_0_1 - 0.114508928571431*G0_0_1_3_0_0 + 0.0482142857142879*G0_0_1_4_0_0 - 0.0542410714285708*G0_0_1_4_0_1 - 0.138616071428578*G0_0_1_5_0_0 - 0.385714285714292*G0_0_1_5_0_1 - 0.0482142857142879*G0_0_1_6_0_0 + 0.210937500000005*G0_0_1_6_0_1 - 0.301339285714289*G0_0_1_7_0_0 - 0.054241071428575*G0_0_1_7_0_1 + 0.114508928571431*G0_0_1_8_0_0 + 0.25312500000001*G0_0_1_9_0_0 + 0.108482142857146*G0_0_1_9_0_1 + 0.186830357142859*G0_0_1_10_1_0 + 0.186830357142859*G0_0_1_10_1_1 - 0.0120535714285714*G0_0_1_12_1_1 - 0.114508928571431*G0_0_1_13_1_0 + 0.0482142857142879*G0_0_1_14_1_0 - 0.0542410714285708*G0_0_1_14_1_1 - 0.138616071428578*G0_0_1_15_1_0 - 0.385714285714292*G0_0_1_15_1_1 - 0.0482142857142879*G0_0_1_16_1_0 + 0.210937500000005*G0_0_1_16_1_1 - 0.301339285714289*G0_0_1_17_1_0 - 0.054241071428575*G0_0_1_17_1_1 + 0.114508928571431*G0_0_1_18_1_0 + 0.25312500000001*G0_0_1_19_1_0 + 0.108482142857146*G0_0_1_19_1_1 - 0.186830357142859*G0_1_0_0_0_0 - 0.186830357142859*G0_1_0_0_0_1 + 0.0120535714285714*G0_1_0_2_0_1 + 0.114508928571431*G0_1_0_3_0_0 - 0.0482142857142879*G0_1_0_4_0_0 + 0.0542410714285708*G0_1_0_4_0_1 + 0.138616071428578*G0_1_0_5_0_0 + 0.385714285714292*G0_1_0_5_0_1 + 0.048214285714288*G0_1_0_6_0_0 - 0.210937500000005*G0_1_0_6_0_1 + 0.301339285714289*G0_1_0_7_0_0 + 0.054241071428575*G0_1_0_7_0_1 - 0.114508928571431*G0_1_0_8_0_0 - 0.25312500000001*G0_1_0_9_0_0 - 0.108482142857146*G0_1_0_9_0_1 - 0.186830357142859*G0_1_0_10_1_0 - 0.186830357142859*G0_1_0_10_1_1 + 0.0120535714285714*G0_1_0_12_1_1 + 0.114508928571431*G0_1_0_13_1_0 - 0.0482142857142879*G0_1_0_14_1_0 + 0.0542410714285708*G0_1_0_14_1_1 + 0.138616071428578*G0_1_0_15_1_0 + 0.385714285714292*G0_1_0_15_1_1 + 0.048214285714288*G0_1_0_16_1_0 - 0.210937500000005*G0_1_0_16_1_1 + 0.301339285714289*G0_1_0_17_1_0 + 0.054241071428575*G0_1_0_17_1_1 - 0.114508928571431*G0_1_0_18_1_0 - 0.25312500000001*G0_1_0_19_1_0 - 0.108482142857146*G0_1_0_19_1_1; + A[219] = A[180] + 0.108482142857145*G0_0_1_1_0_0 - 0.108482142857145*G0_0_1_2_0_1 + 0.0723214285714282*G0_0_1_3_0_0 + 0.180803571428574*G0_0_1_3_0_1 - 0.180803571428573*G0_0_1_4_0_0 - 0.0723214285714278*G0_0_1_4_0_1 - 0.144642857142862*G0_0_1_5_0_0 - 0.144642857142864*G0_0_1_5_0_1 + 0.180803571428573*G0_0_1_6_0_0 + 0.253125000000009*G0_0_1_6_0_1 + 0.144642857142861*G0_0_1_7_0_0 + 0.144642857142864*G0_0_1_7_0_1 - 0.253125000000008*G0_0_1_8_0_0 - 0.180803571428574*G0_0_1_8_0_1 + 0.0723214285714342*G0_0_1_9_0_0 - 0.0723214285714358*G0_0_1_9_0_1 + 0.108482142857145*G0_0_1_11_1_0 - 0.108482142857145*G0_0_1_12_1_1 + 0.0723214285714282*G0_0_1_13_1_0 + 0.180803571428574*G0_0_1_13_1_1 - 0.180803571428573*G0_0_1_14_1_0 - 0.0723214285714278*G0_0_1_14_1_1 - 0.144642857142862*G0_0_1_15_1_0 - 0.144642857142864*G0_0_1_15_1_1 + 0.180803571428573*G0_0_1_16_1_0 + 0.253125000000009*G0_0_1_16_1_1 + 0.144642857142861*G0_0_1_17_1_0 + 0.144642857142864*G0_0_1_17_1_1 - 0.253125000000008*G0_0_1_18_1_0 - 0.180803571428574*G0_0_1_18_1_1 + 0.0723214285714342*G0_0_1_19_1_0 - 0.0723214285714358*G0_0_1_19_1_1 - 0.108482142857145*G0_1_0_1_0_0 + 0.108482142857145*G0_1_0_2_0_1 - 0.072321428571428*G0_1_0_3_0_0 - 0.180803571428574*G0_1_0_3_0_1 + 0.180803571428573*G0_1_0_4_0_0 + 0.0723214285714278*G0_1_0_4_0_1 + 0.144642857142862*G0_1_0_5_0_0 + 0.144642857142864*G0_1_0_5_0_1 - 0.180803571428573*G0_1_0_6_0_0 - 0.253125000000009*G0_1_0_6_0_1 - 0.144642857142861*G0_1_0_7_0_0 - 0.144642857142864*G0_1_0_7_0_1 + 0.253125000000008*G0_1_0_8_0_0 + 0.180803571428574*G0_1_0_8_0_1 - 0.072321428571434*G0_1_0_9_0_0 + 0.0723214285714355*G0_1_0_9_0_1 - 0.108482142857145*G0_1_0_11_1_0 + 0.108482142857145*G0_1_0_12_1_1 - 0.072321428571428*G0_1_0_13_1_0 - 0.180803571428574*G0_1_0_13_1_1 + 0.180803571428573*G0_1_0_14_1_0 + 0.0723214285714278*G0_1_0_14_1_1 + 0.144642857142862*G0_1_0_15_1_0 + 0.144642857142864*G0_1_0_15_1_1 - 0.180803571428573*G0_1_0_16_1_0 - 0.253125000000009*G0_1_0_16_1_1 - 0.144642857142861*G0_1_0_17_1_0 - 0.144642857142864*G0_1_0_17_1_1 + 0.253125000000008*G0_1_0_18_1_0 + 0.180803571428574*G0_1_0_18_1_1 - 0.072321428571434*G0_1_0_19_1_0 + 0.0723214285714355*G0_1_0_19_1_1; + A[121] = A[101] - 0.108482142857144*G0_0_0_0_0_0 - 0.108482142857144*G0_0_0_0_0_1 - 0.307366071428577*G0_0_0_2_0_1 + 0.27120535714286*G0_0_0_3_0_0 - 0.452008928571436*G0_0_0_4_0_0 + 0.126562500000001*G0_0_0_4_0_1 - 0.343526785714296*G0_0_0_5_0_0 - 0.0904017857142901*G0_0_0_5_0_1 + 0.452008928571436*G0_0_0_6_0_0 + 0.506250000000012*G0_0_0_6_0_1 + 0.379687500000005*G0_0_0_7_0_0 + 0.126562499999999*G0_0_0_7_0_1 - 0.271205357142861*G0_0_0_8_0_0 + 0.0723214285714364*G0_0_0_9_0_0 - 0.253125*G0_0_0_9_0_1 - 0.108482142857144*G0_0_0_10_1_0 - 0.108482142857144*G0_0_0_10_1_1 - 0.307366071428577*G0_0_0_12_1_1 + 0.27120535714286*G0_0_0_13_1_0 - 0.452008928571436*G0_0_0_14_1_0 + 0.126562500000001*G0_0_0_14_1_1 - 0.343526785714296*G0_0_0_15_1_0 - 0.0904017857142901*G0_0_0_15_1_1 + 0.452008928571436*G0_0_0_16_1_0 + 0.506250000000012*G0_0_0_16_1_1 + 0.379687500000005*G0_0_0_17_1_0 + 0.126562499999999*G0_0_0_17_1_1 - 0.271205357142861*G0_0_0_18_1_0 + 0.0723214285714364*G0_0_0_19_1_0 - 0.253125*G0_0_0_19_1_1 + 0.19888392857143*G0_1_0_0_0_0 + 0.19888392857143*G0_1_0_0_0_1 - 0.198883928571432*G0_1_0_2_0_1 - 0.198883928571429*G0_1_0_4_0_0 - 0.397767857142873*G0_1_0_5_0_0 - 0.596651785714297*G0_1_0_5_0_1 + 0.198883928571429*G0_1_0_6_0_0 + 0.596651785714299*G0_1_0_6_0_1 - 0.198883928571429*G0_1_0_7_0_0 + 0.397767857142874*G0_1_0_9_0_0 + 0.19888392857143*G0_1_0_10_1_0 + 0.19888392857143*G0_1_0_10_1_1 - 0.198883928571432*G0_1_0_12_1_1 - 0.198883928571429*G0_1_0_14_1_0 - 0.397767857142873*G0_1_0_15_1_0 - 0.596651785714297*G0_1_0_15_1_1 + 0.198883928571429*G0_1_0_16_1_0 + 0.596651785714299*G0_1_0_16_1_1 - 0.198883928571429*G0_1_0_17_1_0 + 0.397767857142874*G0_1_0_19_1_0; + A[331] = A[121]; + A[138] = 0.0; + A[386] = 0.0; + A[205] = 0.0; + A[228] = 0.0; + A[19] = 0.0; + A[287] = 0.0; + A[259] = 0.108482142857146*G0_1_0_0_0_0 + 0.108482142857146*G0_1_0_0_0_1 + 0.108482142857146*G0_1_0_1_0_0 - 0.0723214285714349*G0_1_0_3_0_0 + 0.180803571428574*G0_1_0_3_0_1 - 0.144642857142864*G0_1_0_4_0_1 - 0.0723214285714339*G0_1_0_5_0_0 - 0.253125000000008*G0_1_0_5_0_1 + 0.144642857142862*G0_1_0_6_0_1 - 0.108482142857145*G0_1_0_7_0_0 + 0.072321428571429*G0_1_0_7_0_1 - 0.108482142857146*G0_1_0_8_0_0 - 0.180803571428574*G0_1_0_8_0_1 + 0.144642857142869*G0_1_0_9_0_0 + 0.0723214285714352*G0_1_0_9_0_1 + 0.108482142857146*G0_1_0_10_1_0 + 0.108482142857146*G0_1_0_10_1_1 + 0.108482142857146*G0_1_0_11_1_0 - 0.0723214285714349*G0_1_0_13_1_0 + 0.180803571428574*G0_1_0_13_1_1 - 0.144642857142864*G0_1_0_14_1_1 - 0.0723214285714339*G0_1_0_15_1_0 - 0.253125000000008*G0_1_0_15_1_1 + 0.144642857142862*G0_1_0_16_1_1 - 0.108482142857145*G0_1_0_17_1_0 + 0.072321428571429*G0_1_0_17_1_1 - 0.108482142857146*G0_1_0_18_1_0 - 0.180803571428574*G0_1_0_18_1_1 + 0.144642857142869*G0_1_0_19_1_0 + 0.0723214285714352*G0_1_0_19_1_1 + 0.108482142857145*G0_1_1_1_0_0 - 0.433928571428573*G0_1_1_2_0_1 + 0.397767857142859*G0_1_1_3_0_0 + 0.542410714285724*G0_1_1_3_0_1 - 1.2294642857143*G0_1_1_4_0_0 - 0.831696428571445*G0_1_1_4_0_1 - 0.470089285714294*G0_1_1_5_0_0 - 0.108482142857143*G0_1_1_5_0_1 + 1.2294642857143*G0_1_1_6_0_0 + 0.542410714285716*G0_1_1_6_0_1 - 0.253125000000011*G0_1_1_7_0_0 - 0.614732142857161*G0_1_1_7_0_1 + 0.144642857142865*G0_1_1_8_0_0 - 0.542410714285724*G0_1_1_8_0_1 + 0.0723214285714351*G0_1_1_9_0_0 + 1.44642857142861*G0_1_1_9_0_1 + 0.108482142857145*G0_1_1_11_1_0 - 0.433928571428573*G0_1_1_12_1_1 + 0.397767857142859*G0_1_1_13_1_0 + 0.542410714285724*G0_1_1_13_1_1 - 1.2294642857143*G0_1_1_14_1_0 - 0.831696428571445*G0_1_1_14_1_1 - 0.470089285714294*G0_1_1_15_1_0 - 0.108482142857143*G0_1_1_15_1_1 + 1.2294642857143*G0_1_1_16_1_0 + 0.542410714285716*G0_1_1_16_1_1 - 0.253125000000011*G0_1_1_17_1_0 - 0.614732142857161*G0_1_1_17_1_1 + 0.144642857142865*G0_1_1_18_1_0 - 0.542410714285724*G0_1_1_18_1_1 + 0.0723214285714351*G0_1_1_19_1_0 + 1.44642857142861*G0_1_1_19_1_1; + A[257] = A[259] - 0.295312500000004*G0_1_0_0_0_0 - 0.295312500000004*G0_1_0_0_0_1 - 0.0964285714285752*G0_1_0_1_0_0 + 0.126562500000005*G0_1_0_3_0_0 - 0.229017857142864*G0_1_0_3_0_1 + 0.259151785714297*G0_1_0_4_0_1 + 0.126562500000009*G0_1_0_5_0_0 + 0.554464285714297*G0_1_0_5_0_1 - 0.259151785714293*G0_1_0_6_0_1 + 0.494196428571437*G0_1_0_7_0_0 + 0.0662946428571491*G0_1_0_7_0_1 - 0.102455357142858*G0_1_0_8_0_0 + 0.229017857142864*G0_1_0_8_0_1 - 0.253125000000014*G0_1_0_9_0_0 - 0.325446428571446*G0_1_0_9_0_1 - 0.295312500000004*G0_1_0_10_1_0 - 0.295312500000004*G0_1_0_10_1_1 - 0.0964285714285752*G0_1_0_11_1_0 + 0.126562500000005*G0_1_0_13_1_0 - 0.229017857142864*G0_1_0_13_1_1 + 0.259151785714297*G0_1_0_14_1_1 + 0.126562500000009*G0_1_0_15_1_0 + 0.554464285714297*G0_1_0_15_1_1 - 0.259151785714293*G0_1_0_16_1_1 + 0.494196428571437*G0_1_0_17_1_0 + 0.0662946428571491*G0_1_0_17_1_1 - 0.102455357142858*G0_1_0_18_1_0 + 0.229017857142864*G0_1_0_18_1_1 - 0.253125000000014*G0_1_0_19_1_0 - 0.325446428571446*G0_1_0_19_1_1 + 0.0796875000000007*G0_1_1_0_0_0 + 0.0796875000000008*G0_1_1_0_0_1 - 0.0676339285714309*G0_1_1_1_0_0 + 0.408482142857143*G0_1_1_2_0_1 - 0.445982142857147*G0_1_1_3_0_0 - 0.584598214285728*G0_1_1_3_0_1 + 1.3982142857143*G0_1_1_4_0_0 + 1.06071428571431*G0_1_1_4_0_1 + 0.445982142857153*G0_1_1_5_0_0 - 0.162723214285718*G0_1_1_5_0_1 - 1.3982142857143*G0_1_1_6_0_0 - 0.325446428571427*G0_1_1_6_0_1 + 0.391741071428589*G0_1_1_7_0_0 + 1.00044642857146*G0_1_1_7_0_1 - 0.403794642857159*G0_1_1_8_0_0 + 0.584598214285728*G0_1_1_8_0_1 - 2.06116071428577*G0_1_1_9_0_1 + 0.0796875000000007*G0_1_1_10_1_0 + 0.0796875000000008*G0_1_1_10_1_1 - 0.0676339285714309*G0_1_1_11_1_0 + 0.408482142857143*G0_1_1_12_1_1 - 0.445982142857147*G0_1_1_13_1_0 - 0.584598214285728*G0_1_1_13_1_1 + 1.3982142857143*G0_1_1_14_1_0 + 1.06071428571431*G0_1_1_14_1_1 + 0.445982142857153*G0_1_1_15_1_0 - 0.162723214285718*G0_1_1_15_1_1 - 1.3982142857143*G0_1_1_16_1_0 - 0.325446428571427*G0_1_1_16_1_1 + 0.391741071428589*G0_1_1_17_1_0 + 1.00044642857146*G0_1_1_17_1_1 - 0.403794642857159*G0_1_1_18_1_0 + 0.584598214285728*G0_1_1_18_1_1 - 2.06116071428577*G0_1_1_19_1_1; + A[47] = A[257]; + A[38] = 0.0; + A[306] = 0.0; + A[9] = A[219]; + A[322] = 0.0; + A[343] = 0.0; + A[156] = 0.0; + A[368] = 0.0; + A[174] = 0.0; + A[195] = 0.0; + A[221] = 0.0; + A[197] = 0.0; + A[271] = -0.0796875000000009*G0_0_0_0_0_0 - 0.0796875000000008*G0_0_0_0_0_1 + 0.459375000000001*G0_0_0_1_0_0 - 0.149330357142861*G0_0_0_2_0_1 + 0.602678571428582*G0_0_0_3_0_0 + 1.06071428571429*G0_0_0_3_0_1 - 0.500223214285721*G0_0_0_4_0_0 - 0.349553571428569*G0_0_0_4_0_1 + 0.229017857142862*G0_0_0_5_0_0 + 0.114508928571432*G0_0_0_5_0_1 + 0.500223214285722*G0_0_0_6_0_0 + 0.11450892857143*G0_0_0_6_0_1 + 0.379687500000003*G0_0_0_7_0_0 + 0.494196428571433*G0_0_0_7_0_1 - 0.759375000000003*G0_0_0_8_0_0 - 1.06071428571429*G0_0_0_8_0_1 - 0.831696428571444*G0_0_0_9_0_0 - 0.144642857142863*G0_0_0_9_0_1 - 0.0796875000000009*G0_0_0_10_1_0 - 0.0796875000000008*G0_0_0_10_1_1 + 0.459375000000001*G0_0_0_11_1_0 - 0.149330357142861*G0_0_0_12_1_1 + 0.602678571428582*G0_0_0_13_1_0 + 1.06071428571429*G0_0_0_13_1_1 - 0.500223214285721*G0_0_0_14_1_0 - 0.349553571428569*G0_0_0_14_1_1 + 0.229017857142862*G0_0_0_15_1_0 + 0.114508928571432*G0_0_0_15_1_1 + 0.500223214285722*G0_0_0_16_1_0 + 0.11450892857143*G0_0_0_16_1_1 + 0.379687500000003*G0_0_0_17_1_0 + 0.494196428571433*G0_0_0_17_1_1 - 0.759375000000003*G0_0_0_18_1_0 - 1.06071428571429*G0_0_0_18_1_1 - 0.831696428571444*G0_0_0_19_1_0 - 0.144642857142863*G0_0_0_19_1_1 - 0.266517857142861*G0_1_0_0_0_0 - 0.26651785714286*G0_1_0_0_0_1 + 2.0263392857143*G0_1_0_1_0_0 + 0.26651785714286*G0_1_0_2_0_1 + 1.06071428571429*G0_1_0_3_0_0 + 3.96562500000003*G0_1_0_3_0_1 - 0.168750000000001*G0_1_0_4_0_0 - 1.3138392857143*G0_1_0_4_0_1 + 0.168750000000001*G0_1_0_5_0_0 + 0.168750000000001*G0_1_0_6_0_0 + 1.1450892857143*G0_1_0_7_0_0 + 1.3138392857143*G0_1_0_7_0_1 - 2.90491071428574*G0_1_0_8_0_0 - 3.96562500000003*G0_1_0_8_0_1 - 1.22946428571429*G0_1_0_9_0_0 - 0.266517857142861*G0_1_0_10_1_0 - 0.26651785714286*G0_1_0_10_1_1 + 2.0263392857143*G0_1_0_11_1_0 + 0.26651785714286*G0_1_0_12_1_1 + 1.06071428571429*G0_1_0_13_1_0 + 3.96562500000003*G0_1_0_13_1_1 - 0.168750000000001*G0_1_0_14_1_0 - 1.3138392857143*G0_1_0_14_1_1 + 0.168750000000001*G0_1_0_15_1_0 + 0.168750000000001*G0_1_0_16_1_0 + 1.1450892857143*G0_1_0_17_1_0 + 1.3138392857143*G0_1_0_17_1_1 - 2.90491071428574*G0_1_0_18_1_0 - 3.96562500000003*G0_1_0_18_1_1 - 1.22946428571429*G0_1_0_19_1_0; + A[56] = 0.0; + A[73] = 0.0; + A[33] = 0.0; + A[94] = 0.0; + A[50] = 0.0; + A[115] = 0.0; + A[79] = 0.0; + A[132] = 0.0; + A[344] = 0.0; + A[363] = 0.0; + A[226] = 0.0; + A[241] = 0.0; + A[264] = 0.0; + A[26] = A[235] - 0.108482142857144*G0_0_0_0_0_0 - 0.108482142857144*G0_0_0_0_0_1 - 0.307366071428577*G0_0_0_2_0_1 + 0.27120535714286*G0_0_0_3_0_0 - 0.452008928571436*G0_0_0_4_0_0 + 0.126562500000001*G0_0_0_4_0_1 - 0.343526785714296*G0_0_0_5_0_0 - 0.0904017857142901*G0_0_0_5_0_1 + 0.452008928571436*G0_0_0_6_0_0 + 0.506250000000012*G0_0_0_6_0_1 + 0.379687500000006*G0_0_0_7_0_0 + 0.126562499999999*G0_0_0_7_0_1 - 0.271205357142861*G0_0_0_8_0_0 + 0.0723214285714366*G0_0_0_9_0_0 - 0.253125*G0_0_0_9_0_1 - 0.108482142857144*G0_0_0_10_1_0 - 0.108482142857144*G0_0_0_10_1_1 - 0.307366071428577*G0_0_0_12_1_1 + 0.27120535714286*G0_0_0_13_1_0 - 0.452008928571436*G0_0_0_14_1_0 + 0.126562500000001*G0_0_0_14_1_1 - 0.343526785714296*G0_0_0_15_1_0 - 0.0904017857142901*G0_0_0_15_1_1 + 0.452008928571436*G0_0_0_16_1_0 + 0.506250000000012*G0_0_0_16_1_1 + 0.379687500000006*G0_0_0_17_1_0 + 0.126562499999999*G0_0_0_17_1_1 - 0.271205357142861*G0_0_0_18_1_0 + 0.0723214285714366*G0_0_0_19_1_0 - 0.253125*G0_0_0_19_1_1 + 0.19888392857143*G0_0_1_0_0_0 + 0.19888392857143*G0_0_1_0_0_1 - 0.198883928571432*G0_0_1_2_0_1 - 0.198883928571429*G0_0_1_4_0_0 - 0.397767857142873*G0_0_1_5_0_0 - 0.596651785714297*G0_0_1_5_0_1 + 0.198883928571429*G0_0_1_6_0_0 + 0.596651785714299*G0_0_1_6_0_1 - 0.198883928571429*G0_0_1_7_0_0 + 0.397767857142874*G0_0_1_9_0_0 + 0.19888392857143*G0_0_1_10_1_0 + 0.19888392857143*G0_0_1_10_1_1 - 0.198883928571432*G0_0_1_12_1_1 - 0.198883928571429*G0_0_1_14_1_0 - 0.397767857142873*G0_0_1_15_1_0 - 0.596651785714297*G0_0_1_15_1_1 + 0.198883928571429*G0_0_1_16_1_0 + 0.596651785714299*G0_0_1_16_1_1 - 0.198883928571429*G0_0_1_17_1_0 + 0.397767857142874*G0_0_1_19_1_0; + A[99] = 0.0; + A[118] = 0.0; + A[383] = 0.0; + A[282] = 0.0; + A[61] = A[271]; + A[136] = 0.0; + A[388] = 0.0; + A[348] = 0.0; + A[203] = 0.0; + A[285] = 0.0; + A[36] = 0.0; + A[300] = 0.0; + A[11] = 0.0; + A[30] = 0.0; + A[81] = -A[121] + 0.0529017857142857*G0_1_0_0_0_0 + 0.0529017857142856*G0_1_0_0_0_1 - 0.649553571428578*G0_1_0_1_0_0 - 0.33616071428572*G0_1_0_2_0_1 - 0.235044642857139*G0_1_0_3_0_0 - 1.3138392857143*G0_1_0_3_0_1 - 0.325446428571432*G0_1_0_4_0_0 + 0.439955357142868*G0_1_0_4_0_1 - 0.307366071428581*G0_1_0_5_0_0 - 0.156696428571434*G0_1_0_5_0_1 + 0.325446428571432*G0_1_0_6_0_0 + 0.439955357142869*G0_1_0_6_0_1 - 0.10848214285714*G0_1_0_7_0_0 - 0.259151785714287*G0_1_0_7_0_1 + 0.705133928571432*G0_1_0_8_0_0 + 1.3138392857143*G0_1_0_8_0_1 + 0.54241071428572*G0_1_0_9_0_0 - 0.180803571428582*G0_1_0_9_0_1 + 0.0529017857142857*G0_1_0_10_1_0 + 0.0529017857142856*G0_1_0_10_1_1 - 0.649553571428578*G0_1_0_11_1_0 - 0.33616071428572*G0_1_0_12_1_1 - 0.235044642857139*G0_1_0_13_1_0 - 1.3138392857143*G0_1_0_13_1_1 - 0.325446428571432*G0_1_0_14_1_0 + 0.439955357142868*G0_1_0_14_1_1 - 0.307366071428581*G0_1_0_15_1_0 - 0.156696428571434*G0_1_0_15_1_1 + 0.325446428571432*G0_1_0_16_1_0 + 0.439955357142869*G0_1_0_16_1_1 - 0.10848214285714*G0_1_0_17_1_0 - 0.259151785714287*G0_1_0_17_1_1 + 0.705133928571432*G0_1_0_18_1_0 + 1.3138392857143*G0_1_0_18_1_1 + 0.54241071428572*G0_1_0_19_1_0 - 0.180803571428582*G0_1_0_19_1_1; + A[324] = 0.0; + A[131] = 0.0; + A[341] = 0.0; + A[158] = 0.0; + A[366] = 0.0; + A[193] = 0.0; + A[223] = 0.0; + A[292] = -0.266517857142862*G0_0_1_0_0_0 - 0.266517857142862*G0_0_1_0_0_1 + 0.266517857142861*G0_0_1_1_0_0 + 2.02633928571431*G0_0_1_2_0_1 - 1.3138392857143*G0_0_1_3_0_0 - 0.16875*G0_0_1_3_0_1 + 3.96562500000004*G0_0_1_4_0_0 + 1.06071428571429*G0_0_1_4_0_1 + 1.3138392857143*G0_0_1_5_0_0 + 1.1450892857143*G0_0_1_5_0_1 - 3.96562500000004*G0_0_1_6_0_0 - 2.90491071428575*G0_0_1_6_0_1 + 0.168750000000004*G0_0_1_7_0_1 + 0.16875*G0_0_1_8_0_1 - 1.2294642857143*G0_0_1_9_0_1 - 0.266517857142862*G0_0_1_10_1_0 - 0.266517857142862*G0_0_1_10_1_1 + 0.266517857142861*G0_0_1_11_1_0 + 2.02633928571431*G0_0_1_12_1_1 - 1.3138392857143*G0_0_1_13_1_0 - 0.16875*G0_0_1_13_1_1 + 3.96562500000004*G0_0_1_14_1_0 + 1.06071428571429*G0_0_1_14_1_1 + 1.3138392857143*G0_0_1_15_1_0 + 1.1450892857143*G0_0_1_15_1_1 - 3.96562500000004*G0_0_1_16_1_0 - 2.90491071428575*G0_0_1_16_1_1 + 0.168750000000004*G0_0_1_17_1_1 + 0.16875*G0_0_1_18_1_1 - 1.2294642857143*G0_0_1_19_1_1 - 0.0796875000000013*G0_1_1_0_0_0 - 0.0796875000000013*G0_1_1_0_0_1 - 0.14933035714286*G0_1_1_1_0_0 + 0.459375000000002*G0_1_1_2_0_1 - 0.34955357142857*G0_1_1_3_0_0 - 0.50022321428572*G0_1_1_3_0_1 + 1.06071428571429*G0_1_1_4_0_0 + 0.602678571428582*G0_1_1_4_0_1 + 0.494196428571435*G0_1_1_5_0_0 + 0.379687500000004*G0_1_1_5_0_1 - 1.06071428571429*G0_1_1_6_0_0 - 0.759375000000006*G0_1_1_6_0_1 + 0.114508928571433*G0_1_1_7_0_0 + 0.229017857142863*G0_1_1_7_0_1 + 0.114508928571428*G0_1_1_8_0_0 + 0.50022321428572*G0_1_1_8_0_1 - 0.144642857142864*G0_1_1_9_0_0 - 0.831696428571445*G0_1_1_9_0_1 - 0.0796875000000013*G0_1_1_10_1_0 - 0.0796875000000013*G0_1_1_10_1_1 - 0.14933035714286*G0_1_1_11_1_0 + 0.459375000000002*G0_1_1_12_1_1 - 0.34955357142857*G0_1_1_13_1_0 - 0.50022321428572*G0_1_1_13_1_1 + 1.06071428571429*G0_1_1_14_1_0 + 0.602678571428582*G0_1_1_14_1_1 + 0.494196428571435*G0_1_1_15_1_0 + 0.379687500000004*G0_1_1_15_1_1 - 1.06071428571429*G0_1_1_16_1_0 - 0.759375000000006*G0_1_1_16_1_1 + 0.114508928571433*G0_1_1_17_1_0 + 0.229017857142863*G0_1_1_17_1_1 + 0.114508928571428*G0_1_1_18_1_0 + 0.50022321428572*G0_1_1_18_1_1 - 0.144642857142864*G0_1_1_19_1_0 - 0.831696428571445*G0_1_1_19_1_1; + A[244] = 0.0; + A[309] = 0.0; + A[269] = 0.0; + A[75] = 0.0; + A[23] = A[271] - 0.266517857142861*G0_0_1_0_0_0 - 0.26651785714286*G0_0_1_0_0_1 + 2.0263392857143*G0_0_1_1_0_0 + 0.26651785714286*G0_0_1_2_0_1 + 1.06071428571429*G0_0_1_3_0_0 + 3.96562500000003*G0_0_1_3_0_1 - 0.168750000000001*G0_0_1_4_0_0 - 1.3138392857143*G0_0_1_4_0_1 + 0.168750000000001*G0_0_1_5_0_0 + 0.168750000000001*G0_0_1_6_0_0 + 1.1450892857143*G0_0_1_7_0_0 + 1.3138392857143*G0_0_1_7_0_1 - 2.90491071428574*G0_0_1_8_0_0 - 3.96562500000003*G0_0_1_8_0_1 - 1.22946428571429*G0_0_1_9_0_0 - 0.266517857142861*G0_0_1_10_1_0 - 0.26651785714286*G0_0_1_10_1_1 + 2.0263392857143*G0_0_1_11_1_0 + 0.26651785714286*G0_0_1_12_1_1 + 1.06071428571429*G0_0_1_13_1_0 + 3.96562500000003*G0_0_1_13_1_1 - 0.168750000000001*G0_0_1_14_1_0 - 1.3138392857143*G0_0_1_14_1_1 + 0.168750000000001*G0_0_1_15_1_0 + 0.168750000000001*G0_0_1_16_1_0 + 1.1450892857143*G0_0_1_17_1_0 + 1.3138392857143*G0_0_1_17_1_1 - 2.90491071428574*G0_0_1_18_1_0 - 3.96562500000003*G0_0_1_18_1_1 - 1.22946428571429*G0_0_1_19_1_0 + 0.266517857142861*G0_1_0_0_0_0 + 0.26651785714286*G0_1_0_0_0_1 - 2.0263392857143*G0_1_0_1_0_0 - 0.26651785714286*G0_1_0_2_0_1 - 1.06071428571429*G0_1_0_3_0_0 - 3.96562500000003*G0_1_0_3_0_1 + 0.168750000000001*G0_1_0_4_0_0 + 1.3138392857143*G0_1_0_4_0_1 - 0.168750000000001*G0_1_0_5_0_0 - 0.168750000000001*G0_1_0_6_0_0 - 1.1450892857143*G0_1_0_7_0_0 - 1.3138392857143*G0_1_0_7_0_1 + 2.90491071428574*G0_1_0_8_0_0 + 3.96562500000003*G0_1_0_8_0_1 + 1.22946428571429*G0_1_0_9_0_0 + 0.266517857142861*G0_1_0_10_1_0 + 0.26651785714286*G0_1_0_10_1_1 - 2.0263392857143*G0_1_0_11_1_0 - 0.26651785714286*G0_1_0_12_1_1 - 1.06071428571429*G0_1_0_13_1_0 - 3.96562500000003*G0_1_0_13_1_1 + 0.168750000000001*G0_1_0_14_1_0 + 1.3138392857143*G0_1_0_14_1_1 - 0.168750000000001*G0_1_0_15_1_0 - 0.168750000000001*G0_1_0_16_1_0 - 1.1450892857143*G0_1_0_17_1_0 - 1.3138392857143*G0_1_0_17_1_1 + 2.90491071428574*G0_1_0_18_1_0 + 3.96562500000003*G0_1_0_18_1_1 + 1.22946428571429*G0_1_0_19_1_0; + A[48] = A[257] + 0.19888392857143*G0_1_0_0_0_0 + 0.19888392857143*G0_1_0_0_0_1 - 0.198883928571429*G0_1_0_1_0_0 - 0.198883928571424*G0_1_0_3_0_1 - 0.198883928571429*G0_1_0_5_0_1 - 0.596651785714296*G0_1_0_7_0_0 - 0.397767857142872*G0_1_0_7_0_1 + 0.596651785714295*G0_1_0_8_0_0 + 0.198883928571424*G0_1_0_8_0_1 + 0.397767857142876*G0_1_0_9_0_1 + 0.19888392857143*G0_1_0_10_1_0 + 0.19888392857143*G0_1_0_10_1_1 - 0.198883928571429*G0_1_0_11_1_0 - 0.198883928571424*G0_1_0_13_1_1 - 0.198883928571429*G0_1_0_15_1_1 - 0.596651785714296*G0_1_0_17_1_0 - 0.397767857142872*G0_1_0_17_1_1 + 0.596651785714295*G0_1_0_18_1_0 + 0.198883928571424*G0_1_0_18_1_1 + 0.397767857142876*G0_1_0_19_1_1 - 0.108482142857144*G0_1_1_0_0_0 - 0.108482142857145*G0_1_1_0_0_1 - 0.307366071428574*G0_1_1_1_0_0 + 0.126562500000004*G0_1_1_3_0_0 - 0.45200892857143*G0_1_1_3_0_1 + 0.271205357142857*G0_1_1_4_0_1 + 0.126562499999999*G0_1_1_5_0_0 + 0.379687500000005*G0_1_1_5_0_1 - 0.271205357142859*G0_1_1_6_0_1 - 0.0904017857142885*G0_1_1_7_0_0 - 0.343526785714294*G0_1_1_7_0_1 + 0.506250000000007*G0_1_1_8_0_0 + 0.45200892857143*G0_1_1_8_0_1 - 0.253125000000003*G0_1_1_9_0_0 + 0.072321428571437*G0_1_1_9_0_1 - 0.108482142857144*G0_1_1_10_1_0 - 0.108482142857145*G0_1_1_10_1_1 - 0.307366071428574*G0_1_1_11_1_0 + 0.126562500000004*G0_1_1_13_1_0 - 0.45200892857143*G0_1_1_13_1_1 + 0.271205357142857*G0_1_1_14_1_1 + 0.126562499999999*G0_1_1_15_1_0 + 0.379687500000005*G0_1_1_15_1_1 - 0.271205357142859*G0_1_1_16_1_1 - 0.0904017857142885*G0_1_1_17_1_0 - 0.343526785714294*G0_1_1_17_1_1 + 0.506250000000007*G0_1_1_18_1_0 + 0.45200892857143*G0_1_1_18_1_1 - 0.253125000000003*G0_1_1_19_1_0 + 0.072321428571437*G0_1_1_19_1_1; + A[162] = A[48] + 0.0120535714285707*G0_0_1_0_0_0 + 0.0120535714285707*G0_0_1_0_0_1 - 0.186830357142859*G0_0_1_1_0_0 + 0.0542410714285757*G0_0_1_3_0_0 - 0.247098214285714*G0_0_1_3_0_1 + 0.114508928571428*G0_0_1_4_0_1 + 0.0542410714285702*G0_0_1_5_0_0 + 0.10245535714286*G0_0_1_5_0_1 - 0.11450892857143*G0_0_1_6_0_1 - 0.210937500000004*G0_0_1_7_0_0 - 0.259151785714293*G0_0_1_7_0_1 + 0.385714285714292*G0_0_1_8_0_0 + 0.247098214285714*G0_0_1_8_0_1 - 0.108482142857146*G0_0_1_9_0_0 + 0.144642857142865*G0_0_1_9_0_1 + 0.0120535714285707*G0_0_1_10_1_0 + 0.0120535714285707*G0_0_1_10_1_1 - 0.186830357142859*G0_0_1_11_1_0 + 0.0542410714285757*G0_0_1_13_1_0 - 0.247098214285714*G0_0_1_13_1_1 + 0.114508928571428*G0_0_1_14_1_1 + 0.0542410714285702*G0_0_1_15_1_0 + 0.10245535714286*G0_0_1_15_1_1 - 0.11450892857143*G0_0_1_16_1_1 - 0.210937500000004*G0_0_1_17_1_0 - 0.259151785714293*G0_0_1_17_1_1 + 0.385714285714292*G0_0_1_18_1_0 + 0.247098214285714*G0_0_1_18_1_1 - 0.108482142857146*G0_0_1_19_1_0 + 0.144642857142865*G0_0_1_19_1_1 - 0.0120535714285708*G0_1_0_0_0_0 - 0.0120535714285707*G0_1_0_0_0_1 + 0.186830357142859*G0_1_0_1_0_0 - 0.0542410714285756*G0_1_0_3_0_0 + 0.247098214285714*G0_1_0_3_0_1 - 0.114508928571428*G0_1_0_4_0_1 - 0.0542410714285702*G0_1_0_5_0_0 - 0.10245535714286*G0_1_0_5_0_1 + 0.11450892857143*G0_1_0_6_0_1 + 0.210937500000004*G0_1_0_7_0_0 + 0.259151785714294*G0_1_0_7_0_1 - 0.385714285714292*G0_1_0_8_0_0 - 0.247098214285714*G0_1_0_8_0_1 + 0.108482142857146*G0_1_0_9_0_0 - 0.144642857142865*G0_1_0_9_0_1 - 0.0120535714285708*G0_1_0_10_1_0 - 0.0120535714285707*G0_1_0_10_1_1 + 0.186830357142859*G0_1_0_11_1_0 - 0.0542410714285756*G0_1_0_13_1_0 + 0.247098214285714*G0_1_0_13_1_1 - 0.114508928571428*G0_1_0_14_1_1 - 0.0542410714285702*G0_1_0_15_1_0 - 0.10245535714286*G0_1_0_15_1_1 + 0.11450892857143*G0_1_0_16_1_1 + 0.210937500000004*G0_1_0_17_1_0 + 0.259151785714294*G0_1_0_17_1_1 - 0.385714285714292*G0_1_0_18_1_0 - 0.247098214285714*G0_1_0_18_1_1 + 0.108482142857146*G0_1_0_19_1_0 - 0.144642857142865*G0_1_0_19_1_1; + A[62] = -A[162] + 0.0529017857142858*G0_0_1_0_0_0 + 0.0529017857142857*G0_0_1_0_0_1 - 0.33616071428572*G0_0_1_1_0_0 - 0.649553571428581*G0_0_1_2_0_1 + 0.439955357142872*G0_0_1_3_0_0 - 0.325446428571429*G0_0_1_3_0_1 - 1.3138392857143*G0_0_1_4_0_0 - 0.235044642857143*G0_0_1_4_0_1 - 0.25915178571429*G0_0_1_5_0_0 - 0.108482142857143*G0_0_1_5_0_1 + 1.3138392857143*G0_0_1_6_0_0 + 0.705133928571438*G0_0_1_6_0_1 - 0.156696428571433*G0_0_1_7_0_0 - 0.307366071428582*G0_0_1_7_0_1 + 0.439955357142867*G0_0_1_8_0_0 + 0.32544642857143*G0_0_1_8_0_1 - 0.180803571428581*G0_0_1_9_0_0 + 0.542410714285724*G0_0_1_9_0_1 + 0.0529017857142858*G0_0_1_10_1_0 + 0.0529017857142857*G0_0_1_10_1_1 - 0.33616071428572*G0_0_1_11_1_0 - 0.649553571428581*G0_0_1_12_1_1 + 0.439955357142872*G0_0_1_13_1_0 - 0.325446428571429*G0_0_1_13_1_1 - 1.3138392857143*G0_0_1_14_1_0 - 0.235044642857143*G0_0_1_14_1_1 - 0.25915178571429*G0_0_1_15_1_0 - 0.108482142857143*G0_0_1_15_1_1 + 1.3138392857143*G0_0_1_16_1_0 + 0.705133928571438*G0_0_1_16_1_1 - 0.156696428571433*G0_0_1_17_1_0 - 0.307366071428582*G0_0_1_17_1_1 + 0.439955357142867*G0_0_1_18_1_0 + 0.32544642857143*G0_0_1_18_1_1 - 0.180803571428581*G0_0_1_19_1_0 + 0.542410714285724*G0_0_1_19_1_1; + A[370] = -A[162] - 0.675000000000007*G0_0_0_0_0_0 - 0.675000000000007*G0_0_0_0_0_1 + 0.41584821428572*G0_0_0_1_0_0 + 0.0120535714285707*G0_0_0_2_0_1 + 0.271205357142861*G0_0_0_3_0_0 + 0.572544642857151*G0_0_0_3_0_1 - 0.108482142857144*G0_0_0_4_0_0 - 0.0060267857142844*G0_0_0_4_0_1 - 0.379687500000003*G0_0_0_5_0_0 + 0.765401785714293*G0_0_0_5_0_1 + 0.108482142857144*G0_0_0_6_0_0 - 0.102455357142856*G0_0_0_6_0_1 + 1.29575892857145*G0_0_0_7_0_0 + 0.150669642857151*G0_0_0_7_0_1 - 1.03660714285716*G0_0_0_8_0_0 - 0.572544642857151*G0_0_0_8_0_1 + 0.108482142857142*G0_0_0_9_0_0 - 0.144642857142866*G0_0_0_9_0_1 - 0.675000000000007*G0_0_0_10_1_0 - 0.675000000000007*G0_0_0_10_1_1 + 0.41584821428572*G0_0_0_11_1_0 + 0.0120535714285707*G0_0_0_12_1_1 + 0.271205357142861*G0_0_0_13_1_0 + 0.572544642857151*G0_0_0_13_1_1 - 0.108482142857144*G0_0_0_14_1_0 - 0.0060267857142844*G0_0_0_14_1_1 - 0.379687500000003*G0_0_0_15_1_0 + 0.765401785714293*G0_0_0_15_1_1 + 0.108482142857144*G0_0_0_16_1_0 - 0.102455357142856*G0_0_0_16_1_1 + 1.29575892857145*G0_0_0_17_1_0 + 0.150669642857151*G0_0_0_17_1_1 - 1.03660714285716*G0_0_0_18_1_0 - 0.572544642857151*G0_0_0_18_1_1 + 0.108482142857142*G0_0_0_19_1_0 - 0.144642857142866*G0_0_0_19_1_1 - 0.662946428571437*G0_0_1_0_0_0 - 0.662946428571437*G0_0_1_0_0_1 + 0.229017857142861*G0_0_1_1_0_0 + 0.0120535714285699*G0_0_1_2_0_1 + 0.325446428571436*G0_0_1_3_0_0 + 0.325446428571437*G0_0_1_3_0_1 - 0.108482142857147*G0_0_1_4_0_0 + 0.108482142857144*G0_0_1_4_0_1 - 0.325446428571433*G0_0_1_5_0_0 + 0.867857142857153*G0_0_1_5_0_1 + 0.108482142857148*G0_0_1_6_0_0 - 0.216964285714286*G0_0_1_6_0_1 + 1.08482142857144*G0_0_1_7_0_0 - 0.108482142857143*G0_0_1_7_0_1 - 0.650892857142867*G0_0_1_8_0_0 - 0.325446428571437*G0_0_1_8_0_1 - 0.662946428571437*G0_0_1_10_1_0 - 0.662946428571437*G0_0_1_10_1_1 + 0.229017857142861*G0_0_1_11_1_0 + 0.0120535714285699*G0_0_1_12_1_1 + 0.325446428571436*G0_0_1_13_1_0 + 0.325446428571437*G0_0_1_13_1_1 - 0.108482142857147*G0_0_1_14_1_0 + 0.108482142857144*G0_0_1_14_1_1 - 0.325446428571433*G0_0_1_15_1_0 + 0.867857142857153*G0_0_1_15_1_1 + 0.108482142857148*G0_0_1_16_1_0 - 0.216964285714286*G0_0_1_16_1_1 + 1.08482142857144*G0_0_1_17_1_0 - 0.108482142857143*G0_0_1_17_1_1 - 0.650892857142867*G0_0_1_18_1_0 - 0.325446428571437*G0_0_1_18_1_1 - 0.0254464285714306*G0_1_0_0_0_0 - 0.0254464285714305*G0_1_0_0_0_1 + 0.266517857142861*G0_1_0_1_0_0 - 0.0287946428571436*G0_1_0_2_0_1 + 0.24709821428572*G0_1_0_3_0_0 + 0.494196428571436*G0_1_0_3_0_1 - 0.00602678571428589*G0_1_0_4_0_0 + 0.0421875000000032*G0_1_0_4_0_1 + 0.11450892857143*G0_1_0_5_0_0 - 0.0542410714285695*G0_1_0_5_0_1 + 0.00602678571428595*G0_1_0_6_0_0 + 0.108482142857144*G0_1_0_6_0_1 + 0.331473214285721*G0_1_0_7_0_0 + 0.500223214285721*G0_1_0_7_0_1 - 0.572544642857151*G0_1_0_8_0_0 - 0.494196428571436*G0_1_0_8_0_1 - 0.361607142857151*G0_1_0_9_0_0 - 0.542410714285724*G0_1_0_9_0_1 - 0.0254464285714306*G0_1_0_10_1_0 - 0.0254464285714305*G0_1_0_10_1_1 + 0.266517857142861*G0_1_0_11_1_0 - 0.0287946428571436*G0_1_0_12_1_1 + 0.24709821428572*G0_1_0_13_1_0 + 0.494196428571436*G0_1_0_13_1_1 - 0.00602678571428589*G0_1_0_14_1_0 + 0.0421875000000032*G0_1_0_14_1_1 + 0.11450892857143*G0_1_0_15_1_0 - 0.0542410714285695*G0_1_0_15_1_1 + 0.00602678571428595*G0_1_0_16_1_0 + 0.108482142857144*G0_1_0_16_1_1 + 0.331473214285721*G0_1_0_17_1_0 + 0.500223214285721*G0_1_0_17_1_1 - 0.572544642857151*G0_1_0_18_1_0 - 0.494196428571436*G0_1_0_18_1_1 - 0.361607142857151*G0_1_0_19_1_0 - 0.542410714285724*G0_1_0_19_1_1 - 0.0542410714285741*G0_1_1_0_0_0 - 0.054241071428574*G0_1_1_0_0_1 - 0.0542410714285741*G0_1_1_2_0_1 + 0.325446428571436*G0_1_1_3_0_0 + 0.162723214285714*G0_1_1_4_0_0 + 0.542410714285724*G0_1_1_4_0_1 + 0.216964285714288*G0_1_1_5_0_0 + 0.0542410714285743*G0_1_1_5_0_1 - 0.162723214285714*G0_1_1_6_0_0 + 0.0542410714285738*G0_1_1_6_0_1 + 0.379687500000011*G0_1_1_7_0_0 + 0.542410714285725*G0_1_1_7_0_1 - 0.325446428571437*G0_1_1_8_0_0 - 0.542410714285725*G0_1_1_9_0_0 - 1.08482142857145*G0_1_1_9_0_1 - 0.0542410714285741*G0_1_1_10_1_0 - 0.054241071428574*G0_1_1_10_1_1 - 0.0542410714285741*G0_1_1_12_1_1 + 0.325446428571436*G0_1_1_13_1_0 + 0.162723214285714*G0_1_1_14_1_0 + 0.542410714285724*G0_1_1_14_1_1 + 0.216964285714288*G0_1_1_15_1_0 + 0.0542410714285743*G0_1_1_15_1_1 - 0.162723214285714*G0_1_1_16_1_0 + 0.0542410714285738*G0_1_1_16_1_1 + 0.379687500000011*G0_1_1_17_1_0 + 0.542410714285725*G0_1_1_17_1_1 - 0.325446428571437*G0_1_1_18_1_0 - 0.542410714285725*G0_1_1_19_1_0 - 1.08482142857145*G0_1_1_19_1_1; + A[160] = A[370]; + A[253] = -A[48] + 0.0529017857142858*G0_1_0_0_0_0 + 0.0529017857142857*G0_1_0_0_0_1 - 0.33616071428572*G0_1_0_1_0_0 - 0.649553571428581*G0_1_0_2_0_1 + 0.439955357142871*G0_1_0_3_0_0 - 0.325446428571429*G0_1_0_3_0_1 - 1.3138392857143*G0_1_0_4_0_0 - 0.235044642857142*G0_1_0_4_0_1 - 0.25915178571429*G0_1_0_5_0_0 - 0.108482142857143*G0_1_0_5_0_1 + 1.3138392857143*G0_1_0_6_0_0 + 0.705133928571438*G0_1_0_6_0_1 - 0.156696428571433*G0_1_0_7_0_0 - 0.307366071428582*G0_1_0_7_0_1 + 0.439955357142867*G0_1_0_8_0_0 + 0.32544642857143*G0_1_0_8_0_1 - 0.180803571428581*G0_1_0_9_0_0 + 0.542410714285724*G0_1_0_9_0_1 + 0.0529017857142858*G0_1_0_10_1_0 + 0.0529017857142857*G0_1_0_10_1_1 - 0.33616071428572*G0_1_0_11_1_0 - 0.649553571428581*G0_1_0_12_1_1 + 0.439955357142871*G0_1_0_13_1_0 - 0.325446428571429*G0_1_0_13_1_1 - 1.3138392857143*G0_1_0_14_1_0 - 0.235044642857142*G0_1_0_14_1_1 - 0.25915178571429*G0_1_0_15_1_0 - 0.108482142857143*G0_1_0_15_1_1 + 1.3138392857143*G0_1_0_16_1_0 + 0.705133928571438*G0_1_0_16_1_1 - 0.156696428571433*G0_1_0_17_1_0 - 0.307366071428582*G0_1_0_17_1_1 + 0.439955357142867*G0_1_0_18_1_0 + 0.32544642857143*G0_1_0_18_1_1 - 0.180803571428581*G0_1_0_19_1_0 + 0.542410714285724*G0_1_0_19_1_1; + A[45] = A[253] - 0.190178571428576*G0_1_0_0_0_0 - 0.190178571428576*G0_1_0_0_0_1 + 0.190178571428576*G0_1_0_1_0_0 + 1.29910714285716*G0_1_0_2_0_1 - 0.699107142857156*G0_1_0_3_0_0 - 0.0241071428571423*G0_1_0_3_0_1 + 2.6276785714286*G0_1_0_4_0_0 + 0.843750000000005*G0_1_0_4_0_1 + 0.699107142857155*G0_1_0_5_0_0 + 0.675000000000013*G0_1_0_5_0_1 - 2.6276785714286*G0_1_0_6_0_0 - 1.7839285714286*G0_1_0_6_0_1 + 0.0241071428571475*G0_1_0_7_0_1 + 0.0241071428571424*G0_1_0_8_0_1 - 0.867857142857152*G0_1_0_9_0_1 - 0.190178571428576*G0_1_0_10_1_0 - 0.190178571428576*G0_1_0_10_1_1 + 0.190178571428576*G0_1_0_11_1_0 + 1.29910714285716*G0_1_0_12_1_1 - 0.699107142857156*G0_1_0_13_1_0 - 0.0241071428571423*G0_1_0_13_1_1 + 2.6276785714286*G0_1_0_14_1_0 + 0.843750000000005*G0_1_0_14_1_1 + 0.699107142857155*G0_1_0_15_1_0 + 0.675000000000013*G0_1_0_15_1_1 - 2.6276785714286*G0_1_0_16_1_0 - 1.7839285714286*G0_1_0_16_1_1 + 0.0241071428571475*G0_1_0_17_1_1 + 0.0241071428571424*G0_1_0_18_1_1 - 0.867857142857152*G0_1_0_19_1_1 - 0.444642857142864*G0_1_1_0_0_0 - 0.444642857142864*G0_1_1_0_0_1 - 0.254464285714288*G0_1_1_1_0_0 + 0.64955357142858*G0_1_1_2_0_1 - 0.132589285714287*G0_1_1_3_0_0 - 0.602678571428578*G0_1_1_3_0_1 + 1.3138392857143*G0_1_1_4_0_0 + 0.879910714285725*G0_1_1_4_0_1 + 0.566517857142869*G0_1_1_5_0_0 + 1.1450892857143*G0_1_1_5_0_1 - 1.3138392857143*G0_1_1_6_0_0 - 1.35000000000002*G0_1_1_6_0_1 + 0.349553571428579*G0_1_1_7_0_0 - 0.229017857142857*G0_1_1_7_0_1 + 0.349553571428573*G0_1_1_8_0_0 + 0.602678571428578*G0_1_1_8_0_1 - 0.433928571428582*G0_1_1_9_0_0 - 0.650892857142868*G0_1_1_9_0_1 - 0.444642857142864*G0_1_1_10_1_0 - 0.444642857142864*G0_1_1_10_1_1 - 0.254464285714288*G0_1_1_11_1_0 + 0.64955357142858*G0_1_1_12_1_1 - 0.132589285714287*G0_1_1_13_1_0 - 0.602678571428578*G0_1_1_13_1_1 + 1.3138392857143*G0_1_1_14_1_0 + 0.879910714285725*G0_1_1_14_1_1 + 0.566517857142869*G0_1_1_15_1_0 + 1.1450892857143*G0_1_1_15_1_1 - 1.3138392857143*G0_1_1_16_1_0 - 1.35000000000002*G0_1_1_16_1_1 + 0.349553571428579*G0_1_1_17_1_0 - 0.229017857142857*G0_1_1_17_1_1 + 0.349553571428573*G0_1_1_18_1_0 + 0.602678571428578*G0_1_1_18_1_1 - 0.433928571428582*G0_1_1_19_1_0 - 0.650892857142868*G0_1_1_19_1_1; + A[113] = 0.0; + A[122] = -A[292] + 0.33616071428572*G0_1_1_0_0_0 + 0.33616071428572*G0_1_1_0_0_1 - 0.33616071428572*G0_1_1_1_0_0 - 1.1075892857143*G0_1_1_2_0_1 + 0.470089285714298*G0_1_1_3_0_0 - 0.44598214285715*G0_1_1_3_0_1 - 1.84419642857145*G0_1_1_4_0_0 - 0.156696428571423*G0_1_1_4_0_1 - 0.470089285714296*G0_1_1_5_0_0 - 0.916071428571446*G0_1_1_5_0_1 + 1.84419642857145*G0_1_1_6_0_0 + 1.68750000000003*G0_1_1_6_0_1 + 0.445982142857153*G0_1_1_7_0_1 + 0.445982142857151*G0_1_1_8_0_1 - 0.289285714285729*G0_1_1_9_0_1 + 0.33616071428572*G0_1_1_10_1_0 + 0.33616071428572*G0_1_1_10_1_1 - 0.33616071428572*G0_1_1_11_1_0 - 1.1075892857143*G0_1_1_12_1_1 + 0.470089285714298*G0_1_1_13_1_0 - 0.44598214285715*G0_1_1_13_1_1 - 1.84419642857145*G0_1_1_14_1_0 - 0.156696428571423*G0_1_1_14_1_1 - 0.470089285714296*G0_1_1_15_1_0 - 0.916071428571446*G0_1_1_15_1_1 + 1.84419642857145*G0_1_1_16_1_0 + 1.68750000000003*G0_1_1_16_1_1 + 0.445982142857153*G0_1_1_17_1_1 + 0.445982142857151*G0_1_1_18_1_1 - 0.289285714285729*G0_1_1_19_1_1; + A[151] = 0.0; + A[361] = 0.0; + A[243] = 0.0; + A[262] = 0.0; + A[24] = -A[26] + 0.0529017857142857*G0_0_1_0_0_0 + 0.0529017857142856*G0_0_1_0_0_1 - 0.649553571428578*G0_0_1_1_0_0 - 0.33616071428572*G0_0_1_2_0_1 - 0.235044642857139*G0_0_1_3_0_0 - 1.3138392857143*G0_0_1_3_0_1 - 0.325446428571432*G0_0_1_4_0_0 + 0.439955357142868*G0_0_1_4_0_1 - 0.307366071428581*G0_0_1_5_0_0 - 0.156696428571434*G0_0_1_5_0_1 + 0.325446428571432*G0_0_1_6_0_0 + 0.439955357142869*G0_0_1_6_0_1 - 0.10848214285714*G0_0_1_7_0_0 - 0.259151785714287*G0_0_1_7_0_1 + 0.705133928571432*G0_0_1_8_0_0 + 1.3138392857143*G0_0_1_8_0_1 + 0.54241071428572*G0_0_1_9_0_0 - 0.180803571428582*G0_0_1_9_0_1 + 0.0529017857142857*G0_0_1_10_1_0 + 0.0529017857142856*G0_0_1_10_1_1 - 0.649553571428578*G0_0_1_11_1_0 - 0.33616071428572*G0_0_1_12_1_1 - 0.235044642857139*G0_0_1_13_1_0 - 1.3138392857143*G0_0_1_13_1_1 - 0.325446428571432*G0_0_1_14_1_0 + 0.439955357142868*G0_0_1_14_1_1 - 0.307366071428581*G0_0_1_15_1_0 - 0.156696428571434*G0_0_1_15_1_1 + 0.325446428571432*G0_0_1_16_1_0 + 0.439955357142869*G0_0_1_16_1_1 - 0.10848214285714*G0_0_1_17_1_0 - 0.259151785714287*G0_0_1_17_1_1 + 0.705133928571432*G0_0_1_18_1_0 + 1.3138392857143*G0_0_1_18_1_1 + 0.54241071428572*G0_0_1_19_1_0 - 0.180803571428582*G0_0_1_19_1_1; + A[43] = A[253]; + A[116] = 0.0; + A[328] = 0.0; + A[385] = 0.0; + A[181] = A[239] - 0.108482142857145*G0_0_1_0_0_0 - 0.108482142857145*G0_0_1_0_0_1 - 0.108482142857145*G0_0_1_2_0_1 + 0.144642857142863*G0_0_1_3_0_0 - 0.180803571428572*G0_0_1_4_0_0 + 0.0723214285714366*G0_0_1_4_0_1 - 0.0723214285714281*G0_0_1_5_0_0 + 0.108482142857146*G0_0_1_5_0_1 + 0.180803571428572*G0_0_1_6_0_0 + 0.108482142857145*G0_0_1_6_0_1 + 0.253125000000008*G0_0_1_7_0_0 + 0.0723214285714341*G0_0_1_7_0_1 - 0.144642857142861*G0_0_1_8_0_0 - 0.072321428571435*G0_0_1_9_0_0 - 0.144642857142871*G0_0_1_9_0_1 - 0.108482142857145*G0_0_1_10_1_0 - 0.108482142857145*G0_0_1_10_1_1 - 0.108482142857145*G0_0_1_12_1_1 + 0.144642857142863*G0_0_1_13_1_0 - 0.180803571428572*G0_0_1_14_1_0 + 0.0723214285714366*G0_0_1_14_1_1 - 0.0723214285714281*G0_0_1_15_1_0 + 0.108482142857146*G0_0_1_15_1_1 + 0.180803571428572*G0_0_1_16_1_0 + 0.108482142857145*G0_0_1_16_1_1 + 0.253125000000008*G0_0_1_17_1_0 + 0.0723214285714341*G0_0_1_17_1_1 - 0.144642857142861*G0_0_1_18_1_0 - 0.072321428571435*G0_0_1_19_1_0 - 0.144642857142871*G0_0_1_19_1_1 + 0.108482142857145*G0_1_0_0_0_0 + 0.108482142857145*G0_1_0_0_0_1 + 0.108482142857145*G0_1_0_2_0_1 - 0.144642857142863*G0_1_0_3_0_0 + 0.180803571428572*G0_1_0_4_0_0 - 0.0723214285714365*G0_1_0_4_0_1 + 0.0723214285714282*G0_1_0_5_0_0 - 0.108482142857146*G0_1_0_5_0_1 - 0.180803571428572*G0_1_0_6_0_0 - 0.108482142857145*G0_1_0_6_0_1 - 0.253125000000008*G0_1_0_7_0_0 - 0.0723214285714339*G0_1_0_7_0_1 + 0.144642857142861*G0_1_0_8_0_0 + 0.0723214285714349*G0_1_0_9_0_0 + 0.144642857142871*G0_1_0_9_0_1 + 0.108482142857145*G0_1_0_10_1_0 + 0.108482142857145*G0_1_0_10_1_1 + 0.108482142857145*G0_1_0_12_1_1 - 0.144642857142863*G0_1_0_13_1_0 + 0.180803571428572*G0_1_0_14_1_0 - 0.0723214285714365*G0_1_0_14_1_1 + 0.0723214285714282*G0_1_0_15_1_0 - 0.108482142857146*G0_1_0_15_1_1 - 0.180803571428572*G0_1_0_16_1_0 - 0.108482142857145*G0_1_0_16_1_1 - 0.253125000000008*G0_1_0_17_1_0 - 0.0723214285714339*G0_1_0_17_1_1 + 0.144642857142861*G0_1_0_18_1_0 + 0.0723214285714349*G0_1_0_19_1_0 + 0.144642857142871*G0_1_0_19_1_1; + A[379] = -A[181] + 0.108482142857142*G0_0_0_0_0_0 + 0.108482142857142*G0_0_0_0_0_1 + 0.108482142857142*G0_0_0_1_0_0 + 1.22946428571432*G0_0_0_3_0_0 + 0.831696428571444*G0_0_0_3_0_1 + 0.506250000000022*G0_0_0_4_0_1 + 1.22946428571432*G0_0_0_5_0_0 + 0.397767857142877*G0_0_0_5_0_1 - 0.506250000000019*G0_0_0_6_0_1 - 0.108482142857143*G0_0_0_7_0_0 + 0.723214285714302*G0_0_0_7_0_1 - 0.108482142857141*G0_0_0_8_0_0 - 0.831696428571445*G0_0_0_8_0_1 - 2.45892857142865*G0_0_0_9_0_0 - 1.22946428571432*G0_0_0_9_0_1 + 0.108482142857142*G0_0_0_10_1_0 + 0.108482142857142*G0_0_0_10_1_1 + 0.108482142857142*G0_0_0_11_1_0 + 1.22946428571432*G0_0_0_13_1_0 + 0.831696428571444*G0_0_0_13_1_1 + 0.506250000000022*G0_0_0_14_1_1 + 1.22946428571432*G0_0_0_15_1_0 + 0.397767857142877*G0_0_0_15_1_1 - 0.506250000000019*G0_0_0_16_1_1 - 0.108482142857143*G0_0_0_17_1_0 + 0.723214285714302*G0_0_0_17_1_1 - 0.108482142857141*G0_0_0_18_1_0 - 0.831696428571445*G0_0_0_18_1_1 - 2.45892857142865*G0_0_0_19_1_0 - 1.22946428571432*G0_0_0_19_1_1 - 0.144642857142866*G0_0_1_0_0_0 - 0.144642857142866*G0_0_1_0_0_1 + 0.144642857142861*G0_0_1_1_0_0 + 0.144642857142866*G0_0_1_2_0_1 + 1.51875000000003*G0_0_1_3_0_0 + 1.51875000000003*G0_0_1_3_0_1 - 0.433928571428568*G0_0_1_4_0_0 - 0.43392857142857*G0_0_1_4_0_1 - 0.216964285714275*G0_0_1_5_0_0 + 0.650892857142885*G0_0_1_5_0_1 + 0.433928571428569*G0_0_1_6_0_0 - 0.650892857142885*G0_0_1_6_0_1 - 1.30178571428573*G0_0_1_7_0_0 - 2.16964285714289*G0_0_1_7_0_1 + 1.30178571428573*G0_0_1_8_0_0 - 1.51875000000003*G0_0_1_8_0_1 - 1.30178571428576*G0_0_1_9_0_0 + 2.60357142857146*G0_0_1_9_0_1 - 0.144642857142866*G0_0_1_10_1_0 - 0.144642857142866*G0_0_1_10_1_1 + 0.144642857142861*G0_0_1_11_1_0 + 0.144642857142866*G0_0_1_12_1_1 + 1.51875000000003*G0_0_1_13_1_0 + 1.51875000000003*G0_0_1_13_1_1 - 0.433928571428568*G0_0_1_14_1_0 - 0.43392857142857*G0_0_1_14_1_1 - 0.216964285714275*G0_0_1_15_1_0 + 0.650892857142885*G0_0_1_15_1_1 + 0.433928571428569*G0_0_1_16_1_0 - 0.650892857142885*G0_0_1_16_1_1 - 1.30178571428573*G0_0_1_17_1_0 - 2.16964285714289*G0_0_1_17_1_1 + 1.30178571428573*G0_0_1_18_1_0 - 1.51875000000003*G0_0_1_18_1_1 - 1.30178571428576*G0_0_1_19_1_0 + 2.60357142857146*G0_0_1_19_1_1 - 0.253125000000005*G0_1_0_0_0_0 - 0.253125000000005*G0_1_0_0_0_1 + 1.22946428571429*G0_1_0_1_0_0 - 0.0723214285714289*G0_1_0_2_0_1 + 2.35044642857145*G0_1_0_3_0_0 + 3.03750000000002*G0_1_0_3_0_1 + 0.0723214285714316*G0_1_0_4_0_0 + 0.687053571428583*G0_1_0_4_0_1 + 0.18080357142858*G0_1_0_5_0_0 - 0.0723214285714309*G0_1_0_6_0_0 + 0.325446428571426*G0_1_0_6_0_1 + 0.940178571428588*G0_1_0_7_0_0 + 1.12098214285716*G0_1_0_7_0_1 - 1.91651785714288*G0_1_0_8_0_0 - 3.03750000000002*G0_1_0_8_0_1 - 2.53125000000003*G0_1_0_9_0_0 - 1.80803571428574*G0_1_0_9_0_1 - 0.253125000000005*G0_1_0_10_1_0 - 0.253125000000005*G0_1_0_10_1_1 + 1.22946428571429*G0_1_0_11_1_0 - 0.0723214285714289*G0_1_0_12_1_1 + 2.35044642857145*G0_1_0_13_1_0 + 3.03750000000002*G0_1_0_13_1_1 + 0.0723214285714316*G0_1_0_14_1_0 + 0.687053571428583*G0_1_0_14_1_1 + 0.18080357142858*G0_1_0_15_1_0 - 0.0723214285714309*G0_1_0_16_1_0 + 0.325446428571426*G0_1_0_16_1_1 + 0.940178571428588*G0_1_0_17_1_0 + 1.12098214285716*G0_1_0_17_1_1 - 1.91651785714288*G0_1_0_18_1_0 - 3.03750000000002*G0_1_0_18_1_1 - 2.53125000000003*G0_1_0_19_1_0 - 1.80803571428574*G0_1_0_19_1_1 - 0.542410714285724*G0_1_1_0_0_0 - 0.542410714285724*G0_1_1_0_0_1 - 0.542410714285724*G0_1_1_2_0_1 + 1.51875000000003*G0_1_1_3_0_0 - 0.108482142857139*G0_1_1_4_0_0 + 1.95267857142862*G0_1_1_4_0_1 + 0.433928571428583*G0_1_1_5_0_0 + 0.542410714285724*G0_1_1_5_0_1 + 0.10848214285714*G0_1_1_6_0_0 + 0.542410714285724*G0_1_1_6_0_1 + 2.06116071428576*G0_1_1_7_0_0 + 1.95267857142862*G0_1_1_7_0_1 - 1.51875000000003*G0_1_1_8_0_0 - 1.95267857142861*G0_1_1_9_0_0 - 3.90535714285723*G0_1_1_9_0_1 - 0.542410714285724*G0_1_1_10_1_0 - 0.542410714285724*G0_1_1_10_1_1 - 0.542410714285724*G0_1_1_12_1_1 + 1.51875000000003*G0_1_1_13_1_0 - 0.108482142857139*G0_1_1_14_1_0 + 1.95267857142862*G0_1_1_14_1_1 + 0.433928571428583*G0_1_1_15_1_0 + 0.542410714285724*G0_1_1_15_1_1 + 0.10848214285714*G0_1_1_16_1_0 + 0.542410714285724*G0_1_1_16_1_1 + 2.06116071428576*G0_1_1_17_1_0 + 1.95267857142862*G0_1_1_17_1_1 - 1.51875000000003*G0_1_1_18_1_0 - 1.95267857142861*G0_1_1_19_1_0 - 3.90535714285723*G0_1_1_19_1_1; + A[186] = A[379] - 0.650892857142867*G0_0_0_0_0_0 - 0.650892857142867*G0_0_0_0_0_1 - 1.08482142857144*G0_0_0_1_0_0 + 0.108482142857147*G0_0_0_2_0_1 - 0.108482142857154*G0_0_0_3_0_0 - 2.16964285714288*G0_0_0_3_0_1 + 0.542410714285724*G0_0_0_4_0_0 + 1.41026785714287*G0_0_0_4_0_1 + 0.108482142857131*G0_0_0_5_0_0 + 1.41026785714287*G0_0_0_5_0_1 - 0.542410714285724*G0_0_0_6_0_0 - 0.867857142857149*G0_0_0_6_0_1 + 0.542410714285726*G0_0_0_7_0_0 - 0.759375000000013*G0_0_0_7_0_1 + 1.19330357142858*G0_0_0_8_0_0 + 2.16964285714288*G0_0_0_8_0_1 - 0.650892857142854*G0_0_0_9_0_1 - 0.650892857142867*G0_0_0_10_1_0 - 0.650892857142867*G0_0_0_10_1_1 - 1.08482142857144*G0_0_0_11_1_0 + 0.108482142857147*G0_0_0_12_1_1 - 0.108482142857154*G0_0_0_13_1_0 - 2.16964285714288*G0_0_0_13_1_1 + 0.542410714285724*G0_0_0_14_1_0 + 1.41026785714287*G0_0_0_14_1_1 + 0.108482142857131*G0_0_0_15_1_0 + 1.41026785714287*G0_0_0_15_1_1 - 0.542410714285724*G0_0_0_16_1_0 - 0.867857142857149*G0_0_0_16_1_1 + 0.542410714285726*G0_0_0_17_1_0 - 0.759375000000013*G0_0_0_17_1_1 + 1.19330357142858*G0_0_0_18_1_0 + 2.16964285714288*G0_0_0_18_1_1 - 0.650892857142854*G0_0_0_19_1_1 - 1.95267857142861*G0_0_1_3_0_0 - 1.9526785714286*G0_0_1_3_0_1 + 1.9526785714286*G0_0_1_4_0_0 + 1.9526785714286*G0_0_1_4_0_1 - 1.95267857142861*G0_0_1_5_0_0 - 1.95267857142861*G0_0_1_5_0_1 - 1.9526785714286*G0_0_1_6_0_0 + 1.95267857142861*G0_0_1_6_0_1 + 1.95267857142861*G0_0_1_7_0_0 + 1.95267857142861*G0_0_1_7_0_1 - 1.95267857142862*G0_0_1_8_0_0 + 1.9526785714286*G0_0_1_8_0_1 + 3.90535714285722*G0_0_1_9_0_0 - 3.90535714285722*G0_0_1_9_0_1 - 1.95267857142861*G0_0_1_13_1_0 - 1.9526785714286*G0_0_1_13_1_1 + 1.9526785714286*G0_0_1_14_1_0 + 1.9526785714286*G0_0_1_14_1_1 - 1.95267857142861*G0_0_1_15_1_0 - 1.95267857142861*G0_0_1_15_1_1 - 1.9526785714286*G0_0_1_16_1_0 + 1.95267857142861*G0_0_1_16_1_1 + 1.95267857142861*G0_0_1_17_1_0 + 1.95267857142861*G0_0_1_17_1_1 - 1.95267857142862*G0_0_1_18_1_0 + 1.9526785714286*G0_0_1_18_1_1 + 3.90535714285722*G0_0_1_19_1_0 - 3.90535714285722*G0_0_1_19_1_1 - 1.41026785714287*G0_1_0_1_0_0 + 1.41026785714287*G0_1_0_2_0_1 - 1.73571428571429*G0_1_0_3_0_0 - 3.14598214285716*G0_1_0_3_0_1 + 3.14598214285717*G0_1_0_4_0_0 + 1.73571428571429*G0_1_0_4_0_1 + 1.08482142857144*G0_1_0_5_0_0 + 1.08482142857145*G0_1_0_5_0_1 - 3.14598214285717*G0_1_0_6_0_0 - 2.49508928571432*G0_1_0_6_0_1 - 1.08482142857144*G0_1_0_7_0_0 - 1.08482142857144*G0_1_0_7_0_1 + 2.49508928571431*G0_1_0_8_0_0 + 3.14598214285716*G0_1_0_8_0_1 + 0.65089285714285*G0_1_0_9_0_0 - 0.650892857142853*G0_1_0_9_0_1 - 1.41026785714287*G0_1_0_11_1_0 + 1.41026785714287*G0_1_0_12_1_1 - 1.73571428571429*G0_1_0_13_1_0 - 3.14598214285716*G0_1_0_13_1_1 + 3.14598214285717*G0_1_0_14_1_0 + 1.73571428571429*G0_1_0_14_1_1 + 1.08482142857144*G0_1_0_15_1_0 + 1.08482142857145*G0_1_0_15_1_1 - 3.14598214285717*G0_1_0_16_1_0 - 2.49508928571432*G0_1_0_16_1_1 - 1.08482142857144*G0_1_0_17_1_0 - 1.08482142857144*G0_1_0_17_1_1 + 2.49508928571431*G0_1_0_18_1_0 + 3.14598214285716*G0_1_0_18_1_1 + 0.65089285714285*G0_1_0_19_1_0 - 0.650892857142853*G0_1_0_19_1_1 + 0.650892857142867*G0_1_1_0_0_0 + 0.650892857142867*G0_1_1_0_0_1 - 0.108482142857144*G0_1_1_1_0_0 + 1.08482142857144*G0_1_1_2_0_1 - 1.41026785714287*G0_1_1_3_0_0 - 0.54241071428572*G0_1_1_3_0_1 + 2.16964285714289*G0_1_1_4_0_0 + 0.108482142857152*G0_1_1_4_0_1 + 0.759375000000015*G0_1_1_5_0_0 - 0.542410714285725*G0_1_1_5_0_1 - 2.16964285714288*G0_1_1_6_0_0 - 1.19330357142858*G0_1_1_6_0_1 - 1.41026785714287*G0_1_1_7_0_0 - 0.108482142857131*G0_1_1_7_0_1 + 0.867857142857146*G0_1_1_8_0_0 + 0.54241071428572*G0_1_1_8_0_1 + 0.650892857142855*G0_1_1_9_0_0 + 0.650892857142867*G0_1_1_10_1_0 + 0.650892857142867*G0_1_1_10_1_1 - 0.108482142857144*G0_1_1_11_1_0 + 1.08482142857144*G0_1_1_12_1_1 - 1.41026785714287*G0_1_1_13_1_0 - 0.54241071428572*G0_1_1_13_1_1 + 2.16964285714289*G0_1_1_14_1_0 + 0.108482142857152*G0_1_1_14_1_1 + 0.759375000000015*G0_1_1_15_1_0 - 0.542410714285725*G0_1_1_15_1_1 - 2.16964285714288*G0_1_1_16_1_0 - 1.19330357142858*G0_1_1_16_1_1 - 1.41026785714287*G0_1_1_17_1_0 - 0.108482142857131*G0_1_1_17_1_1 + 0.867857142857146*G0_1_1_18_1_0 + 0.54241071428572*G0_1_1_18_1_1 + 0.650892857142855*G0_1_1_19_1_0; + A[319] = A[186] + 1.37410714285717*G0_0_0_0_0_0 + 1.37410714285717*G0_0_0_0_0_1 - 0.0723214285714365*G0_0_0_1_0_0 - 0.0723214285714346*G0_0_0_2_0_1 - 1.95267857142861*G0_0_0_3_0_0 - 1.95267857142862*G0_0_0_4_0_0 - 3.90535714285722*G0_0_0_4_0_1 + 1.95267857142858*G0_0_0_5_0_0 - 0.650892857142884*G0_0_0_5_0_1 + 1.95267857142862*G0_0_0_6_0_0 - 0.650892857142852*G0_0_0_6_0_1 - 2.60357142857149*G0_0_0_7_0_0 + 1.30178571428576*G0_0_0_8_0_0 + 3.90535714285725*G0_0_0_9_0_1 + 1.37410714285717*G0_0_0_10_1_0 + 1.37410714285717*G0_0_0_10_1_1 - 0.0723214285714365*G0_0_0_11_1_0 - 0.0723214285714346*G0_0_0_12_1_1 - 1.95267857142861*G0_0_0_13_1_0 - 1.95267857142862*G0_0_0_14_1_0 - 3.90535714285722*G0_0_0_14_1_1 + 1.95267857142858*G0_0_0_15_1_0 - 0.650892857142884*G0_0_0_15_1_1 + 1.95267857142862*G0_0_0_16_1_0 - 0.650892857142852*G0_0_0_16_1_1 - 2.60357142857149*G0_0_0_17_1_0 + 1.30178571428576*G0_0_0_18_1_0 + 3.90535714285725*G0_0_0_19_1_1 + 0.831696428571448*G0_0_1_0_0_0 + 0.831696428571448*G0_0_1_0_0_1 - 0.0723214285714365*G0_0_1_1_0_0 - 0.614732142857156*G0_0_1_2_0_1 - 1.08482142857146*G0_0_1_3_0_0 - 2.71205357142863*G0_0_1_4_0_0 - 3.25446428571436*G0_0_1_4_0_1 + 1.73571428571428*G0_0_1_5_0_0 - 0.108482142857164*G0_0_1_5_0_1 + 2.71205357142863*G0_0_1_6_0_0 - 0.108482142857129*G0_0_1_6_0_1 - 1.19330357142862*G0_0_1_7_0_0 + 0.650892857142826*G0_0_1_7_0_1 + 0.433928571428608*G0_0_1_8_0_0 - 0.650892857142818*G0_0_1_9_0_0 + 2.60357142857154*G0_0_1_9_0_1 + 0.831696428571448*G0_0_1_10_1_0 + 0.831696428571448*G0_0_1_10_1_1 - 0.0723214285714365*G0_0_1_11_1_0 - 0.614732142857156*G0_0_1_12_1_1 - 1.08482142857146*G0_0_1_13_1_0 - 2.71205357142863*G0_0_1_14_1_0 - 3.25446428571436*G0_0_1_14_1_1 + 1.73571428571428*G0_0_1_15_1_0 - 0.108482142857164*G0_0_1_15_1_1 + 2.71205357142863*G0_0_1_16_1_0 - 0.108482142857129*G0_0_1_16_1_1 - 1.19330357142862*G0_0_1_17_1_0 + 0.650892857142826*G0_0_1_17_1_1 + 0.433928571428608*G0_0_1_18_1_0 - 0.650892857142818*G0_0_1_19_1_0 + 2.60357142857154*G0_0_1_19_1_1 - 0.0361607142856999*G0_1_0_0_0_0 - 0.0361607142856998*G0_1_0_0_0_1 - 0.0723214285714374*G0_1_0_1_0_0 - 1.48258928571431*G0_1_0_2_0_1 - 0.867857142857172*G0_1_0_3_0_0 - 5.09866071428578*G0_1_0_4_0_0 - 4.55625000000007*G0_1_0_4_0_1 + 0.216964285714276*G0_1_0_5_0_0 + 0.759374999999983*G0_1_0_5_0_1 + 5.09866071428578*G0_1_0_6_0_0 + 0.759375000000022*G0_1_0_6_0_1 - 0.108482142857179*G0_1_0_7_0_0 - 0.650892857142888*G0_1_0_7_0_1 + 0.216964285714318*G0_1_0_8_0_0 + 0.650892857142896*G0_1_0_9_0_0 + 5.20714285714296*G0_1_0_9_0_1 - 0.0361607142856999*G0_1_0_10_1_0 - 0.0361607142856998*G0_1_0_10_1_1 - 0.0723214285714374*G0_1_0_11_1_0 - 1.48258928571431*G0_1_0_12_1_1 - 0.867857142857172*G0_1_0_13_1_0 - 5.09866071428578*G0_1_0_14_1_0 - 4.55625000000007*G0_1_0_14_1_1 + 0.216964285714276*G0_1_0_15_1_0 + 0.759374999999983*G0_1_0_15_1_1 + 5.09866071428578*G0_1_0_16_1_0 + 0.759375000000022*G0_1_0_16_1_1 - 0.108482142857179*G0_1_0_17_1_0 - 0.650892857142888*G0_1_0_17_1_1 + 0.216964285714318*G0_1_0_18_1_0 + 0.650892857142896*G0_1_0_19_1_0 + 5.20714285714296*G0_1_0_19_1_1 - 0.650892857142859*G0_1_1_0_0_0 - 0.650892857142859*G0_1_1_0_0_1 - 0.650892857142859*G0_1_1_2_0_1 - 1.30178571428577*G0_1_1_3_0_0 - 3.25446428571435*G0_1_1_4_0_0 - 3.90535714285726*G0_1_1_4_0_1 - 2.60357142857149*G0_1_1_5_0_0 + 0.650892857142859*G0_1_1_5_0_1 + 3.25446428571434*G0_1_1_6_0_0 + 0.650892857142858*G0_1_1_6_0_1 - 0.65089285714291*G0_1_1_7_0_0 - 3.90535714285725*G0_1_1_7_0_1 + 1.30178571428577*G0_1_1_8_0_0 + 3.90535714285725*G0_1_1_9_0_0 + 7.81071428571451*G0_1_1_9_0_1 - 0.650892857142859*G0_1_1_10_1_0 - 0.650892857142859*G0_1_1_10_1_1 - 0.650892857142859*G0_1_1_12_1_1 - 1.30178571428577*G0_1_1_13_1_0 - 3.25446428571435*G0_1_1_14_1_0 - 3.90535714285726*G0_1_1_14_1_1 - 2.60357142857149*G0_1_1_15_1_0 + 0.650892857142859*G0_1_1_15_1_1 + 3.25446428571434*G0_1_1_16_1_0 + 0.650892857142858*G0_1_1_16_1_1 - 0.65089285714291*G0_1_1_17_1_0 - 3.90535714285725*G0_1_1_17_1_1 + 1.30178571428577*G0_1_1_18_1_0 + 3.90535714285725*G0_1_1_19_1_0 + 7.81071428571451*G0_1_1_19_1_1; + A[395] = A[319] - 1.08482142857143*G0_0_1_0_0_0 - 1.08482142857143*G0_0_1_0_0_1 - 0.325446428571438*G0_0_1_1_0_0 + 0.216964285714286*G0_0_1_2_0_1 + 1.41026785714288*G0_0_1_3_0_0 + 0.325446428571429*G0_0_1_3_0_1 - 0.867857142857159*G0_0_1_4_0_0 - 0.325446428571431*G0_0_1_4_0_1 + 1.84419642857147*G0_0_1_5_0_0 + 3.36294642857147*G0_0_1_5_0_1 + 0.867857142857159*G0_0_1_6_0_0 - 2.49508928571432*G0_0_1_6_0_1 + 0.54241071428571*G0_0_1_7_0_0 - 0.976339285714285*G0_0_1_7_0_1 + 0.867857142857162*G0_0_1_8_0_0 - 0.32544642857143*G0_0_1_8_0_1 - 3.25446428571435*G0_0_1_9_0_0 + 1.30178571428572*G0_0_1_9_0_1 - 1.08482142857143*G0_0_1_10_1_0 - 1.08482142857143*G0_0_1_10_1_1 - 0.325446428571438*G0_0_1_11_1_0 + 0.216964285714286*G0_0_1_12_1_1 + 1.41026785714288*G0_0_1_13_1_0 + 0.325446428571429*G0_0_1_13_1_1 - 0.867857142857159*G0_0_1_14_1_0 - 0.325446428571431*G0_0_1_14_1_1 + 1.84419642857147*G0_0_1_15_1_0 + 3.36294642857147*G0_0_1_15_1_1 + 0.867857142857159*G0_0_1_16_1_0 - 2.49508928571432*G0_0_1_16_1_1 + 0.54241071428571*G0_0_1_17_1_0 - 0.976339285714285*G0_0_1_17_1_1 + 0.867857142857162*G0_0_1_18_1_0 - 0.32544642857143*G0_0_1_18_1_1 - 3.25446428571435*G0_0_1_19_1_0 + 1.30178571428572*G0_0_1_19_1_1 + 1.08482142857143*G0_1_0_0_0_0 + 1.08482142857143*G0_1_0_0_0_1 + 0.325446428571438*G0_1_0_1_0_0 - 0.216964285714286*G0_1_0_2_0_1 - 1.41026785714288*G0_1_0_3_0_0 - 0.325446428571429*G0_1_0_3_0_1 + 0.867857142857159*G0_1_0_4_0_0 + 0.325446428571431*G0_1_0_4_0_1 - 1.84419642857147*G0_1_0_5_0_0 - 3.36294642857147*G0_1_0_5_0_1 - 0.867857142857159*G0_1_0_6_0_0 + 2.49508928571432*G0_1_0_6_0_1 - 0.54241071428571*G0_1_0_7_0_0 + 0.976339285714285*G0_1_0_7_0_1 - 0.867857142857162*G0_1_0_8_0_0 + 0.32544642857143*G0_1_0_8_0_1 + 3.25446428571436*G0_1_0_9_0_0 - 1.30178571428572*G0_1_0_9_0_1 + 1.08482142857143*G0_1_0_10_1_0 + 1.08482142857143*G0_1_0_10_1_1 + 0.325446428571438*G0_1_0_11_1_0 - 0.216964285714286*G0_1_0_12_1_1 - 1.41026785714288*G0_1_0_13_1_0 - 0.325446428571429*G0_1_0_13_1_1 + 0.867857142857159*G0_1_0_14_1_0 + 0.325446428571431*G0_1_0_14_1_1 - 1.84419642857147*G0_1_0_15_1_0 - 3.36294642857147*G0_1_0_15_1_1 - 0.867857142857159*G0_1_0_16_1_0 + 2.49508928571432*G0_1_0_16_1_1 - 0.54241071428571*G0_1_0_17_1_0 + 0.976339285714285*G0_1_0_17_1_1 - 0.867857142857162*G0_1_0_18_1_0 + 0.32544642857143*G0_1_0_18_1_1 + 3.25446428571436*G0_1_0_19_1_0 - 1.30178571428572*G0_1_0_19_1_1; + A[169] = A[379]; + A[184] = -A[186] + 0.542410714285724*G0_0_1_0_0_0 + 0.542410714285725*G0_0_1_0_0_1 + 0.54241071428572*G0_0_1_1_0_0 - 4.55625000000006*G0_0_1_3_0_0 - 1.19330357142859*G0_0_1_3_0_1 - 2.82053571428575*G0_0_1_4_0_1 - 4.55625000000007*G0_0_1_5_0_0 - 3.36294642857148*G0_0_1_5_0_1 + 2.82053571428576*G0_0_1_6_0_1 - 0.542410714285726*G0_0_1_7_0_0 - 1.73571428571431*G0_0_1_7_0_1 - 0.542410714285718*G0_0_1_8_0_0 + 1.19330357142859*G0_0_1_8_0_1 + 9.11250000000014*G0_0_1_9_0_0 + 4.55625000000006*G0_0_1_9_0_1 + 0.542410714285724*G0_0_1_10_1_0 + 0.542410714285725*G0_0_1_10_1_1 + 0.54241071428572*G0_0_1_11_1_0 - 4.55625000000006*G0_0_1_13_1_0 - 1.19330357142859*G0_0_1_13_1_1 - 2.82053571428575*G0_0_1_14_1_1 - 4.55625000000007*G0_0_1_15_1_0 - 3.36294642857148*G0_0_1_15_1_1 + 2.82053571428576*G0_0_1_16_1_1 - 0.542410714285726*G0_0_1_17_1_0 - 1.73571428571431*G0_0_1_17_1_1 - 0.542410714285718*G0_0_1_18_1_0 + 1.19330357142859*G0_0_1_18_1_1 + 9.11250000000014*G0_0_1_19_1_0 + 4.55625000000006*G0_0_1_19_1_1 + 0.723214285714305*G0_1_1_0_0_0 + 0.723214285714306*G0_1_1_0_0_1 - 0.180803571428582*G0_1_1_1_0_0 - 0.289285714285729*G0_1_1_2_0_1 - 4.01383928571433*G0_1_1_3_0_0 - 2.49508928571434*G0_1_1_3_0_1 - 0.433928571428568*G0_1_1_4_0_0 - 1.84419642857141*G0_1_1_4_0_1 - 0.54241071428573*G0_1_1_5_0_0 - 1.84419642857149*G0_1_1_5_0_1 + 0.433928571428568*G0_1_1_6_0_0 + 1.41026785714291*G0_1_1_6_0_1 + 0.542410714285732*G0_1_1_7_0_0 + 1.84419642857149*G0_1_1_7_0_1 - 1.08482142857146*G0_1_1_8_0_0 + 2.49508928571434*G0_1_1_8_0_1 + 4.55625000000006*G0_1_1_9_0_0 + 0.723214285714305*G0_1_1_10_1_0 + 0.723214285714306*G0_1_1_10_1_1 - 0.180803571428582*G0_1_1_11_1_0 - 0.289285714285729*G0_1_1_12_1_1 - 4.01383928571433*G0_1_1_13_1_0 - 2.49508928571434*G0_1_1_13_1_1 - 0.433928571428568*G0_1_1_14_1_0 - 1.84419642857141*G0_1_1_14_1_1 - 0.54241071428573*G0_1_1_15_1_0 - 1.84419642857149*G0_1_1_15_1_1 + 0.433928571428568*G0_1_1_16_1_0 + 1.41026785714291*G0_1_1_16_1_1 + 0.542410714285732*G0_1_1_17_1_0 + 1.84419642857149*G0_1_1_17_1_1 - 1.08482142857146*G0_1_1_18_1_0 + 2.49508928571434*G0_1_1_18_1_1 + 4.55625000000006*G0_1_1_19_1_0; + A[299] = A[184] - 0.325446428571438*G0_0_1_0_0_0 - 0.325446428571438*G0_0_1_0_0_1 - 0.216964285714284*G0_0_1_1_0_0 - 1.08482142857143*G0_0_1_2_0_1 + 3.36294642857147*G0_0_1_3_0_0 + 0.867857142857159*G0_0_1_3_0_1 - 1.51874999999999*G0_0_1_4_0_0 + 1.84419642857147*G0_0_1_4_0_1 + 1.19330357142859*G0_0_1_5_0_0 + 0.867857142857159*G0_0_1_5_0_1 + 1.51875*G0_0_1_6_0_0 + 0.542410714285713*G0_0_1_6_0_1 + 1.08482142857146*G0_0_1_7_0_0 + 1.41026785714288*G0_0_1_7_0_1 - 0.542410714285734*G0_0_1_8_0_0 - 0.867857142857159*G0_0_1_8_0_1 - 4.55625000000007*G0_0_1_9_0_0 - 3.25446428571435*G0_0_1_9_0_1 - 0.325446428571438*G0_0_1_10_1_0 - 0.325446428571438*G0_0_1_10_1_1 - 0.216964285714284*G0_0_1_11_1_0 - 1.08482142857143*G0_0_1_12_1_1 + 3.36294642857147*G0_0_1_13_1_0 + 0.867857142857159*G0_0_1_13_1_1 - 1.51874999999999*G0_0_1_14_1_0 + 1.84419642857147*G0_0_1_14_1_1 + 1.19330357142859*G0_0_1_15_1_0 + 0.867857142857159*G0_0_1_15_1_1 + 1.51875*G0_0_1_16_1_0 + 0.542410714285713*G0_0_1_16_1_1 + 1.08482142857146*G0_0_1_17_1_0 + 1.41026785714288*G0_0_1_17_1_1 - 0.542410714285734*G0_0_1_18_1_0 - 0.867857142857159*G0_0_1_18_1_1 - 4.55625000000007*G0_0_1_19_1_0 - 3.25446428571435*G0_0_1_19_1_1 + 0.325446428571438*G0_1_0_0_0_0 + 0.325446428571438*G0_1_0_0_0_1 + 0.216964285714283*G0_1_0_1_0_0 + 1.08482142857143*G0_1_0_2_0_1 - 3.36294642857147*G0_1_0_3_0_0 - 0.867857142857158*G0_1_0_3_0_1 + 1.51874999999999*G0_1_0_4_0_0 - 1.84419642857147*G0_1_0_4_0_1 - 1.19330357142859*G0_1_0_5_0_0 - 0.867857142857159*G0_1_0_5_0_1 - 1.51875*G0_1_0_6_0_0 - 0.542410714285713*G0_1_0_6_0_1 - 1.08482142857146*G0_1_0_7_0_0 - 1.41026785714288*G0_1_0_7_0_1 + 0.542410714285734*G0_1_0_8_0_0 + 0.867857142857159*G0_1_0_8_0_1 + 4.55625000000007*G0_1_0_9_0_0 + 3.25446428571435*G0_1_0_9_0_1 + 0.325446428571438*G0_1_0_10_1_0 + 0.325446428571438*G0_1_0_10_1_1 + 0.216964285714283*G0_1_0_11_1_0 + 1.08482142857143*G0_1_0_12_1_1 - 3.36294642857147*G0_1_0_13_1_0 - 0.867857142857158*G0_1_0_13_1_1 + 1.51874999999999*G0_1_0_14_1_0 - 1.84419642857147*G0_1_0_14_1_1 - 1.19330357142859*G0_1_0_15_1_0 - 0.867857142857159*G0_1_0_15_1_1 - 1.51875*G0_1_0_16_1_0 - 0.542410714285713*G0_1_0_16_1_1 - 1.08482142857146*G0_1_0_17_1_0 - 1.41026785714288*G0_1_0_17_1_1 + 0.542410714285734*G0_1_0_18_1_0 + 0.867857142857159*G0_1_0_18_1_1 + 4.55625000000007*G0_1_0_19_1_0 + 3.25446428571435*G0_1_0_19_1_1; + A[206] = 0.0; + A[16] = 0.0; + A[280] = 0.0; + A[256] = A[122] - 0.266517857142862*G0_0_1_0_0_0 - 0.266517857142862*G0_0_1_0_0_1 + 0.266517857142862*G0_0_1_1_0_0 + 2.02633928571431*G0_0_1_2_0_1 - 1.3138392857143*G0_0_1_3_0_0 - 0.16875*G0_0_1_3_0_1 + 3.96562500000004*G0_0_1_4_0_0 + 1.06071428571429*G0_0_1_4_0_1 + 1.3138392857143*G0_0_1_5_0_0 + 1.1450892857143*G0_0_1_5_0_1 - 3.96562500000004*G0_0_1_6_0_0 - 2.90491071428575*G0_0_1_6_0_1 + 0.168750000000004*G0_0_1_7_0_1 + 0.16875*G0_0_1_8_0_1 - 1.2294642857143*G0_0_1_9_0_1 - 0.266517857142862*G0_0_1_10_1_0 - 0.266517857142862*G0_0_1_10_1_1 + 0.266517857142862*G0_0_1_11_1_0 + 2.02633928571431*G0_0_1_12_1_1 - 1.3138392857143*G0_0_1_13_1_0 - 0.16875*G0_0_1_13_1_1 + 3.96562500000004*G0_0_1_14_1_0 + 1.06071428571429*G0_0_1_14_1_1 + 1.3138392857143*G0_0_1_15_1_0 + 1.1450892857143*G0_0_1_15_1_1 - 3.96562500000004*G0_0_1_16_1_0 - 2.90491071428575*G0_0_1_16_1_1 + 0.168750000000004*G0_0_1_17_1_1 + 0.16875*G0_0_1_18_1_1 - 1.2294642857143*G0_0_1_19_1_1 + 0.266517857142862*G0_1_0_0_0_0 + 0.266517857142862*G0_1_0_0_0_1 - 0.266517857142862*G0_1_0_1_0_0 - 2.02633928571431*G0_1_0_2_0_1 + 1.3138392857143*G0_1_0_3_0_0 + 0.16875*G0_1_0_3_0_1 - 3.96562500000004*G0_1_0_4_0_0 - 1.06071428571429*G0_1_0_4_0_1 - 1.3138392857143*G0_1_0_5_0_0 - 1.1450892857143*G0_1_0_5_0_1 + 3.96562500000004*G0_1_0_6_0_0 + 2.90491071428575*G0_1_0_6_0_1 - 0.168750000000004*G0_1_0_7_0_1 - 0.16875*G0_1_0_8_0_1 + 1.2294642857143*G0_1_0_9_0_1 + 0.266517857142862*G0_1_0_10_1_0 + 0.266517857142862*G0_1_0_10_1_1 - 0.266517857142862*G0_1_0_11_1_0 - 2.02633928571431*G0_1_0_12_1_1 + 1.3138392857143*G0_1_0_13_1_0 + 0.16875*G0_1_0_13_1_1 - 3.96562500000004*G0_1_0_14_1_0 - 1.06071428571429*G0_1_0_14_1_1 - 1.3138392857143*G0_1_0_15_1_0 - 1.1450892857143*G0_1_0_15_1_1 + 3.96562500000004*G0_1_0_16_1_0 + 2.90491071428575*G0_1_0_16_1_1 - 0.168750000000004*G0_1_0_17_1_1 - 0.16875*G0_1_0_18_1_1 + 1.2294642857143*G0_1_0_19_1_1; + A[305] = 0.0; + A[390] = A[180]; + A[171] = 0.0; + A[190] = 0.0; + A[201] = 0.0; + A[177] = 0.0; + A[232] = -0.00781249999999977*G0_0_1_0_0_0 - 0.00781249999999973*G0_0_1_0_0_1 + 0.182589285714288*G0_0_1_1_0_0 + 0.182589285714289*G0_0_1_2_0_1 - 0.149330357142861*G0_0_1_3_0_0 + 0.26651785714286*G0_0_1_3_0_1 + 0.266517857142861*G0_0_1_4_0_0 - 0.14933035714286*G0_0_1_4_0_1 + 0.040848214285715*G0_0_1_5_0_0 + 0.0120535714285713*G0_0_1_5_0_1 - 0.266517857142862*G0_0_1_6_0_0 - 0.18683035714286*G0_0_1_6_0_1 + 0.0120535714285706*G0_0_1_7_0_0 + 0.0408482142857145*G0_0_1_7_0_1 - 0.186830357142859*G0_0_1_8_0_0 - 0.26651785714286*G0_0_1_8_0_1 + 0.108482142857146*G0_0_1_9_0_0 + 0.108482142857145*G0_0_1_9_0_1 - 0.00781249999999977*G0_0_1_10_1_0 - 0.00781249999999973*G0_0_1_10_1_1 + 0.182589285714288*G0_0_1_11_1_0 + 0.182589285714289*G0_0_1_12_1_1 - 0.149330357142861*G0_0_1_13_1_0 + 0.26651785714286*G0_0_1_13_1_1 + 0.266517857142861*G0_0_1_14_1_0 - 0.14933035714286*G0_0_1_14_1_1 + 0.040848214285715*G0_0_1_15_1_0 + 0.0120535714285713*G0_0_1_15_1_1 - 0.266517857142862*G0_0_1_16_1_0 - 0.18683035714286*G0_0_1_16_1_1 + 0.0120535714285706*G0_0_1_17_1_0 + 0.0408482142857145*G0_0_1_17_1_1 - 0.186830357142859*G0_0_1_18_1_0 - 0.26651785714286*G0_0_1_18_1_1 + 0.108482142857146*G0_0_1_19_1_0 + 0.108482142857145*G0_0_1_19_1_1; + A[20] = -A[232] + 0.182589285714288*G0_0_0_0_0_0 + 0.182589285714288*G0_0_0_0_0_1 - 0.182589285714288*G0_0_0_1_0_0 - 0.00781249999999974*G0_0_0_2_0_1 - 0.0796875000000009*G0_0_0_3_0_0 - 0.266517857142861*G0_0_0_3_0_1 + 0.0287946428571436*G0_0_0_4_0_0 + 0.0408482142857147*G0_0_0_4_0_1 + 0.0796875000000008*G0_0_0_5_0_0 - 0.186830357142859*G0_0_0_5_0_1 - 0.0287946428571436*G0_0_0_6_0_0 + 0.012053571428571*G0_0_0_6_0_1 - 0.41584821428572*G0_0_0_7_0_0 - 0.14933035714286*G0_0_0_7_0_1 + 0.41584821428572*G0_0_0_8_0_0 + 0.266517857142861*G0_0_0_8_0_1 + 0.108482142857145*G0_0_0_9_0_1 + 0.182589285714288*G0_0_0_10_1_0 + 0.182589285714288*G0_0_0_10_1_1 - 0.182589285714288*G0_0_0_11_1_0 - 0.00781249999999974*G0_0_0_12_1_1 - 0.0796875000000009*G0_0_0_13_1_0 - 0.266517857142861*G0_0_0_13_1_1 + 0.0287946428571436*G0_0_0_14_1_0 + 0.0408482142857147*G0_0_0_14_1_1 + 0.0796875000000008*G0_0_0_15_1_0 - 0.186830357142859*G0_0_0_15_1_1 - 0.0287946428571436*G0_0_0_16_1_0 + 0.012053571428571*G0_0_0_16_1_1 - 0.41584821428572*G0_0_0_17_1_0 - 0.14933035714286*G0_0_0_17_1_1 + 0.41584821428572*G0_0_0_18_1_0 + 0.266517857142861*G0_0_0_18_1_1 + 0.108482142857145*G0_0_0_19_1_1 + 0.174776785714288*G0_0_1_0_0_0 + 0.174776785714288*G0_0_1_0_0_1 + 0.174776785714289*G0_0_1_2_0_1 - 0.229017857142862*G0_0_1_3_0_0 + 0.295312500000005*G0_0_1_4_0_0 - 0.108482142857145*G0_0_1_4_0_1 + 0.120535714285716*G0_0_1_5_0_0 - 0.174776785714288*G0_0_1_5_0_1 - 0.295312500000005*G0_0_1_6_0_0 - 0.174776785714289*G0_0_1_6_0_1 - 0.403794642857149*G0_0_1_7_0_0 - 0.108482142857146*G0_0_1_7_0_1 + 0.229017857142861*G0_0_1_8_0_0 + 0.108482142857146*G0_0_1_9_0_0 + 0.216964285714291*G0_0_1_9_0_1 + 0.174776785714288*G0_0_1_10_1_0 + 0.174776785714288*G0_0_1_10_1_1 + 0.174776785714289*G0_0_1_12_1_1 - 0.229017857142862*G0_0_1_13_1_0 + 0.295312500000005*G0_0_1_14_1_0 - 0.108482142857145*G0_0_1_14_1_1 + 0.120535714285716*G0_0_1_15_1_0 - 0.174776785714288*G0_0_1_15_1_1 - 0.295312500000005*G0_0_1_16_1_0 - 0.174776785714289*G0_0_1_16_1_1 - 0.403794642857149*G0_0_1_17_1_0 - 0.108482142857146*G0_0_1_17_1_1 + 0.229017857142861*G0_0_1_18_1_0 + 0.108482142857146*G0_0_1_19_1_0 + 0.216964285714291*G0_0_1_19_1_1; + A[212] = -A[232] + 0.174776785714288*G0_0_1_0_0_0 + 0.174776785714288*G0_0_1_0_0_1 + 0.174776785714288*G0_0_1_1_0_0 - 0.108482142857146*G0_0_1_3_0_0 + 0.295312500000003*G0_0_1_3_0_1 - 0.229017857142861*G0_0_1_4_0_1 - 0.108482142857146*G0_0_1_5_0_0 - 0.403794642857149*G0_0_1_5_0_1 + 0.229017857142861*G0_0_1_6_0_1 - 0.174776785714288*G0_0_1_7_0_0 + 0.120535714285715*G0_0_1_7_0_1 - 0.174776785714288*G0_0_1_8_0_0 - 0.295312500000003*G0_0_1_8_0_1 + 0.216964285714291*G0_0_1_9_0_0 + 0.108482142857146*G0_0_1_9_0_1 + 0.174776785714288*G0_0_1_10_1_0 + 0.174776785714288*G0_0_1_10_1_1 + 0.174776785714288*G0_0_1_11_1_0 - 0.108482142857146*G0_0_1_13_1_0 + 0.295312500000003*G0_0_1_13_1_1 - 0.229017857142861*G0_0_1_14_1_1 - 0.108482142857146*G0_0_1_15_1_0 - 0.403794642857149*G0_0_1_15_1_1 + 0.229017857142861*G0_0_1_16_1_1 - 0.174776785714288*G0_0_1_17_1_0 + 0.120535714285715*G0_0_1_17_1_1 - 0.174776785714288*G0_0_1_18_1_0 - 0.295312500000003*G0_0_1_18_1_1 + 0.216964285714291*G0_0_1_19_1_0 + 0.108482142857146*G0_0_1_19_1_1 + 0.182589285714288*G0_1_1_0_0_0 + 0.182589285714288*G0_1_1_0_0_1 - 0.00781249999999974*G0_1_1_1_0_0 - 0.182589285714289*G0_1_1_2_0_1 + 0.0408482142857151*G0_1_1_3_0_0 + 0.0287946428571437*G0_1_1_3_0_1 - 0.266517857142862*G0_1_1_4_0_0 - 0.0796875000000014*G0_1_1_4_0_1 - 0.149330357142861*G0_1_1_5_0_0 - 0.415848214285721*G0_1_1_5_0_1 + 0.266517857142862*G0_1_1_6_0_0 + 0.415848214285722*G0_1_1_6_0_1 - 0.186830357142859*G0_1_1_7_0_0 + 0.079687500000001*G0_1_1_7_0_1 + 0.0120535714285707*G0_1_1_8_0_0 - 0.0287946428571436*G0_1_1_8_0_1 + 0.108482142857146*G0_1_1_9_0_0 + 0.182589285714288*G0_1_1_10_1_0 + 0.182589285714288*G0_1_1_10_1_1 - 0.00781249999999974*G0_1_1_11_1_0 - 0.182589285714289*G0_1_1_12_1_1 + 0.0408482142857151*G0_1_1_13_1_0 + 0.0287946428571437*G0_1_1_13_1_1 - 0.266517857142862*G0_1_1_14_1_0 - 0.0796875000000014*G0_1_1_14_1_1 - 0.149330357142861*G0_1_1_15_1_0 - 0.415848214285721*G0_1_1_15_1_1 + 0.266517857142862*G0_1_1_16_1_0 + 0.415848214285722*G0_1_1_16_1_1 - 0.186830357142859*G0_1_1_17_1_0 + 0.079687500000001*G0_1_1_17_1_1 + 0.0120535714285707*G0_1_1_18_1_0 - 0.0287946428571436*G0_1_1_18_1_1 + 0.108482142857146*G0_1_1_19_1_0; + A[230] = A[20]; + A[2] = A[212]; + A[291] = A[81]; + A[255] = A[45]; + A[302] = 0.0; + A[13] = 0.0; + A[28] = -A[23] + 0.336160714285719*G0_0_0_0_0_0 + 0.336160714285719*G0_0_0_0_0_1 - 1.1075892857143*G0_0_0_1_0_0 - 0.33616071428572*G0_0_0_2_0_1 - 0.15669642857142*G0_0_0_3_0_0 - 1.84419642857144*G0_0_0_3_0_1 - 0.445982142857151*G0_0_0_4_0_0 + 0.470089285714293*G0_0_0_4_0_1 + 0.445982142857152*G0_0_0_5_0_0 + 0.445982142857151*G0_0_0_6_0_0 - 0.916071428571443*G0_0_0_7_0_0 - 0.470089285714292*G0_0_0_7_0_1 + 1.68750000000002*G0_0_0_8_0_0 + 1.84419642857145*G0_0_0_8_0_1 - 0.289285714285732*G0_0_0_9_0_0 + 0.336160714285719*G0_0_0_10_1_0 + 0.336160714285719*G0_0_0_10_1_1 - 1.1075892857143*G0_0_0_11_1_0 - 0.33616071428572*G0_0_0_12_1_1 - 0.15669642857142*G0_0_0_13_1_0 - 1.84419642857144*G0_0_0_13_1_1 - 0.445982142857151*G0_0_0_14_1_0 + 0.470089285714293*G0_0_0_14_1_1 + 0.445982142857152*G0_0_0_15_1_0 + 0.445982142857151*G0_0_0_16_1_0 - 0.916071428571443*G0_0_0_17_1_0 - 0.470089285714292*G0_0_0_17_1_1 + 1.68750000000002*G0_0_0_18_1_0 + 1.84419642857145*G0_0_0_18_1_1 - 0.289285714285732*G0_0_0_19_1_0; + A[55] = 0.0; + A[102] = A[62] - 0.190178571428576*G0_0_1_0_0_0 - 0.190178571428576*G0_0_1_0_0_1 + 0.190178571428576*G0_0_1_1_0_0 + 1.29910714285716*G0_0_1_2_0_1 - 0.699107142857156*G0_0_1_3_0_0 - 0.0241071428571423*G0_0_1_3_0_1 + 2.6276785714286*G0_0_1_4_0_0 + 0.843750000000005*G0_0_1_4_0_1 + 0.699107142857156*G0_0_1_5_0_0 + 0.675000000000013*G0_0_1_5_0_1 - 2.6276785714286*G0_0_1_6_0_0 - 1.7839285714286*G0_0_1_6_0_1 + 0.0241071428571475*G0_0_1_7_0_1 + 0.0241071428571424*G0_0_1_8_0_1 - 0.867857142857152*G0_0_1_9_0_1 - 0.190178571428576*G0_0_1_10_1_0 - 0.190178571428576*G0_0_1_10_1_1 + 0.190178571428576*G0_0_1_11_1_0 + 1.29910714285716*G0_0_1_12_1_1 - 0.699107142857156*G0_0_1_13_1_0 - 0.0241071428571423*G0_0_1_13_1_1 + 2.6276785714286*G0_0_1_14_1_0 + 0.843750000000005*G0_0_1_14_1_1 + 0.699107142857156*G0_0_1_15_1_0 + 0.675000000000013*G0_0_1_15_1_1 - 2.6276785714286*G0_0_1_16_1_0 - 1.7839285714286*G0_0_1_16_1_1 + 0.0241071428571475*G0_0_1_17_1_1 + 0.0241071428571424*G0_0_1_18_1_1 - 0.867857142857152*G0_0_1_19_1_1 - 0.444642857142864*G0_1_1_0_0_0 - 0.444642857142864*G0_1_1_0_0_1 - 0.254464285714288*G0_1_1_1_0_0 + 0.64955357142858*G0_1_1_2_0_1 - 0.132589285714287*G0_1_1_3_0_0 - 0.602678571428578*G0_1_1_3_0_1 + 1.3138392857143*G0_1_1_4_0_0 + 0.879910714285725*G0_1_1_4_0_1 + 0.566517857142869*G0_1_1_5_0_0 + 1.1450892857143*G0_1_1_5_0_1 - 1.3138392857143*G0_1_1_6_0_0 - 1.35000000000002*G0_1_1_6_0_1 + 0.349553571428579*G0_1_1_7_0_0 - 0.229017857142857*G0_1_1_7_0_1 + 0.349553571428573*G0_1_1_8_0_0 + 0.602678571428578*G0_1_1_8_0_1 - 0.433928571428582*G0_1_1_9_0_0 - 0.650892857142868*G0_1_1_9_0_1 - 0.444642857142864*G0_1_1_10_1_0 - 0.444642857142864*G0_1_1_10_1_1 - 0.254464285714288*G0_1_1_11_1_0 + 0.64955357142858*G0_1_1_12_1_1 - 0.132589285714287*G0_1_1_13_1_0 - 0.602678571428578*G0_1_1_13_1_1 + 1.3138392857143*G0_1_1_14_1_0 + 0.879910714285725*G0_1_1_14_1_1 + 0.566517857142869*G0_1_1_15_1_0 + 1.1450892857143*G0_1_1_15_1_1 - 1.3138392857143*G0_1_1_16_1_0 - 1.35000000000002*G0_1_1_16_1_1 + 0.349553571428579*G0_1_1_17_1_0 - 0.229017857142857*G0_1_1_17_1_1 + 0.349553571428573*G0_1_1_18_1_0 + 0.602678571428578*G0_1_1_18_1_1 - 0.433928571428582*G0_1_1_19_1_0 - 0.650892857142868*G0_1_1_19_1_1; + A[326] = 0.0; + A[129] = -A[299] + 0.542410714285724*G0_1_0_0_0_0 + 0.542410714285725*G0_1_0_0_0_1 + 0.54241071428572*G0_1_0_1_0_0 - 4.55625000000006*G0_1_0_3_0_0 - 1.19330357142859*G0_1_0_3_0_1 - 2.82053571428575*G0_1_0_4_0_1 - 4.55625000000007*G0_1_0_5_0_0 - 3.36294642857148*G0_1_0_5_0_1 + 2.82053571428576*G0_1_0_6_0_1 - 0.542410714285726*G0_1_0_7_0_0 - 1.73571428571431*G0_1_0_7_0_1 - 0.542410714285718*G0_1_0_8_0_0 + 1.19330357142859*G0_1_0_8_0_1 + 9.11250000000014*G0_1_0_9_0_0 + 4.55625000000006*G0_1_0_9_0_1 + 0.542410714285724*G0_1_0_10_1_0 + 0.542410714285725*G0_1_0_10_1_1 + 0.54241071428572*G0_1_0_11_1_0 - 4.55625000000006*G0_1_0_13_1_0 - 1.19330357142859*G0_1_0_13_1_1 - 2.82053571428575*G0_1_0_14_1_1 - 4.55625000000007*G0_1_0_15_1_0 - 3.36294642857148*G0_1_0_15_1_1 + 2.82053571428576*G0_1_0_16_1_1 - 0.542410714285726*G0_1_0_17_1_0 - 1.73571428571431*G0_1_0_17_1_1 - 0.542410714285718*G0_1_0_18_1_0 + 1.19330357142859*G0_1_0_18_1_1 + 9.11250000000014*G0_1_0_19_1_0 + 4.55625000000006*G0_1_0_19_1_1 + 0.723214285714305*G0_1_1_0_0_0 + 0.723214285714306*G0_1_1_0_0_1 - 0.180803571428582*G0_1_1_1_0_0 - 0.289285714285729*G0_1_1_2_0_1 - 4.01383928571433*G0_1_1_3_0_0 - 2.49508928571434*G0_1_1_3_0_1 - 0.433928571428568*G0_1_1_4_0_0 - 1.84419642857141*G0_1_1_4_0_1 - 0.54241071428573*G0_1_1_5_0_0 - 1.84419642857149*G0_1_1_5_0_1 + 0.433928571428568*G0_1_1_6_0_0 + 1.41026785714291*G0_1_1_6_0_1 + 0.542410714285732*G0_1_1_7_0_0 + 1.84419642857149*G0_1_1_7_0_1 - 1.08482142857146*G0_1_1_8_0_0 + 2.49508928571434*G0_1_1_8_0_1 + 4.55625000000006*G0_1_1_9_0_0 + 0.723214285714305*G0_1_1_10_1_0 + 0.723214285714306*G0_1_1_10_1_1 - 0.180803571428582*G0_1_1_11_1_0 - 0.289285714285729*G0_1_1_12_1_1 - 4.01383928571433*G0_1_1_13_1_0 - 2.49508928571434*G0_1_1_13_1_1 - 0.433928571428568*G0_1_1_14_1_0 - 1.84419642857141*G0_1_1_14_1_1 - 0.54241071428573*G0_1_1_15_1_0 - 1.84419642857149*G0_1_1_15_1_1 + 0.433928571428568*G0_1_1_16_1_0 + 1.41026785714291*G0_1_1_16_1_1 + 0.542410714285732*G0_1_1_17_1_0 + 1.84419642857149*G0_1_1_17_1_1 - 1.08482142857146*G0_1_1_18_1_0 + 2.49508928571434*G0_1_1_18_1_1 + 4.55625000000006*G0_1_1_19_1_0; + A[347] = 0.0; + A[152] = 0.0; + A[364] = 0.0; + A[208] = 0.0; + A[225] = 0.0; + A[246] = 0.0; + A[218] = A[370] + 0.649553571428577*G0_0_1_0_0_0 + 0.649553571428577*G0_0_1_0_0_1 - 0.149330357142859*G0_0_1_1_0_0 - 0.0408482142857143*G0_0_1_2_0_1 - 0.0241071428571402*G0_0_1_3_0_0 - 0.0783482142857146*G0_0_1_3_0_1 + 0.102455357142858*G0_0_1_4_0_0 + 0.0482142857142874*G0_0_1_4_0_1 + 0.494196428571433*G0_0_1_5_0_0 - 0.819642857142863*G0_0_1_5_0_1 - 0.102455357142858*G0_0_1_6_0_0 + 0.2109375*G0_0_1_6_0_1 - 0.964285714285724*G0_0_1_7_0_0 + 0.34955357142857*G0_0_1_7_0_1 + 0.464062500000007*G0_0_1_8_0_0 + 0.0783482142857148*G0_0_1_8_0_1 - 0.470089285714293*G0_0_1_9_0_0 - 0.397767857142858*G0_0_1_9_0_1 + 0.649553571428577*G0_0_1_10_1_0 + 0.649553571428577*G0_0_1_10_1_1 - 0.149330357142859*G0_0_1_11_1_0 - 0.0408482142857143*G0_0_1_12_1_1 - 0.0241071428571402*G0_0_1_13_1_0 - 0.0783482142857146*G0_0_1_13_1_1 + 0.102455357142858*G0_0_1_14_1_0 + 0.0482142857142874*G0_0_1_14_1_1 + 0.494196428571433*G0_0_1_15_1_0 - 0.819642857142863*G0_0_1_15_1_1 - 0.102455357142858*G0_0_1_16_1_0 + 0.2109375*G0_0_1_16_1_1 - 0.964285714285724*G0_0_1_17_1_0 + 0.34955357142857*G0_0_1_17_1_1 + 0.464062500000007*G0_0_1_18_1_0 + 0.0783482142857148*G0_0_1_18_1_1 - 0.470089285714293*G0_0_1_19_1_0 - 0.397767857142858*G0_0_1_19_1_1 - 0.649553571428577*G0_1_0_0_0_0 - 0.649553571428577*G0_1_0_0_0_1 + 0.149330357142859*G0_1_0_1_0_0 + 0.0408482142857142*G0_1_0_2_0_1 + 0.0241071428571402*G0_1_0_3_0_0 + 0.0783482142857146*G0_1_0_3_0_1 - 0.102455357142858*G0_1_0_4_0_0 - 0.0482142857142874*G0_1_0_4_0_1 - 0.494196428571433*G0_1_0_5_0_0 + 0.819642857142863*G0_1_0_5_0_1 + 0.102455357142858*G0_1_0_6_0_0 - 0.2109375*G0_1_0_6_0_1 + 0.964285714285724*G0_1_0_7_0_0 - 0.34955357142857*G0_1_0_7_0_1 - 0.464062500000007*G0_1_0_8_0_0 - 0.0783482142857148*G0_1_0_8_0_1 + 0.470089285714293*G0_1_0_9_0_0 + 0.397767857142858*G0_1_0_9_0_1 - 0.649553571428577*G0_1_0_10_1_0 - 0.649553571428577*G0_1_0_10_1_1 + 0.149330357142859*G0_1_0_11_1_0 + 0.0408482142857142*G0_1_0_12_1_1 + 0.0241071428571402*G0_1_0_13_1_0 + 0.0783482142857146*G0_1_0_13_1_1 - 0.102455357142858*G0_1_0_14_1_0 - 0.0482142857142874*G0_1_0_14_1_1 - 0.494196428571433*G0_1_0_15_1_0 + 0.819642857142863*G0_1_0_15_1_1 + 0.102455357142858*G0_1_0_16_1_0 - 0.2109375*G0_1_0_16_1_1 + 0.964285714285724*G0_1_0_17_1_0 - 0.34955357142857*G0_1_0_17_1_1 - 0.464062500000007*G0_1_0_18_1_0 - 0.0783482142857148*G0_1_0_18_1_1 + 0.470089285714293*G0_1_0_19_1_0 + 0.397767857142858*G0_1_0_19_1_1; + A[311] = A[101]; + A[267] = 0.0; + A[21] = -0.182589285714288*G0_0_0_0_0_0 - 0.182589285714288*G0_0_0_0_0_1 + 1.07455357142858*G0_0_0_1_0_0 + 0.182589285714288*G0_0_0_2_0_1 + 0.459375000000001*G0_0_0_3_0_0 + 2.0263392857143*G0_0_0_3_0_1 + 0.0254464285714301*G0_0_0_4_0_0 - 0.649553571428577*G0_0_0_4_0_1 - 0.0254464285714302*G0_0_0_5_0_0 - 0.0254464285714299*G0_0_0_6_0_0 + 0.675000000000008*G0_0_0_7_0_0 + 0.649553571428578*G0_0_0_7_0_1 - 1.5669642857143*G0_0_0_8_0_0 - 2.0263392857143*G0_0_0_8_0_1 - 0.433928571428571*G0_0_0_9_0_0 - 0.182589285714288*G0_0_0_10_1_0 - 0.182589285714288*G0_0_0_10_1_1 + 1.07455357142858*G0_0_0_11_1_0 + 0.182589285714288*G0_0_0_12_1_1 + 0.459375000000001*G0_0_0_13_1_0 + 2.0263392857143*G0_0_0_13_1_1 + 0.0254464285714301*G0_0_0_14_1_0 - 0.649553571428577*G0_0_0_14_1_1 - 0.0254464285714302*G0_0_0_15_1_0 - 0.0254464285714299*G0_0_0_16_1_0 + 0.675000000000008*G0_0_0_17_1_0 + 0.649553571428578*G0_0_0_17_1_1 - 1.5669642857143*G0_0_0_18_1_0 - 2.0263392857143*G0_0_0_18_1_1 - 0.433928571428571*G0_0_0_19_1_0; + A[0] = A[21] - 0.891964285714293*G0_0_0_0_0_0 - 0.891964285714293*G0_0_0_0_0_1 - 0.891964285714293*G0_0_0_1_0_0 - 0.433928571428572*G0_0_0_3_0_0 - 2.00089285714287*G0_0_0_3_0_1 + 0.675000000000006*G0_0_0_4_0_1 - 0.433928571428571*G0_0_0_5_0_0 + 1.5669642857143*G0_0_0_5_0_1 - 0.675000000000008*G0_0_0_6_0_1 + 0.891964285714293*G0_0_0_7_0_0 - 1.10892857142858*G0_0_0_7_0_1 + 0.891964285714294*G0_0_0_8_0_0 + 2.00089285714287*G0_0_0_8_0_1 + 0.867857142857143*G0_0_0_9_0_0 + 0.433928571428572*G0_0_0_9_0_1 - 0.891964285714293*G0_0_0_10_1_0 - 0.891964285714293*G0_0_0_10_1_1 - 0.891964285714293*G0_0_0_11_1_0 - 0.433928571428572*G0_0_0_13_1_0 - 2.00089285714287*G0_0_0_13_1_1 + 0.675000000000006*G0_0_0_14_1_1 - 0.433928571428571*G0_0_0_15_1_0 + 1.5669642857143*G0_0_0_15_1_1 - 0.675000000000008*G0_0_0_16_1_1 + 0.891964285714293*G0_0_0_17_1_0 - 1.10892857142858*G0_0_0_17_1_1 + 0.891964285714294*G0_0_0_18_1_0 + 2.00089285714287*G0_0_0_18_1_1 + 0.867857142857143*G0_0_0_19_1_0 + 0.433928571428572*G0_0_0_19_1_1 - 1.07455357142858*G0_0_1_0_0_0 - 1.07455357142858*G0_0_1_0_0_1 + 0.182589285714288*G0_0_1_1_0_0 + 0.182589285714288*G0_0_1_2_0_1 + 0.0254464285714291*G0_0_1_3_0_0 + 0.0254464285714301*G0_0_1_3_0_1 + 0.0254464285714299*G0_0_1_4_0_0 + 0.0254464285714291*G0_0_1_4_0_1 - 0.459375000000002*G0_0_1_5_0_0 + 1.5669642857143*G0_0_1_5_0_1 - 0.02544642857143*G0_0_1_6_0_0 - 0.675000000000008*G0_0_1_6_0_1 + 1.5669642857143*G0_0_1_7_0_0 - 0.459375000000002*G0_0_1_7_0_1 - 0.675000000000007*G0_0_1_8_0_0 - 0.0254464285714304*G0_0_1_8_0_1 + 0.433928571428572*G0_0_1_9_0_0 + 0.433928571428574*G0_0_1_9_0_1 - 1.07455357142858*G0_0_1_10_1_0 - 1.07455357142858*G0_0_1_10_1_1 + 0.182589285714288*G0_0_1_11_1_0 + 0.182589285714288*G0_0_1_12_1_1 + 0.0254464285714291*G0_0_1_13_1_0 + 0.0254464285714301*G0_0_1_13_1_1 + 0.0254464285714299*G0_0_1_14_1_0 + 0.0254464285714291*G0_0_1_14_1_1 - 0.459375000000002*G0_0_1_15_1_0 + 1.5669642857143*G0_0_1_15_1_1 - 0.02544642857143*G0_0_1_16_1_0 - 0.675000000000008*G0_0_1_16_1_1 + 1.5669642857143*G0_0_1_17_1_0 - 0.459375000000002*G0_0_1_17_1_1 - 0.675000000000007*G0_0_1_18_1_0 - 0.0254464285714304*G0_0_1_18_1_1 + 0.433928571428572*G0_0_1_19_1_0 + 0.433928571428574*G0_0_1_19_1_1 - 1.07455357142858*G0_1_0_0_0_0 - 1.07455357142858*G0_1_0_0_0_1 + 0.182589285714288*G0_1_0_1_0_0 + 0.182589285714288*G0_1_0_2_0_1 + 0.0254464285714291*G0_1_0_3_0_0 + 0.0254464285714301*G0_1_0_3_0_1 + 0.0254464285714299*G0_1_0_4_0_0 + 0.0254464285714291*G0_1_0_4_0_1 - 0.459375000000002*G0_1_0_5_0_0 + 1.5669642857143*G0_1_0_5_0_1 - 0.02544642857143*G0_1_0_6_0_0 - 0.675000000000008*G0_1_0_6_0_1 + 1.5669642857143*G0_1_0_7_0_0 - 0.459375000000002*G0_1_0_7_0_1 - 0.675000000000007*G0_1_0_8_0_0 - 0.0254464285714304*G0_1_0_8_0_1 + 0.433928571428572*G0_1_0_9_0_0 + 0.433928571428574*G0_1_0_9_0_1 - 1.07455357142858*G0_1_0_10_1_0 - 1.07455357142858*G0_1_0_10_1_1 + 0.182589285714288*G0_1_0_11_1_0 + 0.182589285714288*G0_1_0_12_1_1 + 0.0254464285714291*G0_1_0_13_1_0 + 0.0254464285714301*G0_1_0_13_1_1 + 0.0254464285714299*G0_1_0_14_1_0 + 0.0254464285714291*G0_1_0_14_1_1 - 0.459375000000002*G0_1_0_15_1_0 + 1.5669642857143*G0_1_0_15_1_1 - 0.02544642857143*G0_1_0_16_1_0 - 0.675000000000008*G0_1_0_16_1_1 + 1.5669642857143*G0_1_0_17_1_0 - 0.459375000000002*G0_1_0_17_1_1 - 0.675000000000007*G0_1_0_18_1_0 - 0.0254464285714304*G0_1_0_18_1_1 + 0.433928571428572*G0_1_0_19_1_0 + 0.433928571428574*G0_1_0_19_1_1 - 1.07455357142858*G0_1_1_0_0_0 - 1.07455357142858*G0_1_1_0_0_1 + 0.182589285714288*G0_1_1_1_0_0 + 0.182589285714288*G0_1_1_2_0_1 + 0.0254464285714292*G0_1_1_3_0_0 + 0.0254464285714302*G0_1_1_3_0_1 + 0.0254464285714299*G0_1_1_4_0_0 + 0.0254464285714292*G0_1_1_4_0_1 - 0.459375000000002*G0_1_1_5_0_0 + 1.5669642857143*G0_1_1_5_0_1 - 0.02544642857143*G0_1_1_6_0_0 - 0.675000000000009*G0_1_1_6_0_1 + 1.5669642857143*G0_1_1_7_0_0 - 0.459375000000002*G0_1_1_7_0_1 - 0.675000000000007*G0_1_1_8_0_0 - 0.0254464285714304*G0_1_1_8_0_1 + 0.433928571428572*G0_1_1_9_0_0 + 0.433928571428573*G0_1_1_9_0_1 - 1.07455357142858*G0_1_1_10_1_0 - 1.07455357142858*G0_1_1_10_1_1 + 0.182589285714288*G0_1_1_11_1_0 + 0.182589285714288*G0_1_1_12_1_1 + 0.0254464285714292*G0_1_1_13_1_0 + 0.0254464285714302*G0_1_1_13_1_1 + 0.0254464285714299*G0_1_1_14_1_0 + 0.0254464285714292*G0_1_1_14_1_1 - 0.459375000000002*G0_1_1_15_1_0 + 1.5669642857143*G0_1_1_15_1_1 - 0.02544642857143*G0_1_1_16_1_0 - 0.675000000000009*G0_1_1_16_1_1 + 1.5669642857143*G0_1_1_17_1_0 - 0.459375000000002*G0_1_1_17_1_1 - 0.675000000000007*G0_1_1_18_1_0 - 0.0254464285714304*G0_1_1_18_1_1 + 0.433928571428572*G0_1_1_19_1_0 + 0.433928571428573*G0_1_1_19_1_1; + A[210] = A[0]; + A[90] = 0.0; + A[46] = A[256]; + A[111] = 0.0; + A[96] = 0.0; + A[145] = 0.759375000000004*G0_0_0_0_0_0 + 0.759375000000004*G0_0_0_0_0_1 - 0.271205357142861*G0_0_0_1_0_0 + 0.054241071428575*G0_0_0_2_0_1 + 0.976339285714305*G0_0_0_3_0_0 + 0.379687500000005*G0_0_0_3_0_1 + 0.271205357142863*G0_0_0_4_0_0 + 0.542410714285726*G0_0_0_4_0_1 + 1.08482142857146*G0_0_0_5_0_0 - 0.542410714285702*G0_0_0_5_0_1 - 0.271205357142862*G0_0_0_6_0_0 - 0.271205357142877*G0_0_0_6_0_1 - 1.62723214285715*G0_0_0_7_0_0 + 1.13906250000001*G0_0_0_8_0_0 - 0.379687500000005*G0_0_0_8_0_1 - 2.06116071428577*G0_0_0_9_0_0 - 0.542410714285735*G0_0_0_9_0_1 + 0.759375000000004*G0_0_0_10_1_0 + 0.759375000000004*G0_0_0_10_1_1 - 0.271205357142861*G0_0_0_11_1_0 + 0.054241071428575*G0_0_0_12_1_1 + 0.976339285714305*G0_0_0_13_1_0 + 0.379687500000005*G0_0_0_13_1_1 + 0.271205357142863*G0_0_0_14_1_0 + 0.542410714285726*G0_0_0_14_1_1 + 1.08482142857146*G0_0_0_15_1_0 - 0.542410714285702*G0_0_0_15_1_1 - 0.271205357142862*G0_0_0_16_1_0 - 0.271205357142877*G0_0_0_16_1_1 - 1.62723214285715*G0_0_0_17_1_0 + 1.13906250000001*G0_0_0_18_1_0 - 0.379687500000005*G0_0_0_18_1_1 - 2.06116071428577*G0_0_0_19_1_0 - 0.542410714285735*G0_0_0_19_1_1 - 2.14553571428574*G0_0_1_0_0_0 - 2.14553571428574*G0_0_1_0_0_1 + 0.301339285714289*G0_0_1_1_0_0 + 0.301339285714289*G0_0_1_2_0_1 + 0.542410714285726*G0_0_1_3_0_0 + 0.108482142857147*G0_0_1_3_0_1 + 0.108482142857146*G0_0_1_4_0_0 + 0.542410714285726*G0_0_1_4_0_1 - 0.542410714285701*G0_0_1_5_0_0 + 3.25446428571432*G0_0_1_5_0_1 - 0.108482142857146*G0_0_1_6_0_0 - 1.41026785714288*G0_0_1_6_0_1 + 3.25446428571432*G0_0_1_7_0_0 - 0.5424107142857*G0_0_1_7_0_1 - 1.41026785714288*G0_0_1_8_0_0 - 0.108482142857148*G0_0_1_8_0_1 - 2.14553571428574*G0_0_1_10_1_0 - 2.14553571428574*G0_0_1_10_1_1 + 0.301339285714289*G0_0_1_11_1_0 + 0.301339285714289*G0_0_1_12_1_1 + 0.542410714285726*G0_0_1_13_1_0 + 0.108482142857147*G0_0_1_13_1_1 + 0.108482142857146*G0_0_1_14_1_0 + 0.542410714285726*G0_0_1_14_1_1 - 0.542410714285701*G0_0_1_15_1_0 + 3.25446428571432*G0_0_1_15_1_1 - 0.108482142857146*G0_0_1_16_1_0 - 1.41026785714288*G0_0_1_16_1_1 + 3.25446428571432*G0_0_1_17_1_0 - 0.5424107142857*G0_0_1_17_1_1 - 1.41026785714288*G0_0_1_18_1_0 - 0.108482142857148*G0_0_1_18_1_1 - 0.301339285714289*G0_1_0_0_0_0 - 0.301339285714289*G0_1_0_0_0_1 - 0.0241071428571411*G0_1_0_1_0_0 - 0.0241071428571407*G0_1_0_2_0_1 + 0.650892857142867*G0_1_0_3_0_0 + 0.216964285714292*G0_1_0_3_0_1 + 0.216964285714292*G0_1_0_4_0_0 + 0.650892857142868*G0_1_0_4_0_1 - 1.08482142857142*G0_1_0_5_0_0 - 0.216964285714292*G0_1_0_6_0_0 + 0.32544642857142*G0_1_0_6_0_1 - 1.08482142857142*G0_1_0_7_0_1 + 0.325446428571422*G0_1_0_8_0_0 - 0.216964285714291*G0_1_0_8_0_1 + 0.433928571428549*G0_1_0_9_0_0 + 0.43392857142855*G0_1_0_9_0_1 - 0.301339285714289*G0_1_0_10_1_0 - 0.301339285714289*G0_1_0_10_1_1 - 0.0241071428571411*G0_1_0_11_1_0 - 0.0241071428571407*G0_1_0_12_1_1 + 0.650892857142867*G0_1_0_13_1_0 + 0.216964285714292*G0_1_0_13_1_1 + 0.216964285714292*G0_1_0_14_1_0 + 0.650892857142868*G0_1_0_14_1_1 - 1.08482142857142*G0_1_0_15_1_0 - 0.216964285714292*G0_1_0_16_1_0 + 0.32544642857142*G0_1_0_16_1_1 - 1.08482142857142*G0_1_0_17_1_1 + 0.325446428571422*G0_1_0_18_1_0 - 0.216964285714291*G0_1_0_18_1_1 + 0.433928571428549*G0_1_0_19_1_0 + 0.43392857142855*G0_1_0_19_1_1 + 0.759375000000004*G0_1_1_0_0_0 + 0.759375000000004*G0_1_1_0_0_1 + 0.0542410714285751*G0_1_1_1_0_0 - 0.271205357142861*G0_1_1_2_0_1 + 0.542410714285725*G0_1_1_3_0_0 + 0.271205357142861*G0_1_1_3_0_1 + 0.379687500000007*G0_1_1_4_0_0 + 0.976339285714306*G0_1_1_4_0_1 - 1.62723214285715*G0_1_1_5_0_1 - 0.379687500000007*G0_1_1_6_0_0 + 1.13906250000001*G0_1_1_6_0_1 - 0.542410714285701*G0_1_1_7_0_0 + 1.08482142857146*G0_1_1_7_0_1 - 0.271205357142879*G0_1_1_8_0_0 - 0.271205357142862*G0_1_1_8_0_1 - 0.542410714285735*G0_1_1_9_0_0 - 2.06116071428577*G0_1_1_9_0_1 + 0.759375000000004*G0_1_1_10_1_0 + 0.759375000000004*G0_1_1_10_1_1 + 0.0542410714285751*G0_1_1_11_1_0 - 0.271205357142861*G0_1_1_12_1_1 + 0.542410714285725*G0_1_1_13_1_0 + 0.271205357142861*G0_1_1_13_1_1 + 0.379687500000007*G0_1_1_14_1_0 + 0.976339285714306*G0_1_1_14_1_1 - 1.62723214285715*G0_1_1_15_1_1 - 0.379687500000007*G0_1_1_16_1_0 + 1.13906250000001*G0_1_1_16_1_1 - 0.542410714285701*G0_1_1_17_1_0 + 1.08482142857146*G0_1_1_17_1_1 - 0.271205357142879*G0_1_1_18_1_0 - 0.271205357142862*G0_1_1_18_1_1 - 0.542410714285735*G0_1_1_19_1_0 - 2.06116071428577*G0_1_1_19_1_1; + A[339] = A[129]; + A[260] = 0.0; + A[236] = A[26]; + A[41] = -0.00781249999999977*G0_1_0_0_0_0 - 0.00781249999999973*G0_1_0_0_0_1 + 0.182589285714288*G0_1_0_1_0_0 + 0.182589285714289*G0_1_0_2_0_1 - 0.149330357142861*G0_1_0_3_0_0 + 0.26651785714286*G0_1_0_3_0_1 + 0.266517857142861*G0_1_0_4_0_0 - 0.14933035714286*G0_1_0_4_0_1 + 0.0408482142857151*G0_1_0_5_0_0 + 0.0120535714285713*G0_1_0_5_0_1 - 0.266517857142862*G0_1_0_6_0_0 - 0.18683035714286*G0_1_0_6_0_1 + 0.0120535714285706*G0_1_0_7_0_0 + 0.0408482142857145*G0_1_0_7_0_1 - 0.186830357142859*G0_1_0_8_0_0 - 0.26651785714286*G0_1_0_8_0_1 + 0.108482142857146*G0_1_0_9_0_0 + 0.108482142857145*G0_1_0_9_0_1 - 0.00781249999999977*G0_1_0_10_1_0 - 0.00781249999999973*G0_1_0_10_1_1 + 0.182589285714288*G0_1_0_11_1_0 + 0.182589285714289*G0_1_0_12_1_1 - 0.149330357142861*G0_1_0_13_1_0 + 0.26651785714286*G0_1_0_13_1_1 + 0.266517857142861*G0_1_0_14_1_0 - 0.14933035714286*G0_1_0_14_1_1 + 0.0408482142857151*G0_1_0_15_1_0 + 0.0120535714285713*G0_1_0_15_1_1 - 0.266517857142862*G0_1_0_16_1_0 - 0.18683035714286*G0_1_0_16_1_1 + 0.0120535714285706*G0_1_0_17_1_0 + 0.0408482142857145*G0_1_0_17_1_1 - 0.186830357142859*G0_1_0_18_1_0 - 0.26651785714286*G0_1_0_18_1_1 + 0.108482142857146*G0_1_0_19_1_0 + 0.108482142857145*G0_1_0_19_1_1; + A[250] = -A[41] + 0.174776785714288*G0_1_0_0_0_0 + 0.174776785714288*G0_1_0_0_0_1 + 0.174776785714288*G0_1_0_1_0_0 - 0.108482142857146*G0_1_0_3_0_0 + 0.295312500000003*G0_1_0_3_0_1 - 0.229017857142861*G0_1_0_4_0_1 - 0.108482142857146*G0_1_0_5_0_0 - 0.403794642857149*G0_1_0_5_0_1 + 0.229017857142861*G0_1_0_6_0_1 - 0.174776785714288*G0_1_0_7_0_0 + 0.120535714285715*G0_1_0_7_0_1 - 0.174776785714288*G0_1_0_8_0_0 - 0.295312500000003*G0_1_0_8_0_1 + 0.216964285714291*G0_1_0_9_0_0 + 0.108482142857146*G0_1_0_9_0_1 + 0.174776785714288*G0_1_0_10_1_0 + 0.174776785714288*G0_1_0_10_1_1 + 0.174776785714288*G0_1_0_11_1_0 - 0.108482142857146*G0_1_0_13_1_0 + 0.295312500000003*G0_1_0_13_1_1 - 0.229017857142861*G0_1_0_14_1_1 - 0.108482142857146*G0_1_0_15_1_0 - 0.403794642857149*G0_1_0_15_1_1 + 0.229017857142861*G0_1_0_16_1_1 - 0.174776785714288*G0_1_0_17_1_0 + 0.120535714285715*G0_1_0_17_1_1 - 0.174776785714288*G0_1_0_18_1_0 - 0.295312500000003*G0_1_0_18_1_1 + 0.216964285714291*G0_1_0_19_1_0 + 0.108482142857146*G0_1_0_19_1_1 + 0.182589285714288*G0_1_1_0_0_0 + 0.182589285714288*G0_1_1_0_0_1 - 0.00781249999999973*G0_1_1_1_0_0 - 0.182589285714289*G0_1_1_2_0_1 + 0.0408482142857151*G0_1_1_3_0_0 + 0.0287946428571437*G0_1_1_3_0_1 - 0.266517857142862*G0_1_1_4_0_0 - 0.0796875000000014*G0_1_1_4_0_1 - 0.149330357142861*G0_1_1_5_0_0 - 0.415848214285721*G0_1_1_5_0_1 + 0.266517857142862*G0_1_1_6_0_0 + 0.415848214285722*G0_1_1_6_0_1 - 0.186830357142859*G0_1_1_7_0_0 + 0.079687500000001*G0_1_1_7_0_1 + 0.0120535714285707*G0_1_1_8_0_0 - 0.0287946428571436*G0_1_1_8_0_1 + 0.108482142857146*G0_1_1_9_0_0 + 0.182589285714288*G0_1_1_10_1_0 + 0.182589285714288*G0_1_1_10_1_1 - 0.00781249999999973*G0_1_1_11_1_0 - 0.182589285714289*G0_1_1_12_1_1 + 0.0408482142857151*G0_1_1_13_1_0 + 0.0287946428571437*G0_1_1_13_1_1 - 0.266517857142862*G0_1_1_14_1_0 - 0.0796875000000014*G0_1_1_14_1_1 - 0.149330357142861*G0_1_1_15_1_0 - 0.415848214285721*G0_1_1_15_1_1 + 0.266517857142862*G0_1_1_16_1_0 + 0.415848214285722*G0_1_1_16_1_1 - 0.186830357142859*G0_1_1_17_1_0 + 0.079687500000001*G0_1_1_17_1_1 + 0.0120535714285707*G0_1_1_18_1_0 - 0.0287946428571436*G0_1_1_18_1_1 + 0.108482142857146*G0_1_1_19_1_0; + A[142] = A[162] - 0.19888392857143*G0_0_1_0_0_0 - 0.19888392857143*G0_0_1_0_0_1 + 0.198883928571429*G0_0_1_1_0_0 + 0.198883928571424*G0_0_1_3_0_1 + 0.198883928571429*G0_0_1_5_0_1 + 0.596651785714296*G0_0_1_7_0_0 + 0.397767857142871*G0_0_1_7_0_1 - 0.596651785714295*G0_0_1_8_0_0 - 0.198883928571424*G0_0_1_8_0_1 - 0.397767857142876*G0_0_1_9_0_1 - 0.19888392857143*G0_0_1_10_1_0 - 0.19888392857143*G0_0_1_10_1_1 + 0.198883928571429*G0_0_1_11_1_0 + 0.198883928571424*G0_0_1_13_1_1 + 0.198883928571429*G0_0_1_15_1_1 + 0.596651785714296*G0_0_1_17_1_0 + 0.397767857142871*G0_0_1_17_1_1 - 0.596651785714295*G0_0_1_18_1_0 - 0.198883928571424*G0_0_1_18_1_1 - 0.397767857142876*G0_0_1_19_1_1 + 0.108482142857144*G0_1_1_0_0_0 + 0.108482142857145*G0_1_1_0_0_1 + 0.307366071428574*G0_1_1_1_0_0 - 0.126562500000004*G0_1_1_3_0_0 + 0.45200892857143*G0_1_1_3_0_1 - 0.271205357142857*G0_1_1_4_0_1 - 0.126562499999999*G0_1_1_5_0_0 - 0.379687500000005*G0_1_1_5_0_1 + 0.271205357142859*G0_1_1_6_0_1 + 0.0904017857142886*G0_1_1_7_0_0 + 0.343526785714294*G0_1_1_7_0_1 - 0.506250000000007*G0_1_1_8_0_0 - 0.45200892857143*G0_1_1_8_0_1 + 0.253125000000003*G0_1_1_9_0_0 - 0.0723214285714371*G0_1_1_9_0_1 + 0.108482142857144*G0_1_1_10_1_0 + 0.108482142857145*G0_1_1_10_1_1 + 0.307366071428574*G0_1_1_11_1_0 - 0.126562500000004*G0_1_1_13_1_0 + 0.45200892857143*G0_1_1_13_1_1 - 0.271205357142857*G0_1_1_14_1_1 - 0.126562499999999*G0_1_1_15_1_0 - 0.379687500000005*G0_1_1_15_1_1 + 0.271205357142859*G0_1_1_16_1_1 + 0.0904017857142886*G0_1_1_17_1_0 + 0.343526785714294*G0_1_1_17_1_1 - 0.506250000000007*G0_1_1_18_1_0 - 0.45200892857143*G0_1_1_18_1_1 + 0.253125000000003*G0_1_1_19_1_0 - 0.0723214285714371*G0_1_1_19_1_1; + A[387] = 0.0; + A[351] = A[81] - 0.444642857142864*G0_0_0_0_0_0 - 0.444642857142863*G0_0_0_0_0_1 + 0.649553571428577*G0_0_0_1_0_0 - 0.254464285714291*G0_0_0_2_0_1 + 0.879910714285724*G0_0_0_3_0_0 + 1.3138392857143*G0_0_0_3_0_1 - 0.602678571428582*G0_0_0_4_0_0 - 0.132589285714286*G0_0_0_4_0_1 - 0.229017857142859*G0_0_0_5_0_0 + 0.349553571428577*G0_0_0_5_0_1 + 0.602678571428582*G0_0_0_6_0_0 + 0.349553571428577*G0_0_0_6_0_1 + 1.1450892857143*G0_0_0_7_0_0 + 0.566517857142867*G0_0_0_7_0_1 - 1.35000000000002*G0_0_0_8_0_0 - 1.3138392857143*G0_0_0_8_0_1 - 0.650892857142865*G0_0_0_9_0_0 - 0.43392857142858*G0_0_0_9_0_1 - 0.444642857142864*G0_0_0_10_1_0 - 0.444642857142863*G0_0_0_10_1_1 + 0.649553571428577*G0_0_0_11_1_0 - 0.254464285714291*G0_0_0_12_1_1 + 0.879910714285724*G0_0_0_13_1_0 + 1.3138392857143*G0_0_0_13_1_1 - 0.602678571428582*G0_0_0_14_1_0 - 0.132589285714286*G0_0_0_14_1_1 - 0.229017857142859*G0_0_0_15_1_0 + 0.349553571428577*G0_0_0_15_1_1 + 0.602678571428582*G0_0_0_16_1_0 + 0.349553571428577*G0_0_0_16_1_1 + 1.1450892857143*G0_0_0_17_1_0 + 0.566517857142867*G0_0_0_17_1_1 - 1.35000000000002*G0_0_0_18_1_0 - 1.3138392857143*G0_0_0_18_1_1 - 0.650892857142865*G0_0_0_19_1_0 - 0.43392857142858*G0_0_0_19_1_1 - 0.190178571428575*G0_1_0_0_0_0 - 0.190178571428575*G0_1_0_0_0_1 + 1.29910714285715*G0_1_0_1_0_0 + 0.190178571428574*G0_1_0_2_0_1 + 0.843750000000002*G0_1_0_3_0_0 + 2.62767857142859*G0_1_0_3_0_1 - 0.0241071428571433*G0_1_0_4_0_0 - 0.699107142857152*G0_1_0_4_0_1 + 0.0241071428571456*G0_1_0_5_0_0 + 0.0241071428571435*G0_1_0_6_0_0 + 0.675000000000009*G0_1_0_7_0_0 + 0.699107142857151*G0_1_0_7_0_1 - 1.78392857142859*G0_1_0_8_0_0 - 2.62767857142859*G0_1_0_8_0_1 - 0.867857142857148*G0_1_0_9_0_0 - 0.190178571428575*G0_1_0_10_1_0 - 0.190178571428575*G0_1_0_10_1_1 + 1.29910714285715*G0_1_0_11_1_0 + 0.190178571428574*G0_1_0_12_1_1 + 0.843750000000002*G0_1_0_13_1_0 + 2.62767857142859*G0_1_0_13_1_1 - 0.0241071428571433*G0_1_0_14_1_0 - 0.699107142857152*G0_1_0_14_1_1 + 0.0241071428571456*G0_1_0_15_1_0 + 0.0241071428571435*G0_1_0_16_1_0 + 0.675000000000009*G0_1_0_17_1_0 + 0.699107142857151*G0_1_0_17_1_1 - 1.78392857142859*G0_1_0_18_1_0 - 2.62767857142859*G0_1_0_18_1_1 - 0.867857142857148*G0_1_0_19_1_0; + A[204] = 0.0; + A[229] = 0.0; + A[18] = 0.0; + A[286] = 0.0; + A[258] = A[48]; + A[39] = 0.0; + A[307] = 0.0; + A[279] = -A[379] + 0.723214285714303*G0_0_0_0_0_0 + 0.723214285714303*G0_0_0_0_0_1 - 0.289285714285732*G0_0_0_1_0_0 - 0.180803571428581*G0_0_0_2_0_1 - 1.84419642857141*G0_0_0_3_0_0 - 0.433928571428572*G0_0_0_3_0_1 - 2.49508928571434*G0_0_0_4_0_0 - 4.01383928571433*G0_0_0_4_0_1 + 1.84419642857148*G0_0_0_5_0_0 + 0.542410714285731*G0_0_0_5_0_1 + 2.49508928571434*G0_0_0_6_0_0 - 1.08482142857145*G0_0_0_6_0_1 - 1.84419642857148*G0_0_0_7_0_0 - 0.542410714285734*G0_0_0_7_0_1 + 1.41026785714291*G0_0_0_8_0_0 + 0.433928571428571*G0_0_0_8_0_1 + 4.55625000000006*G0_0_0_9_0_1 + 0.723214285714303*G0_0_0_10_1_0 + 0.723214285714303*G0_0_0_10_1_1 - 0.289285714285732*G0_0_0_11_1_0 - 0.180803571428581*G0_0_0_12_1_1 - 1.84419642857141*G0_0_0_13_1_0 - 0.433928571428572*G0_0_0_13_1_1 - 2.49508928571434*G0_0_0_14_1_0 - 4.01383928571433*G0_0_0_14_1_1 + 1.84419642857148*G0_0_0_15_1_0 + 0.542410714285731*G0_0_0_15_1_1 + 2.49508928571434*G0_0_0_16_1_0 - 1.08482142857145*G0_0_0_16_1_1 - 1.84419642857148*G0_0_0_17_1_0 - 0.542410714285734*G0_0_0_17_1_1 + 1.41026785714291*G0_0_0_18_1_0 + 0.433928571428571*G0_0_0_18_1_1 + 4.55625000000006*G0_0_0_19_1_1 + 0.542410714285724*G0_0_1_0_0_0 + 0.542410714285724*G0_0_1_0_0_1 + 0.542410714285724*G0_0_1_2_0_1 - 2.82053571428575*G0_0_1_3_0_0 - 1.19330357142859*G0_0_1_4_0_0 - 4.55625000000006*G0_0_1_4_0_1 - 1.73571428571431*G0_0_1_5_0_0 - 0.542410714285723*G0_0_1_5_0_1 + 1.19330357142859*G0_0_1_6_0_0 - 0.542410714285725*G0_0_1_6_0_1 - 3.36294642857149*G0_0_1_7_0_0 - 4.55625000000007*G0_0_1_7_0_1 + 2.82053571428577*G0_0_1_8_0_0 + 4.55625000000006*G0_0_1_9_0_0 + 9.11250000000014*G0_0_1_9_0_1 + 0.542410714285724*G0_0_1_10_1_0 + 0.542410714285724*G0_0_1_10_1_1 + 0.542410714285724*G0_0_1_12_1_1 - 2.82053571428575*G0_0_1_13_1_0 - 1.19330357142859*G0_0_1_14_1_0 - 4.55625000000006*G0_0_1_14_1_1 - 1.73571428571431*G0_0_1_15_1_0 - 0.542410714285723*G0_0_1_15_1_1 + 1.19330357142859*G0_0_1_16_1_0 - 0.542410714285725*G0_0_1_16_1_1 - 3.36294642857149*G0_0_1_17_1_0 - 4.55625000000007*G0_0_1_17_1_1 + 2.82053571428577*G0_0_1_18_1_0 + 4.55625000000006*G0_0_1_19_1_0 + 9.11250000000014*G0_0_1_19_1_1; + A[393] = A[279] - 0.325446428571439*G0_0_1_0_0_0 - 0.325446428571439*G0_0_1_0_0_1 - 1.08482142857143*G0_0_1_1_0_0 - 0.216964285714284*G0_0_1_2_0_1 + 1.84419642857147*G0_0_1_3_0_0 - 1.51874999999999*G0_0_1_3_0_1 + 0.867857142857158*G0_0_1_4_0_0 + 3.36294642857147*G0_0_1_4_0_1 + 1.41026785714288*G0_0_1_5_0_0 + 1.08482142857145*G0_0_1_5_0_1 - 0.867857142857158*G0_0_1_6_0_0 - 0.54241071428573*G0_0_1_6_0_1 + 0.867857142857164*G0_0_1_7_0_0 + 1.19330357142859*G0_0_1_7_0_1 + 0.542410714285704*G0_0_1_8_0_0 + 1.51874999999999*G0_0_1_8_0_1 - 3.25446428571436*G0_0_1_9_0_0 - 4.55625000000007*G0_0_1_9_0_1 - 0.325446428571439*G0_0_1_10_1_0 - 0.325446428571439*G0_0_1_10_1_1 - 1.08482142857143*G0_0_1_11_1_0 - 0.216964285714284*G0_0_1_12_1_1 + 1.84419642857147*G0_0_1_13_1_0 - 1.51874999999999*G0_0_1_13_1_1 + 0.867857142857158*G0_0_1_14_1_0 + 3.36294642857147*G0_0_1_14_1_1 + 1.41026785714288*G0_0_1_15_1_0 + 1.08482142857145*G0_0_1_15_1_1 - 0.867857142857158*G0_0_1_16_1_0 - 0.54241071428573*G0_0_1_16_1_1 + 0.867857142857164*G0_0_1_17_1_0 + 1.19330357142859*G0_0_1_17_1_1 + 0.542410714285704*G0_0_1_18_1_0 + 1.51874999999999*G0_0_1_18_1_1 - 3.25446428571436*G0_0_1_19_1_0 - 4.55625000000007*G0_0_1_19_1_1 + 0.325446428571439*G0_1_0_0_0_0 + 0.325446428571439*G0_1_0_0_0_1 + 1.08482142857143*G0_1_0_1_0_0 + 0.216964285714284*G0_1_0_2_0_1 - 1.84419642857147*G0_1_0_3_0_0 + 1.51874999999999*G0_1_0_3_0_1 - 0.867857142857158*G0_1_0_4_0_0 - 3.36294642857147*G0_1_0_4_0_1 - 1.41026785714288*G0_1_0_5_0_0 - 1.08482142857145*G0_1_0_5_0_1 + 0.867857142857158*G0_1_0_6_0_0 + 0.54241071428573*G0_1_0_6_0_1 - 0.867857142857164*G0_1_0_7_0_0 - 1.19330357142859*G0_1_0_7_0_1 - 0.542410714285704*G0_1_0_8_0_0 - 1.51874999999999*G0_1_0_8_0_1 + 3.25446428571436*G0_1_0_9_0_0 + 4.55625000000007*G0_1_0_9_0_1 + 0.325446428571439*G0_1_0_10_1_0 + 0.325446428571439*G0_1_0_10_1_1 + 1.08482142857143*G0_1_0_11_1_0 + 0.216964285714284*G0_1_0_12_1_1 - 1.84419642857147*G0_1_0_13_1_0 + 1.51874999999999*G0_1_0_13_1_1 - 0.867857142857158*G0_1_0_14_1_0 - 3.36294642857147*G0_1_0_14_1_1 - 1.41026785714288*G0_1_0_15_1_0 - 1.08482142857145*G0_1_0_15_1_1 + 0.867857142857158*G0_1_0_16_1_0 + 0.54241071428573*G0_1_0_16_1_1 - 0.867857142857164*G0_1_0_17_1_0 - 1.19330357142859*G0_1_0_17_1_1 - 0.542410714285704*G0_1_0_18_1_0 - 1.51874999999999*G0_1_0_18_1_1 + 3.25446428571436*G0_1_0_19_1_0 + 4.55625000000007*G0_1_0_19_1_1; + A[398] = -A[393] + 0.723214285714303*G0_0_0_0_0_0 + 0.723214285714304*G0_0_0_0_0_1 - 0.289285714285732*G0_0_0_1_0_0 - 0.180803571428581*G0_0_0_2_0_1 - 1.84419642857141*G0_0_0_3_0_0 - 0.433928571428572*G0_0_0_3_0_1 - 2.49508928571434*G0_0_0_4_0_0 - 4.01383928571433*G0_0_0_4_0_1 + 1.84419642857148*G0_0_0_5_0_0 + 0.542410714285731*G0_0_0_5_0_1 + 2.49508928571434*G0_0_0_6_0_0 - 1.08482142857145*G0_0_0_6_0_1 - 1.84419642857148*G0_0_0_7_0_0 - 0.542410714285735*G0_0_0_7_0_1 + 1.41026785714292*G0_0_0_8_0_0 + 0.433928571428571*G0_0_0_8_0_1 + 4.55625000000006*G0_0_0_9_0_1 + 0.723214285714303*G0_0_0_10_1_0 + 0.723214285714304*G0_0_0_10_1_1 - 0.289285714285732*G0_0_0_11_1_0 - 0.180803571428581*G0_0_0_12_1_1 - 1.84419642857141*G0_0_0_13_1_0 - 0.433928571428572*G0_0_0_13_1_1 - 2.49508928571434*G0_0_0_14_1_0 - 4.01383928571433*G0_0_0_14_1_1 + 1.84419642857148*G0_0_0_15_1_0 + 0.542410714285731*G0_0_0_15_1_1 + 2.49508928571434*G0_0_0_16_1_0 - 1.08482142857145*G0_0_0_16_1_1 - 1.84419642857148*G0_0_0_17_1_0 - 0.542410714285735*G0_0_0_17_1_1 + 1.41026785714292*G0_0_0_18_1_0 + 0.433928571428571*G0_0_0_18_1_1 + 4.55625000000006*G0_0_0_19_1_1 + 0.542410714285724*G0_1_0_0_0_0 + 0.542410714285724*G0_1_0_0_0_1 + 0.542410714285724*G0_1_0_2_0_1 - 2.82053571428575*G0_1_0_3_0_0 - 1.19330357142859*G0_1_0_4_0_0 - 4.55625000000006*G0_1_0_4_0_1 - 1.73571428571431*G0_1_0_5_0_0 - 0.542410714285723*G0_1_0_5_0_1 + 1.19330357142859*G0_1_0_6_0_0 - 0.542410714285725*G0_1_0_6_0_1 - 3.36294642857149*G0_1_0_7_0_0 - 4.55625000000007*G0_1_0_7_0_1 + 2.82053571428577*G0_1_0_8_0_0 + 4.55625000000006*G0_1_0_9_0_0 + 9.11250000000014*G0_1_0_9_0_1 + 0.542410714285724*G0_1_0_10_1_0 + 0.542410714285724*G0_1_0_10_1_1 + 0.542410714285724*G0_1_0_12_1_1 - 2.82053571428575*G0_1_0_13_1_0 - 1.19330357142859*G0_1_0_14_1_0 - 4.55625000000006*G0_1_0_14_1_1 - 1.73571428571431*G0_1_0_15_1_0 - 0.542410714285723*G0_1_0_15_1_1 + 1.19330357142859*G0_1_0_16_1_0 - 0.542410714285725*G0_1_0_16_1_1 - 3.36294642857149*G0_1_0_17_1_0 - 4.55625000000007*G0_1_0_17_1_1 + 2.82053571428577*G0_1_0_18_1_0 + 4.55625000000006*G0_1_0_19_1_0 + 9.11250000000014*G0_1_0_19_1_1; + A[149] = A[398] - 0.650892857142856*G0_0_0_0_0_0 - 0.650892857142857*G0_0_0_0_0_1 - 0.650892857142854*G0_0_0_1_0_0 - 3.90535714285725*G0_0_0_3_0_0 - 3.25446428571433*G0_0_0_3_0_1 - 1.30178571428578*G0_0_0_4_0_1 - 3.90535714285725*G0_0_0_5_0_0 - 0.650892857142912*G0_0_0_5_0_1 + 1.30178571428577*G0_0_0_6_0_1 + 0.650892857142858*G0_0_0_7_0_0 - 2.60357142857148*G0_0_0_7_0_1 + 0.650892857142853*G0_0_0_8_0_0 + 3.25446428571433*G0_0_0_8_0_1 + 7.8107142857145*G0_0_0_9_0_0 + 3.90535714285725*G0_0_0_9_0_1 - 0.650892857142856*G0_0_0_10_1_0 - 0.650892857142857*G0_0_0_10_1_1 - 0.650892857142854*G0_0_0_11_1_0 - 3.90535714285725*G0_0_0_13_1_0 - 3.25446428571433*G0_0_0_13_1_1 - 1.30178571428578*G0_0_0_14_1_1 - 3.90535714285725*G0_0_0_15_1_0 - 0.650892857142912*G0_0_0_15_1_1 + 1.30178571428577*G0_0_0_16_1_1 + 0.650892857142858*G0_0_0_17_1_0 - 2.60357142857148*G0_0_0_17_1_1 + 0.650892857142853*G0_0_0_18_1_0 + 3.25446428571433*G0_0_0_18_1_1 + 7.8107142857145*G0_0_0_19_1_0 + 3.90535714285725*G0_0_0_19_1_1 - 0.0361607142857027*G0_0_1_0_0_0 - 0.0361607142857028*G0_0_1_0_0_1 - 1.4825892857143*G0_0_1_1_0_0 - 0.0723214285714363*G0_0_1_2_0_1 - 4.55625000000007*G0_0_1_3_0_0 - 5.09866071428577*G0_0_1_3_0_1 - 0.867857142857174*G0_0_1_4_0_1 - 0.650892857142887*G0_0_1_5_0_0 - 0.108482142857177*G0_0_1_5_0_1 + 0.216964285714315*G0_0_1_6_0_1 + 0.759374999999993*G0_0_1_7_0_0 + 0.216964285714283*G0_0_1_7_0_1 + 0.759375000000011*G0_0_1_8_0_0 + 5.09866071428577*G0_0_1_8_0_1 + 5.20714285714296*G0_0_1_9_0_0 + 0.650892857142889*G0_0_1_9_0_1 - 0.0361607142857027*G0_0_1_10_1_0 - 0.0361607142857028*G0_0_1_10_1_1 - 1.4825892857143*G0_0_1_11_1_0 - 0.0723214285714363*G0_0_1_12_1_1 - 4.55625000000007*G0_0_1_13_1_0 - 5.09866071428577*G0_0_1_13_1_1 - 0.867857142857174*G0_0_1_14_1_1 - 0.650892857142887*G0_0_1_15_1_0 - 0.108482142857177*G0_0_1_15_1_1 + 0.216964285714315*G0_0_1_16_1_1 + 0.759374999999993*G0_0_1_17_1_0 + 0.216964285714283*G0_0_1_17_1_1 + 0.759375000000011*G0_0_1_18_1_0 + 5.09866071428577*G0_0_1_18_1_1 + 5.20714285714296*G0_0_1_19_1_0 + 0.650892857142889*G0_0_1_19_1_1 + 0.831696428571447*G0_1_0_0_0_0 + 0.831696428571447*G0_1_0_0_0_1 - 0.614732142857154*G0_1_0_1_0_0 - 0.0723214285714365*G0_1_0_2_0_1 - 3.25446428571436*G0_1_0_3_0_0 - 2.71205357142863*G0_1_0_3_0_1 - 1.08482142857147*G0_1_0_4_0_1 + 0.650892857142824*G0_1_0_5_0_0 - 1.19330357142862*G0_1_0_5_0_1 + 0.43392857142861*G0_1_0_6_0_1 - 0.108482142857156*G0_1_0_7_0_0 + 1.73571428571429*G0_1_0_7_0_1 - 0.108482142857138*G0_1_0_8_0_0 + 2.71205357142863*G0_1_0_8_0_1 + 2.60357142857154*G0_1_0_9_0_0 - 0.650892857142822*G0_1_0_9_0_1 + 0.831696428571447*G0_1_0_10_1_0 + 0.831696428571447*G0_1_0_10_1_1 - 0.614732142857154*G0_1_0_11_1_0 - 0.0723214285714365*G0_1_0_12_1_1 - 3.25446428571436*G0_1_0_13_1_0 - 2.71205357142863*G0_1_0_13_1_1 - 1.08482142857147*G0_1_0_14_1_1 + 0.650892857142824*G0_1_0_15_1_0 - 1.19330357142862*G0_1_0_15_1_1 + 0.43392857142861*G0_1_0_16_1_1 - 0.108482142857156*G0_1_0_17_1_0 + 1.73571428571429*G0_1_0_17_1_1 - 0.108482142857138*G0_1_0_18_1_0 + 2.71205357142863*G0_1_0_18_1_1 + 2.60357142857154*G0_1_0_19_1_0 - 0.650892857142822*G0_1_0_19_1_1 + 1.37410714285717*G0_1_1_0_0_0 + 1.37410714285717*G0_1_1_0_0_1 - 0.0723214285714328*G0_1_1_1_0_0 - 0.0723214285714371*G0_1_1_2_0_1 - 3.90535714285721*G0_1_1_3_0_0 - 1.95267857142861*G0_1_1_3_0_1 - 1.95267857142861*G0_1_1_4_0_1 - 2.60357142857149*G0_1_1_5_0_1 + 1.30178571428576*G0_1_1_6_0_1 - 0.650892857142878*G0_1_1_7_0_0 + 1.95267857142858*G0_1_1_7_0_1 - 0.650892857142858*G0_1_1_8_0_0 + 1.95267857142861*G0_1_1_8_0_1 + 3.90535714285725*G0_1_1_9_0_0 + 1.37410714285717*G0_1_1_10_1_0 + 1.37410714285717*G0_1_1_10_1_1 - 0.0723214285714328*G0_1_1_11_1_0 - 0.0723214285714371*G0_1_1_12_1_1 - 3.90535714285721*G0_1_1_13_1_0 - 1.95267857142861*G0_1_1_13_1_1 - 1.95267857142861*G0_1_1_14_1_1 - 2.60357142857149*G0_1_1_15_1_1 + 1.30178571428576*G0_1_1_16_1_1 - 0.650892857142878*G0_1_1_17_1_0 + 1.95267857142858*G0_1_1_17_1_1 - 0.650892857142858*G0_1_1_18_1_0 + 1.95267857142861*G0_1_1_18_1_1 + 3.90535714285725*G0_1_1_19_1_0; + A[183] = A[393]; + A[397] = A[149] + 1.08482142857143*G0_0_1_0_0_0 + 1.08482142857143*G0_0_1_0_0_1 - 0.216964285714285*G0_0_1_1_0_0 + 0.325446428571439*G0_0_1_2_0_1 + 0.32544642857143*G0_0_1_3_0_0 + 0.867857142857162*G0_0_1_3_0_1 - 0.325446428571427*G0_0_1_4_0_0 - 1.41026785714288*G0_0_1_4_0_1 + 0.976339285714284*G0_0_1_5_0_0 - 0.542410714285712*G0_0_1_5_0_1 + 0.325446428571427*G0_0_1_6_0_0 - 0.867857142857162*G0_0_1_6_0_1 - 3.36294642857147*G0_0_1_7_0_0 - 1.84419642857148*G0_0_1_7_0_1 + 2.49508928571432*G0_0_1_8_0_0 - 0.867857142857161*G0_0_1_8_0_1 - 1.30178571428571*G0_0_1_9_0_0 + 3.25446428571436*G0_0_1_9_0_1 + 1.08482142857143*G0_0_1_10_1_0 + 1.08482142857143*G0_0_1_10_1_1 - 0.216964285714285*G0_0_1_11_1_0 + 0.325446428571439*G0_0_1_12_1_1 + 0.32544642857143*G0_0_1_13_1_0 + 0.867857142857162*G0_0_1_13_1_1 - 0.325446428571427*G0_0_1_14_1_0 - 1.41026785714288*G0_0_1_14_1_1 + 0.976339285714284*G0_0_1_15_1_0 - 0.542410714285712*G0_0_1_15_1_1 + 0.325446428571427*G0_0_1_16_1_0 - 0.867857142857162*G0_0_1_16_1_1 - 3.36294642857147*G0_0_1_17_1_0 - 1.84419642857148*G0_0_1_17_1_1 + 2.49508928571432*G0_0_1_18_1_0 - 0.867857142857161*G0_0_1_18_1_1 - 1.30178571428571*G0_0_1_19_1_0 + 3.25446428571436*G0_0_1_19_1_1 - 1.08482142857143*G0_1_0_0_0_0 - 1.08482142857143*G0_1_0_0_0_1 + 0.216964285714285*G0_1_0_1_0_0 - 0.325446428571439*G0_1_0_2_0_1 - 0.325446428571431*G0_1_0_3_0_0 - 0.867857142857162*G0_1_0_3_0_1 + 0.325446428571427*G0_1_0_4_0_0 + 1.41026785714288*G0_1_0_4_0_1 - 0.976339285714284*G0_1_0_5_0_0 + 0.542410714285712*G0_1_0_5_0_1 - 0.325446428571427*G0_1_0_6_0_0 + 0.867857142857162*G0_1_0_6_0_1 + 3.36294642857147*G0_1_0_7_0_0 + 1.84419642857148*G0_1_0_7_0_1 - 2.49508928571432*G0_1_0_8_0_0 + 0.867857142857162*G0_1_0_8_0_1 + 1.30178571428571*G0_1_0_9_0_0 - 3.25446428571436*G0_1_0_9_0_1 - 1.08482142857143*G0_1_0_10_1_0 - 1.08482142857143*G0_1_0_10_1_1 + 0.216964285714285*G0_1_0_11_1_0 - 0.325446428571439*G0_1_0_12_1_1 - 0.325446428571431*G0_1_0_13_1_0 - 0.867857142857162*G0_1_0_13_1_1 + 0.325446428571427*G0_1_0_14_1_0 + 1.41026785714288*G0_1_0_14_1_1 - 0.976339285714284*G0_1_0_15_1_0 + 0.542410714285712*G0_1_0_15_1_1 - 0.325446428571427*G0_1_0_16_1_0 + 0.867857142857162*G0_1_0_16_1_1 + 3.36294642857147*G0_1_0_17_1_0 + 1.84419642857148*G0_1_0_17_1_1 - 2.49508928571432*G0_1_0_18_1_0 + 0.867857142857162*G0_1_0_18_1_1 + 1.30178571428571*G0_1_0_19_1_0 - 3.25446428571436*G0_1_0_19_1_1; + A[187] = A[397]; + A[8] = A[218]; + A[107] = A[145] + 1.84419642857145*G0_0_1_0_0_0 + 1.84419642857145*G0_0_1_0_0_1 - 0.32544642857143*G0_0_1_1_0_0 - 0.32544642857143*G0_0_1_2_0_1 + 0.108482142857142*G0_0_1_3_0_0 + 0.108482142857144*G0_0_1_3_0_1 + 0.108482142857146*G0_0_1_4_0_0 + 0.108482142857142*G0_0_1_4_0_1 - 0.542410714285715*G0_0_1_5_0_0 - 3.25446428571431*G0_0_1_5_0_1 - 0.108482142857146*G0_0_1_6_0_0 + 1.7357142857143*G0_0_1_6_0_1 - 3.25446428571431*G0_0_1_7_0_0 - 0.542410714285718*G0_0_1_7_0_1 + 1.7357142857143*G0_0_1_8_0_0 - 0.108482142857143*G0_0_1_8_0_1 + 0.433928571428574*G0_0_1_9_0_0 + 0.433928571428574*G0_0_1_9_0_1 + 1.84419642857145*G0_0_1_10_1_0 + 1.84419642857145*G0_0_1_10_1_1 - 0.32544642857143*G0_0_1_11_1_0 - 0.32544642857143*G0_0_1_12_1_1 + 0.108482142857142*G0_0_1_13_1_0 + 0.108482142857144*G0_0_1_13_1_1 + 0.108482142857146*G0_0_1_14_1_0 + 0.108482142857142*G0_0_1_14_1_1 - 0.542410714285715*G0_0_1_15_1_0 - 3.25446428571431*G0_0_1_15_1_1 - 0.108482142857146*G0_0_1_16_1_0 + 1.7357142857143*G0_0_1_16_1_1 - 3.25446428571431*G0_0_1_17_1_0 - 0.542410714285718*G0_0_1_17_1_1 + 1.7357142857143*G0_0_1_18_1_0 - 0.108482142857143*G0_0_1_18_1_1 + 0.433928571428574*G0_0_1_19_1_0 + 0.433928571428574*G0_0_1_19_1_1 - 1.84419642857145*G0_1_0_0_0_0 - 1.84419642857145*G0_1_0_0_0_1 + 0.32544642857143*G0_1_0_1_0_0 + 0.32544642857143*G0_1_0_2_0_1 - 0.108482142857142*G0_1_0_3_0_0 - 0.108482142857144*G0_1_0_3_0_1 - 0.108482142857146*G0_1_0_4_0_0 - 0.108482142857142*G0_1_0_4_0_1 + 0.542410714285715*G0_1_0_5_0_0 + 3.25446428571431*G0_1_0_5_0_1 + 0.108482142857145*G0_1_0_6_0_0 - 1.7357142857143*G0_1_0_6_0_1 + 3.25446428571431*G0_1_0_7_0_0 + 0.542410714285718*G0_1_0_7_0_1 - 1.7357142857143*G0_1_0_8_0_0 + 0.108482142857143*G0_1_0_8_0_1 - 0.433928571428574*G0_1_0_9_0_0 - 0.433928571428574*G0_1_0_9_0_1 - 1.84419642857145*G0_1_0_10_1_0 - 1.84419642857145*G0_1_0_10_1_1 + 0.32544642857143*G0_1_0_11_1_0 + 0.32544642857143*G0_1_0_12_1_1 - 0.108482142857142*G0_1_0_13_1_0 - 0.108482142857144*G0_1_0_13_1_1 - 0.108482142857146*G0_1_0_14_1_0 - 0.108482142857142*G0_1_0_14_1_1 + 0.542410714285715*G0_1_0_15_1_0 + 3.25446428571431*G0_1_0_15_1_1 + 0.108482142857145*G0_1_0_16_1_0 - 1.7357142857143*G0_1_0_16_1_1 + 3.25446428571431*G0_1_0_17_1_0 + 0.542410714285718*G0_1_0_17_1_1 - 1.7357142857143*G0_1_0_18_1_0 + 0.108482142857143*G0_1_0_18_1_1 - 0.433928571428574*G0_1_0_19_1_0 - 0.433928571428574*G0_1_0_19_1_1; + A[321] = 0.0; + A[392] = A[259] + 0.108482142857146*G0_0_1_0_0_0 + 0.108482142857146*G0_0_1_0_0_1 + 0.108482142857146*G0_0_1_1_0_0 - 0.072321428571435*G0_0_1_3_0_0 + 0.180803571428574*G0_0_1_3_0_1 - 0.144642857142864*G0_0_1_4_0_1 - 0.0723214285714339*G0_0_1_5_0_0 - 0.253125000000008*G0_0_1_5_0_1 + 0.144642857142862*G0_0_1_6_0_1 - 0.108482142857146*G0_0_1_7_0_0 + 0.0723214285714288*G0_0_1_7_0_1 - 0.108482142857146*G0_0_1_8_0_0 - 0.180803571428574*G0_0_1_8_0_1 + 0.144642857142869*G0_0_1_9_0_0 + 0.0723214285714354*G0_0_1_9_0_1 + 0.108482142857146*G0_0_1_10_1_0 + 0.108482142857146*G0_0_1_10_1_1 + 0.108482142857146*G0_0_1_11_1_0 - 0.072321428571435*G0_0_1_13_1_0 + 0.180803571428574*G0_0_1_13_1_1 - 0.144642857142864*G0_0_1_14_1_1 - 0.0723214285714339*G0_0_1_15_1_0 - 0.253125000000008*G0_0_1_15_1_1 + 0.144642857142862*G0_0_1_16_1_1 - 0.108482142857146*G0_0_1_17_1_0 + 0.0723214285714288*G0_0_1_17_1_1 - 0.108482142857146*G0_0_1_18_1_0 - 0.180803571428574*G0_0_1_18_1_1 + 0.144642857142869*G0_0_1_19_1_0 + 0.0723214285714354*G0_0_1_19_1_1 - 0.108482142857146*G0_1_0_0_0_0 - 0.108482142857146*G0_1_0_0_0_1 - 0.108482142857146*G0_1_0_1_0_0 + 0.072321428571435*G0_1_0_3_0_0 - 0.180803571428574*G0_1_0_3_0_1 + 0.144642857142864*G0_1_0_4_0_1 + 0.0723214285714339*G0_1_0_5_0_0 + 0.253125000000008*G0_1_0_5_0_1 - 0.144642857142862*G0_1_0_6_0_1 + 0.108482142857146*G0_1_0_7_0_0 - 0.0723214285714288*G0_1_0_7_0_1 + 0.108482142857146*G0_1_0_8_0_0 + 0.180803571428574*G0_1_0_8_0_1 - 0.144642857142869*G0_1_0_9_0_0 - 0.0723214285714354*G0_1_0_9_0_1 - 0.108482142857146*G0_1_0_10_1_0 - 0.108482142857146*G0_1_0_10_1_1 - 0.108482142857146*G0_1_0_11_1_0 + 0.072321428571435*G0_1_0_13_1_0 - 0.180803571428574*G0_1_0_13_1_1 + 0.144642857142864*G0_1_0_14_1_1 + 0.0723214285714339*G0_1_0_15_1_0 + 0.253125000000008*G0_1_0_15_1_1 - 0.144642857142862*G0_1_0_16_1_1 + 0.108482142857146*G0_1_0_17_1_0 - 0.0723214285714288*G0_1_0_17_1_1 + 0.108482142857146*G0_1_0_18_1_0 + 0.180803571428574*G0_1_0_18_1_1 - 0.144642857142869*G0_1_0_19_1_0 - 0.0723214285714354*G0_1_0_19_1_1; + A[352] = A[142]; + A[157] = 0.0; + A[371] = -A[271] + 0.336160714285719*G0_0_0_0_0_0 + 0.336160714285719*G0_0_0_0_0_1 - 1.1075892857143*G0_0_0_1_0_0 - 0.33616071428572*G0_0_0_2_0_1 - 0.15669642857142*G0_0_0_3_0_0 - 1.84419642857144*G0_0_0_3_0_1 - 0.445982142857151*G0_0_0_4_0_0 + 0.470089285714293*G0_0_0_4_0_1 + 0.445982142857152*G0_0_0_5_0_0 + 0.445982142857151*G0_0_0_6_0_0 - 0.916071428571443*G0_0_0_7_0_0 - 0.470089285714292*G0_0_0_7_0_1 + 1.68750000000002*G0_0_0_8_0_0 + 1.84419642857145*G0_0_0_8_0_1 - 0.289285714285732*G0_0_0_9_0_0 + 0.336160714285719*G0_0_0_10_1_0 + 0.336160714285719*G0_0_0_10_1_1 - 1.1075892857143*G0_0_0_11_1_0 - 0.33616071428572*G0_0_0_12_1_1 - 0.15669642857142*G0_0_0_13_1_0 - 1.84419642857144*G0_0_0_13_1_1 - 0.445982142857151*G0_0_0_14_1_0 + 0.470089285714293*G0_0_0_14_1_1 + 0.445982142857152*G0_0_0_15_1_0 + 0.445982142857151*G0_0_0_16_1_0 - 0.916071428571443*G0_0_0_17_1_0 - 0.470089285714292*G0_0_0_17_1_1 + 1.68750000000002*G0_0_0_18_1_0 + 1.84419642857145*G0_0_0_18_1_1 - 0.289285714285732*G0_0_0_19_1_0; + A[173] = 0.0; + A[188] = A[398]; + A[179] = 0.0; + A[234] = A[24]; + A[198] = 0.0; + A[289] = 0.0; + A[249] = 0.0; + A[312] = A[102]; + A[272] = A[62]; + A[59] = 0.0; + A[15] = 0.0; + A[70] = 0.0; + A[34] = 0.0; + A[93] = 0.0; + A[53] = 0.0; + A[76] = 0.0; + A[135] = 0.0; + A[345] = 0.0; + A[154] = 0.0; + A[362] = 0.0; + A[227] = 0.0; + A[240] = 0.0; + A[265] = 0.0; + A[27] = A[24] - 0.444642857142864*G0_0_0_0_0_0 - 0.444642857142863*G0_0_0_0_0_1 + 0.649553571428577*G0_0_0_1_0_0 - 0.254464285714291*G0_0_0_2_0_1 + 0.879910714285724*G0_0_0_3_0_0 + 1.3138392857143*G0_0_0_3_0_1 - 0.602678571428582*G0_0_0_4_0_0 - 0.132589285714286*G0_0_0_4_0_1 - 0.229017857142859*G0_0_0_5_0_0 + 0.349553571428577*G0_0_0_5_0_1 + 0.602678571428582*G0_0_0_6_0_0 + 0.349553571428577*G0_0_0_6_0_1 + 1.1450892857143*G0_0_0_7_0_0 + 0.566517857142867*G0_0_0_7_0_1 - 1.35000000000002*G0_0_0_8_0_0 - 1.3138392857143*G0_0_0_8_0_1 - 0.650892857142865*G0_0_0_9_0_0 - 0.43392857142858*G0_0_0_9_0_1 - 0.444642857142864*G0_0_0_10_1_0 - 0.444642857142863*G0_0_0_10_1_1 + 0.649553571428577*G0_0_0_11_1_0 - 0.254464285714291*G0_0_0_12_1_1 + 0.879910714285724*G0_0_0_13_1_0 + 1.3138392857143*G0_0_0_13_1_1 - 0.602678571428582*G0_0_0_14_1_0 - 0.132589285714286*G0_0_0_14_1_1 - 0.229017857142859*G0_0_0_15_1_0 + 0.349553571428577*G0_0_0_15_1_1 + 0.602678571428582*G0_0_0_16_1_0 + 0.349553571428577*G0_0_0_16_1_1 + 1.1450892857143*G0_0_0_17_1_0 + 0.566517857142867*G0_0_0_17_1_1 - 1.35000000000002*G0_0_0_18_1_0 - 1.3138392857143*G0_0_0_18_1_1 - 0.650892857142865*G0_0_0_19_1_0 - 0.43392857142858*G0_0_0_19_1_1 - 0.190178571428575*G0_0_1_0_0_0 - 0.190178571428575*G0_0_1_0_0_1 + 1.29910714285715*G0_0_1_1_0_0 + 0.190178571428574*G0_0_1_2_0_1 + 0.843750000000002*G0_0_1_3_0_0 + 2.62767857142859*G0_0_1_3_0_1 - 0.0241071428571433*G0_0_1_4_0_0 - 0.699107142857152*G0_0_1_4_0_1 + 0.0241071428571456*G0_0_1_5_0_0 + 0.0241071428571435*G0_0_1_6_0_0 + 0.675000000000009*G0_0_1_7_0_0 + 0.699107142857151*G0_0_1_7_0_1 - 1.78392857142859*G0_0_1_8_0_0 - 2.62767857142859*G0_0_1_8_0_1 - 0.867857142857148*G0_0_1_9_0_0 - 0.190178571428575*G0_0_1_10_1_0 - 0.190178571428575*G0_0_1_10_1_1 + 1.29910714285715*G0_0_1_11_1_0 + 0.190178571428574*G0_0_1_12_1_1 + 0.843750000000002*G0_0_1_13_1_0 + 2.62767857142859*G0_0_1_13_1_1 - 0.0241071428571433*G0_0_1_14_1_0 - 0.699107142857152*G0_0_1_14_1_1 + 0.0241071428571456*G0_0_1_15_1_0 + 0.0241071428571435*G0_0_1_16_1_0 + 0.675000000000009*G0_0_1_17_1_0 + 0.699107142857151*G0_0_1_17_1_1 - 1.78392857142859*G0_0_1_18_1_0 - 2.62767857142859*G0_0_1_18_1_1 - 0.867857142857148*G0_0_1_19_1_0; + A[44] = -A[256] + 0.33616071428572*G0_1_1_0_0_0 + 0.33616071428572*G0_1_1_0_0_1 - 0.33616071428572*G0_1_1_1_0_0 - 1.1075892857143*G0_1_1_2_0_1 + 0.470089285714298*G0_1_1_3_0_0 - 0.44598214285715*G0_1_1_3_0_1 - 1.84419642857145*G0_1_1_4_0_0 - 0.156696428571424*G0_1_1_4_0_1 - 0.470089285714296*G0_1_1_5_0_0 - 0.916071428571446*G0_1_1_5_0_1 + 1.84419642857145*G0_1_1_6_0_0 + 1.68750000000003*G0_1_1_6_0_1 + 0.445982142857152*G0_1_1_7_0_1 + 0.445982142857151*G0_1_1_8_0_1 - 0.289285714285729*G0_1_1_9_0_1 + 0.33616071428572*G0_1_1_10_1_0 + 0.33616071428572*G0_1_1_10_1_1 - 0.33616071428572*G0_1_1_11_1_0 - 1.1075892857143*G0_1_1_12_1_1 + 0.470089285714298*G0_1_1_13_1_0 - 0.44598214285715*G0_1_1_13_1_1 - 1.84419642857145*G0_1_1_14_1_0 - 0.156696428571424*G0_1_1_14_1_1 - 0.470089285714296*G0_1_1_15_1_0 - 0.916071428571446*G0_1_1_15_1_1 + 1.84419642857145*G0_1_1_16_1_0 + 1.68750000000003*G0_1_1_16_1_1 + 0.445982142857152*G0_1_1_17_1_1 + 0.445982142857151*G0_1_1_18_1_1 - 0.289285714285729*G0_1_1_19_1_1; + A[109] = A[319]; + A[98] = 0.0; + A[119] = 0.0; + A[380] = 0.0; + A[161] = A[371]; + A[238] = A[28]; + A[332] = A[122]; + A[139] = 0.0; + A[389] = 0.0; + A[349] = 0.0; + A[185] = A[395]; + A[202] = 0.0; + A[231] = A[21]; + A[284] = 0.0; + A[252] = -0.182589285714289*G0_1_1_0_0_0 - 0.182589285714289*G0_1_1_0_0_1 + 0.182589285714289*G0_1_1_1_0_0 + 1.07455357142858*G0_1_1_2_0_1 - 0.64955357142858*G0_1_1_3_0_0 + 0.0254464285714305*G0_1_1_3_0_1 + 2.02633928571431*G0_1_1_4_0_0 + 0.459375000000002*G0_1_1_4_0_1 + 0.64955357142858*G0_1_1_5_0_0 + 0.67500000000001*G0_1_1_5_0_1 - 2.02633928571431*G0_1_1_6_0_0 - 1.56696428571431*G0_1_1_6_0_1 - 0.0254464285714294*G0_1_1_7_0_1 - 0.0254464285714305*G0_1_1_8_0_1 - 0.433928571428573*G0_1_1_9_0_1 - 0.182589285714289*G0_1_1_10_1_0 - 0.182589285714289*G0_1_1_10_1_1 + 0.182589285714289*G0_1_1_11_1_0 + 1.07455357142858*G0_1_1_12_1_1 - 0.64955357142858*G0_1_1_13_1_0 + 0.0254464285714305*G0_1_1_13_1_1 + 2.02633928571431*G0_1_1_14_1_0 + 0.459375000000002*G0_1_1_14_1_1 + 0.64955357142858*G0_1_1_15_1_0 + 0.67500000000001*G0_1_1_15_1_1 - 2.02633928571431*G0_1_1_16_1_0 - 1.56696428571431*G0_1_1_16_1_1 - 0.0254464285714294*G0_1_1_17_1_1 - 0.0254464285714305*G0_1_1_18_1_1 - 0.433928571428573*G0_1_1_19_1_1; + A[37] = 0.0; + A[301] = 0.0; + A[277] = A[143] - 0.0542410714285714*G0_0_1_0_0_0 - 0.0542410714285717*G0_0_1_0_0_1 - 0.650892857142863*G0_0_1_1_0_0 + 0.271205357142872*G0_0_1_3_0_0 - 0.976339285714286*G0_0_1_3_0_1 + 0.216964285714291*G0_0_1_4_0_0 + 0.813616071428584*G0_0_1_4_0_1 + 0.271205357142862*G0_0_1_5_0_0 + 0.433928571428578*G0_0_1_5_0_1 - 0.216964285714291*G0_0_1_6_0_0 - 0.379687500000007*G0_0_1_6_0_1 - 0.325446428571438*G0_0_1_7_0_0 - 0.488169642857154*G0_0_1_7_0_1 + 1.03058035714287*G0_0_1_8_0_0 + 0.976339285714287*G0_0_1_8_0_1 - 0.542410714285734*G0_0_1_9_0_0 - 0.325446428571429*G0_0_1_9_0_1 - 0.0542410714285714*G0_0_1_10_1_0 - 0.0542410714285717*G0_0_1_10_1_1 - 0.650892857142863*G0_0_1_11_1_0 + 0.271205357142872*G0_0_1_13_1_0 - 0.976339285714286*G0_0_1_13_1_1 + 0.216964285714291*G0_0_1_14_1_0 + 0.813616071428584*G0_0_1_14_1_1 + 0.271205357142862*G0_0_1_15_1_0 + 0.433928571428578*G0_0_1_15_1_1 - 0.216964285714291*G0_0_1_16_1_0 - 0.379687500000007*G0_0_1_16_1_1 - 0.325446428571438*G0_0_1_17_1_0 - 0.488169642857154*G0_0_1_17_1_1 + 1.03058035714287*G0_0_1_18_1_0 + 0.976339285714287*G0_0_1_18_1_1 - 0.542410714285734*G0_0_1_19_1_0 - 0.325446428571429*G0_0_1_19_1_1 + 0.0542410714285713*G0_1_0_0_0_0 + 0.0542410714285717*G0_1_0_0_0_1 + 0.650892857142863*G0_1_0_1_0_0 - 0.271205357142872*G0_1_0_3_0_0 + 0.976339285714287*G0_1_0_3_0_1 - 0.216964285714291*G0_1_0_4_0_0 - 0.813616071428584*G0_1_0_4_0_1 - 0.271205357142862*G0_1_0_5_0_0 - 0.433928571428577*G0_1_0_5_0_1 + 0.216964285714291*G0_1_0_6_0_0 + 0.379687500000008*G0_1_0_6_0_1 + 0.325446428571438*G0_1_0_7_0_0 + 0.488169642857154*G0_1_0_7_0_1 - 1.03058035714287*G0_1_0_8_0_0 - 0.976339285714287*G0_1_0_8_0_1 + 0.542410714285734*G0_1_0_9_0_0 + 0.325446428571429*G0_1_0_9_0_1 + 0.0542410714285713*G0_1_0_10_1_0 + 0.0542410714285717*G0_1_0_10_1_1 + 0.650892857142863*G0_1_0_11_1_0 - 0.271205357142872*G0_1_0_13_1_0 + 0.976339285714287*G0_1_0_13_1_1 - 0.216964285714291*G0_1_0_14_1_0 - 0.813616071428584*G0_1_0_14_1_1 - 0.271205357142862*G0_1_0_15_1_0 - 0.433928571428577*G0_1_0_15_1_1 + 0.216964285714291*G0_1_0_16_1_0 + 0.379687500000008*G0_1_0_16_1_1 + 0.325446428571438*G0_1_0_17_1_0 + 0.488169642857154*G0_1_0_17_1_1 - 1.03058035714287*G0_1_0_18_1_0 - 0.976339285714287*G0_1_0_18_1_1 + 0.542410714285734*G0_1_0_19_1_0 + 0.325446428571429*G0_1_0_19_1_1; + A[377] = -A[277] + 1.07879464285716*G0_0_0_0_0_0 + 1.07879464285716*G0_0_0_0_0_1 - 0.916071428571443*G0_0_0_1_0_0 - 0.156696428571433*G0_0_0_2_0_1 - 0.27120535714283*G0_0_0_3_0_0 - 1.7357142857143*G0_0_0_3_0_1 + 0.542410714285722*G0_0_0_4_0_0 + 1.24754464285718*G0_0_0_4_0_1 + 2.11540178571432*G0_0_0_5_0_0 - 0.867857142857152*G0_0_0_5_0_1 - 0.542410714285722*G0_0_0_6_0_0 - 0.0542410714285713*G0_0_0_6_0_1 - 0.86785714285716*G0_0_0_7_0_0 + 2.11540178571431*G0_0_0_7_0_1 + 0.705133928571446*G0_0_0_8_0_0 + 1.7357142857143*G0_0_0_8_0_1 - 1.84419642857148*G0_0_0_9_0_0 - 3.36294642857149*G0_0_0_9_0_1 + 1.07879464285716*G0_0_0_10_1_0 + 1.07879464285716*G0_0_0_10_1_1 - 0.916071428571443*G0_0_0_11_1_0 - 0.156696428571433*G0_0_0_12_1_1 - 0.27120535714283*G0_0_0_13_1_0 - 1.7357142857143*G0_0_0_13_1_1 + 0.542410714285722*G0_0_0_14_1_0 + 1.24754464285718*G0_0_0_14_1_1 + 2.11540178571432*G0_0_0_15_1_0 - 0.867857142857152*G0_0_0_15_1_1 - 0.542410714285722*G0_0_0_16_1_0 - 0.0542410714285713*G0_0_0_16_1_1 - 0.86785714285716*G0_0_0_17_1_0 + 2.11540178571431*G0_0_0_17_1_1 + 0.705133928571446*G0_0_0_18_1_0 + 1.7357142857143*G0_0_0_18_1_1 - 1.84419642857148*G0_0_0_19_1_0 - 3.36294642857149*G0_0_0_19_1_1 - 0.235044642857141*G0_0_1_0_0_0 - 0.235044642857141*G0_0_1_0_0_1 - 0.470089285714292*G0_0_1_1_0_0 - 0.307366071428582*G0_0_1_2_0_1 - 0.433928571428553*G0_0_1_3_0_0 - 1.84419642857144*G0_0_1_3_0_1 + 0.488169642857148*G0_0_1_4_0_0 + 1.73571428571433*G0_0_1_4_0_1 + 0.976339285714289*G0_0_1_5_0_0 + 0.271205357142846*G0_0_1_5_0_1 - 0.488169642857148*G0_0_1_6_0_0 + 0.271205357142877*G0_0_1_6_0_1 + 2.11540178571431*G0_0_1_7_0_0 + 2.82053571428575*G0_0_1_7_0_1 - 1.41026785714287*G0_0_1_8_0_0 + 1.84419642857144*G0_0_1_8_0_1 - 0.542410714285734*G0_0_1_9_0_0 - 4.55625000000007*G0_0_1_9_0_1 - 0.235044642857141*G0_0_1_10_1_0 - 0.235044642857141*G0_0_1_10_1_1 - 0.470089285714292*G0_0_1_11_1_0 - 0.307366071428582*G0_0_1_12_1_1 - 0.433928571428553*G0_0_1_13_1_0 - 1.84419642857144*G0_0_1_13_1_1 + 0.488169642857148*G0_0_1_14_1_0 + 1.73571428571433*G0_0_1_14_1_1 + 0.976339285714289*G0_0_1_15_1_0 + 0.271205357142846*G0_0_1_15_1_1 - 0.488169642857148*G0_0_1_16_1_0 + 0.271205357142877*G0_0_1_16_1_1 + 2.11540178571431*G0_0_1_17_1_0 + 2.82053571428575*G0_0_1_17_1_1 - 1.41026785714287*G0_0_1_18_1_0 + 1.84419642857144*G0_0_1_18_1_1 - 0.542410714285734*G0_0_1_19_1_0 - 4.55625000000007*G0_0_1_19_1_1; + A[165] = A[377] - 1.67544642857145*G0_0_0_0_0_0 - 1.67544642857145*G0_0_0_0_0_1 + 1.51272321428574*G0_0_0_1_0_0 + 0.265178571428574*G0_0_0_2_0_1 + 0.162723214285705*G0_0_0_3_0_0 + 2.11540178571431*G0_0_0_3_0_1 - 0.705133928571441*G0_0_0_4_0_1 - 2.00691964285719*G0_0_0_5_0_0 + 1.35602678571429*G0_0_0_5_0_1 + 0.0542410714285854*G0_0_0_6_0_1 + 2.98325892857147*G0_0_0_7_0_0 - 0.37968750000001*G0_0_0_7_0_1 - 2.82053571428575*G0_0_0_8_0_0 - 2.11540178571431*G0_0_0_8_0_1 + 1.84419642857148*G0_0_0_9_0_0 + 1.08482142857145*G0_0_0_9_0_1 - 1.67544642857145*G0_0_0_10_1_0 - 1.67544642857145*G0_0_0_10_1_1 + 1.51272321428574*G0_0_0_11_1_0 + 0.265178571428574*G0_0_0_12_1_1 + 0.162723214285705*G0_0_0_13_1_0 + 2.11540178571431*G0_0_0_13_1_1 - 0.705133928571441*G0_0_0_14_1_1 - 2.00691964285719*G0_0_0_15_1_0 + 1.35602678571429*G0_0_0_15_1_1 + 0.0542410714285854*G0_0_0_16_1_1 + 2.98325892857147*G0_0_0_17_1_0 - 0.37968750000001*G0_0_0_17_1_1 - 2.82053571428575*G0_0_0_18_1_0 - 2.11540178571431*G0_0_0_18_1_1 + 1.84419642857148*G0_0_0_19_1_0 + 1.08482142857145*G0_0_0_19_1_1 + 0.614732142857142*G0_0_1_0_0_0 + 0.614732142857142*G0_0_1_0_0_1 + 0.849776785714295*G0_0_1_1_0_0 + 0.361607142857153*G0_0_1_2_0_1 + 0.922098214285717*G0_0_1_3_0_0 + 2.65781250000003*G0_0_1_3_0_1 - 1.24754464285716*G0_0_1_4_0_1 - 0.37968750000001*G0_0_1_5_0_0 - 0.922098214285709*G0_0_1_5_0_1 - 0.0542410714285853*G0_0_1_6_0_1 - 2.11540178571431*G0_0_1_7_0_0 - 1.57299107142861*G0_0_1_7_0_1 + 0.650892857142873*G0_0_1_8_0_0 - 2.65781250000003*G0_0_1_8_0_1 - 0.542410714285708*G0_0_1_9_0_0 + 2.82053571428577*G0_0_1_9_0_1 + 0.614732142857142*G0_0_1_10_1_0 + 0.614732142857142*G0_0_1_10_1_1 + 0.849776785714295*G0_0_1_11_1_0 + 0.361607142857153*G0_0_1_12_1_1 + 0.922098214285717*G0_0_1_13_1_0 + 2.65781250000003*G0_0_1_13_1_1 - 1.24754464285716*G0_0_1_14_1_1 - 0.37968750000001*G0_0_1_15_1_0 - 0.922098214285709*G0_0_1_15_1_1 - 0.0542410714285853*G0_0_1_16_1_1 - 2.11540178571431*G0_0_1_17_1_0 - 1.57299107142861*G0_0_1_17_1_1 + 0.650892857142873*G0_0_1_18_1_0 - 2.65781250000003*G0_0_1_18_1_1 - 0.542410714285708*G0_0_1_19_1_0 + 2.82053571428577*G0_0_1_19_1_1 - 0.216964285714291*G0_1_0_0_0_0 - 0.216964285714291*G0_1_0_0_0_1 + 0.976339285714295*G0_1_0_1_0_0 + 0.0542410714285688*G0_1_0_2_0_1 + 0.488169642857154*G0_1_0_3_0_0 + 1.62723214285716*G0_1_0_3_0_1 + 0.0542410714285706*G0_1_0_4_0_0 - 0.162723214285706*G0_1_0_4_0_1 + 0.596651785714289*G0_1_0_5_0_0 + 0.162723214285718*G0_1_0_5_0_1 - 0.0542410714285706*G0_1_0_6_0_0 + 1.35602678571431*G0_1_0_7_0_0 + 1.78995535714288*G0_1_0_7_0_1 - 2.11540178571431*G0_1_0_8_0_0 - 1.62723214285716*G0_1_0_8_0_1 - 1.08482142857144*G0_1_0_9_0_0 - 1.62723214285717*G0_1_0_9_0_1 - 0.216964285714291*G0_1_0_10_1_0 - 0.216964285714291*G0_1_0_10_1_1 + 0.976339285714295*G0_1_0_11_1_0 + 0.0542410714285688*G0_1_0_12_1_1 + 0.488169642857154*G0_1_0_13_1_0 + 1.62723214285716*G0_1_0_13_1_1 + 0.0542410714285706*G0_1_0_14_1_0 - 0.162723214285706*G0_1_0_14_1_1 + 0.596651785714289*G0_1_0_15_1_0 + 0.162723214285718*G0_1_0_15_1_1 - 0.0542410714285706*G0_1_0_16_1_0 + 1.35602678571431*G0_1_0_17_1_0 + 1.78995535714288*G0_1_0_17_1_1 - 2.11540178571431*G0_1_0_18_1_0 - 1.62723214285716*G0_1_0_18_1_1 - 1.08482142857144*G0_1_0_19_1_0 - 1.62723214285717*G0_1_0_19_1_1 - 0.55446428571429*G0_1_1_0_0_0 - 0.55446428571429*G0_1_1_0_0_1 + 1.31383928571429*G0_1_1_1_0_0 + 0.06629464285714*G0_1_1_2_0_1 + 0.81361607142858*G0_1_1_3_0_0 + 2.27812500000001*G0_1_1_3_0_1 - 0.0542410714285711*G0_1_1_4_0_0 - 0.271205357142848*G0_1_1_4_0_1 + 0.271205357142861*G0_1_1_5_0_0 + 0.488169642857144*G0_1_1_5_0_1 + 0.0542410714285713*G0_1_1_6_0_0 + 1.89843750000002*G0_1_1_7_0_0 + 1.68147321428574*G0_1_1_7_0_1 - 2.65781250000003*G0_1_1_8_0_0 - 2.27812500000001*G0_1_1_8_0_1 - 1.08482142857144*G0_1_1_9_0_0 - 1.41026785714289*G0_1_1_9_0_1 - 0.55446428571429*G0_1_1_10_1_0 - 0.55446428571429*G0_1_1_10_1_1 + 1.31383928571429*G0_1_1_11_1_0 + 0.06629464285714*G0_1_1_12_1_1 + 0.81361607142858*G0_1_1_13_1_0 + 2.27812500000001*G0_1_1_13_1_1 - 0.0542410714285711*G0_1_1_14_1_0 - 0.271205357142848*G0_1_1_14_1_1 + 0.271205357142861*G0_1_1_15_1_0 + 0.488169642857144*G0_1_1_15_1_1 + 0.0542410714285713*G0_1_1_16_1_0 + 1.89843750000002*G0_1_1_17_1_0 + 1.68147321428574*G0_1_1_17_1_1 - 2.65781250000003*G0_1_1_18_1_0 - 2.27812500000001*G0_1_1_18_1_1 - 1.08482142857144*G0_1_1_19_1_0 - 1.41026785714289*G0_1_1_19_1_1; + A[189] = -A[377] - 0.150669642857159*G0_0_0_0_0_0 - 0.150669642857159*G0_0_0_0_0_1 + 0.150669642857159*G0_0_0_1_0_0 - 0.0662946428571354*G0_0_0_2_0_1 + 2.76629464285717*G0_0_0_3_0_0 + 0.0542410714285753*G0_0_0_3_0_1 + 4.17656250000009*G0_0_0_4_0_0 + 7.10558035714297*G0_0_0_4_0_1 - 2.76629464285718*G0_0_0_5_0_0 - 2.71205357142859*G0_0_0_5_0_1 - 4.17656250000009*G0_0_0_6_0_0 + 2.92901785714289*G0_0_0_6_0_1 + 2.0611607142858*G0_0_0_7_0_0 + 2.00691964285721*G0_0_0_7_0_1 - 2.0611607142858*G0_0_0_8_0_0 - 0.0542410714285739*G0_0_0_8_0_1 - 9.11250000000019*G0_0_0_9_0_1 - 0.150669642857159*G0_0_0_10_1_0 - 0.150669642857159*G0_0_0_10_1_1 + 0.150669642857159*G0_0_0_11_1_0 - 0.0662946428571354*G0_0_0_12_1_1 + 2.76629464285717*G0_0_0_13_1_0 + 0.0542410714285753*G0_0_0_13_1_1 + 4.17656250000009*G0_0_0_14_1_0 + 7.10558035714297*G0_0_0_14_1_1 - 2.76629464285718*G0_0_0_15_1_0 - 2.71205357142859*G0_0_0_15_1_1 - 4.17656250000009*G0_0_0_16_1_0 + 2.92901785714289*G0_0_0_16_1_1 + 2.0611607142858*G0_0_0_17_1_0 + 2.00691964285721*G0_0_0_17_1_1 - 2.0611607142858*G0_0_0_18_1_0 - 0.0542410714285739*G0_0_0_18_1_1 - 9.11250000000019*G0_0_0_19_1_1 - 1.22343750000002*G0_0_1_0_0_0 - 1.22343750000002*G0_0_1_0_0_1 - 0.89196428571429*G0_0_1_1_0_0 - 0.186830357142858*G0_0_1_2_0_1 + 4.3392857142858*G0_0_1_3_0_0 - 0.867857142857134*G0_0_1_3_0_1 + 2.22388392857147*G0_0_1_4_0_0 + 6.72589285714298*G0_0_1_4_0_1 + 2.27812500000006*G0_0_1_5_0_0 + 2.33236607142862*G0_0_1_5_0_1 - 2.22388392857147*G0_0_1_6_0_0 - 0.922098214285736*G0_0_1_6_0_1 + 3.30870535714293*G0_0_1_7_0_0 + 3.25446428571437*G0_0_1_7_0_1 - 1.19330357142862*G0_0_1_8_0_0 + 0.867857142857135*G0_0_1_8_0_1 - 6.61741071428586*G0_0_1_9_0_0 - 9.98035714285735*G0_0_1_9_0_1 - 1.22343750000002*G0_0_1_10_1_0 - 1.22343750000002*G0_0_1_10_1_1 - 0.89196428571429*G0_0_1_11_1_0 - 0.186830357142858*G0_0_1_12_1_1 + 4.3392857142858*G0_0_1_13_1_0 - 0.867857142857134*G0_0_1_13_1_1 + 2.22388392857147*G0_0_1_14_1_0 + 6.72589285714298*G0_0_1_14_1_1 + 2.27812500000006*G0_0_1_15_1_0 + 2.33236607142862*G0_0_1_15_1_1 - 2.22388392857147*G0_0_1_16_1_0 - 0.922098214285736*G0_0_1_16_1_1 + 3.30870535714293*G0_0_1_17_1_0 + 3.25446428571437*G0_0_1_17_1_1 - 1.19330357142862*G0_0_1_18_1_0 + 0.867857142857135*G0_0_1_18_1_1 - 6.61741071428586*G0_0_1_19_1_0 - 9.98035714285735*G0_0_1_19_1_1 - 1.04263392857145*G0_1_0_0_0_0 - 1.04263392857145*G0_1_0_0_0_1 - 1.07276785714286*G0_1_0_1_0_0 + 0.120535714285725*G0_1_0_2_0_1 + 5.04441964285723*G0_1_0_3_0_0 + 1.95267857142862*G0_1_0_4_0_0 + 5.80379464285724*G0_1_0_4_0_1 + 1.57299107142863*G0_1_0_5_0_0 + 2.49508928571435*G0_1_0_5_0_1 - 1.95267857142861*G0_1_0_6_0_0 - 1.57299107142862*G0_1_0_6_0_1 + 0.86785714285718*G0_1_0_7_0_0 - 0.0542410714285348*G0_1_0_7_0_1 + 1.24754464285713*G0_1_0_8_0_0 - 6.61741071428586*G0_1_0_9_0_0 - 5.7495535714287*G0_1_0_9_0_1 - 1.04263392857145*G0_1_0_10_1_0 - 1.04263392857145*G0_1_0_10_1_1 - 1.07276785714286*G0_1_0_11_1_0 + 0.120535714285725*G0_1_0_12_1_1 + 5.04441964285723*G0_1_0_13_1_0 + 1.95267857142862*G0_1_0_14_1_0 + 5.80379464285724*G0_1_0_14_1_1 + 1.57299107142863*G0_1_0_15_1_0 + 2.49508928571435*G0_1_0_15_1_1 - 1.95267857142861*G0_1_0_16_1_0 - 1.57299107142862*G0_1_0_16_1_1 + 0.86785714285718*G0_1_0_17_1_0 - 0.0542410714285348*G0_1_0_17_1_1 + 1.24754464285713*G0_1_0_18_1_0 - 6.61741071428586*G0_1_0_19_1_0 - 5.7495535714287*G0_1_0_19_1_1 - 0.946205357142886*G0_1_1_0_0_0 - 0.946205357142888*G0_1_1_0_0_1 - 1.16919642857143*G0_1_1_1_0_0 + 1.48861607142861*G0_1_1_2_0_1 + 5.53258928571438*G0_1_1_3_0_0 + 1.62723214285722*G0_1_1_3_0_1 + 2.65781250000004*G0_1_1_4_0_0 + 3.90535714285716*G0_1_1_4_0_1 + 1.08482142857149*G0_1_1_5_0_0 + 3.63415178571439*G0_1_1_5_0_1 - 2.65781250000004*G0_1_1_6_0_0 - 4.17656250000012*G0_1_1_6_0_1 - 3.30870535714289*G0_1_1_7_0_0 - 5.8580357142858*G0_1_1_7_0_1 + 5.42410714285721*G0_1_1_8_0_0 - 1.62723214285721*G0_1_1_8_0_1 - 6.61741071428586*G0_1_1_9_0_0 + 1.95267857142864*G0_1_1_9_0_1 - 0.946205357142886*G0_1_1_10_1_0 - 0.946205357142888*G0_1_1_10_1_1 - 1.16919642857143*G0_1_1_11_1_0 + 1.48861607142861*G0_1_1_12_1_1 + 5.53258928571438*G0_1_1_13_1_0 + 1.62723214285722*G0_1_1_13_1_1 + 2.65781250000004*G0_1_1_14_1_0 + 3.90535714285716*G0_1_1_14_1_1 + 1.08482142857149*G0_1_1_15_1_0 + 3.63415178571439*G0_1_1_15_1_1 - 2.65781250000004*G0_1_1_16_1_0 - 4.17656250000012*G0_1_1_16_1_1 - 3.30870535714289*G0_1_1_17_1_0 - 5.8580357142858*G0_1_1_17_1_1 + 5.42410714285721*G0_1_1_18_1_0 - 1.62723214285721*G0_1_1_18_1_1 - 6.61741071428586*G0_1_1_19_1_0 + 1.95267857142864*G0_1_1_19_1_1; + A[167] = A[377]; + A[375] = A[165]; + A[399] = A[189]; + A[358] = A[377] + 0.18080357142857*G0_0_1_0_0_0 + 0.18080357142857*G0_0_1_0_0_1 - 0.180803571428571*G0_0_1_1_0_0 + 0.307366071428583*G0_0_1_2_0_1 + 0.705133928571426*G0_0_1_3_0_0 + 0.867857142857158*G0_0_1_3_0_1 - 0.271205357142857*G0_0_1_4_0_0 - 0.922098214285742*G0_0_1_4_0_1 - 0.705133928571427*G0_0_1_5_0_0 + 0.162723214285731*G0_0_1_5_0_1 + 0.271205357142858*G0_0_1_6_0_0 - 0.650892857142884*G0_0_1_6_0_1 - 2.44084821428575*G0_0_1_7_0_0 - 3.3087053571429*G0_0_1_7_0_1 + 2.44084821428575*G0_0_1_8_0_0 - 0.867857142857157*G0_0_1_8_0_1 + 4.23080357142864*G0_0_1_9_0_1 + 0.18080357142857*G0_0_1_10_1_0 + 0.18080357142857*G0_0_1_10_1_1 - 0.180803571428571*G0_0_1_11_1_0 + 0.307366071428583*G0_0_1_12_1_1 + 0.705133928571426*G0_0_1_13_1_0 + 0.867857142857158*G0_0_1_13_1_1 - 0.271205357142857*G0_0_1_14_1_0 - 0.922098214285742*G0_0_1_14_1_1 - 0.705133928571427*G0_0_1_15_1_0 + 0.162723214285731*G0_0_1_15_1_1 + 0.271205357142858*G0_0_1_16_1_0 - 0.650892857142884*G0_0_1_16_1_1 - 2.44084821428575*G0_0_1_17_1_0 - 3.3087053571429*G0_0_1_17_1_1 + 2.44084821428575*G0_0_1_18_1_0 - 0.867857142857157*G0_0_1_18_1_1 + 4.23080357142864*G0_0_1_19_1_1 - 0.180803571428571*G0_1_0_0_0_0 - 0.18080357142857*G0_1_0_0_0_1 + 0.180803571428571*G0_1_0_1_0_0 - 0.307366071428583*G0_1_0_2_0_1 - 0.705133928571426*G0_1_0_3_0_0 - 0.867857142857158*G0_1_0_3_0_1 + 0.271205357142857*G0_1_0_4_0_0 + 0.922098214285742*G0_1_0_4_0_1 + 0.705133928571427*G0_1_0_5_0_0 - 0.16272321428573*G0_1_0_5_0_1 - 0.271205357142858*G0_1_0_6_0_0 + 0.650892857142884*G0_1_0_6_0_1 + 2.44084821428575*G0_1_0_7_0_0 + 3.3087053571429*G0_1_0_7_0_1 - 2.44084821428575*G0_1_0_8_0_0 + 0.867857142857157*G0_1_0_8_0_1 - 4.23080357142864*G0_1_0_9_0_1 - 0.180803571428571*G0_1_0_10_1_0 - 0.18080357142857*G0_1_0_10_1_1 + 0.180803571428571*G0_1_0_11_1_0 - 0.307366071428583*G0_1_0_12_1_1 - 0.705133928571426*G0_1_0_13_1_0 - 0.867857142857158*G0_1_0_13_1_1 + 0.271205357142857*G0_1_0_14_1_0 + 0.922098214285742*G0_1_0_14_1_1 + 0.705133928571427*G0_1_0_15_1_0 - 0.16272321428573*G0_1_0_15_1_1 - 0.271205357142858*G0_1_0_16_1_0 + 0.650892857142884*G0_1_0_16_1_1 + 2.44084821428575*G0_1_0_17_1_0 + 3.3087053571429*G0_1_0_17_1_1 - 2.44084821428575*G0_1_0_18_1_0 + 0.867857142857157*G0_1_0_18_1_1 - 4.23080357142864*G0_1_0_19_1_1; + A[65] = -A[165] - 0.608705357142865*G0_0_0_0_0_0 - 0.608705357142865*G0_0_0_0_0_1 + 0.445982142857152*G0_0_0_1_0_0 - 0.25915178571429*G0_0_0_2_0_1 - 0.325446428571431*G0_0_0_3_0_0 - 0.108482142857141*G0_0_0_3_0_1 + 0.27120535714287*G0_0_0_4_0_0 + 0.759375000000022*G0_0_0_4_0_1 - 1.51875000000005*G0_0_0_5_0_0 - 0.379687500000025*G0_0_0_5_0_1 - 0.27120535714287*G0_0_0_6_0_0 + 1.24754464285718*G0_0_0_6_0_1 + 2.11540178571432*G0_0_0_7_0_0 + 0.976339285714289*G0_0_0_7_0_1 - 1.9526785714286*G0_0_0_8_0_0 + 0.108482142857141*G0_0_0_8_0_1 + 1.84419642857148*G0_0_0_9_0_0 - 1.73571428571431*G0_0_0_9_0_1 - 0.608705357142865*G0_0_0_10_1_0 - 0.608705357142865*G0_0_0_10_1_1 + 0.445982142857152*G0_0_0_11_1_0 - 0.25915178571429*G0_0_0_12_1_1 - 0.325446428571431*G0_0_0_13_1_0 - 0.108482142857141*G0_0_0_13_1_1 + 0.27120535714287*G0_0_0_14_1_0 + 0.759375000000022*G0_0_0_14_1_1 - 1.51875000000005*G0_0_0_15_1_0 - 0.379687500000025*G0_0_0_15_1_1 - 0.27120535714287*G0_0_0_16_1_0 + 1.24754464285718*G0_0_0_16_1_1 + 2.11540178571432*G0_0_0_17_1_0 + 0.976339285714289*G0_0_0_17_1_1 - 1.9526785714286*G0_0_0_18_1_0 + 0.108482142857141*G0_0_0_18_1_1 + 1.84419642857148*G0_0_0_19_1_0 - 1.73571428571431*G0_0_0_19_1_1 + 0.705133928571434*G0_0_1_0_0_0 + 0.705133928571434*G0_0_1_0_0_1 - 0.108482142857143*G0_0_1_2_0_1 - 0.162723214285706*G0_0_1_3_0_0 + 0.325446428571444*G0_0_1_4_0_0 + 0.271205357142876*G0_0_1_4_0_1 - 0.379687500000025*G0_0_1_5_0_0 - 1.51875000000002*G0_0_1_5_0_1 - 0.325446428571444*G0_0_1_6_0_0 + 0.922098214285733*G0_0_1_6_0_1 - 0.867857142857152*G0_0_1_7_0_0 + 0.271205357142846*G0_0_1_7_0_1 + 0.162723214285717*G0_0_1_8_0_0 + 0.542410714285731*G0_0_1_9_0_0 - 0.542410714285723*G0_0_1_9_0_1 + 0.705133928571434*G0_0_1_10_1_0 + 0.705133928571434*G0_0_1_10_1_1 - 0.108482142857143*G0_0_1_12_1_1 - 0.162723214285706*G0_0_1_13_1_0 + 0.325446428571444*G0_0_1_14_1_0 + 0.271205357142876*G0_0_1_14_1_1 - 0.379687500000025*G0_0_1_15_1_0 - 1.51875000000002*G0_0_1_15_1_1 - 0.325446428571444*G0_0_1_16_1_0 + 0.922098214285733*G0_0_1_16_1_1 - 0.867857142857152*G0_0_1_17_1_0 + 0.271205357142846*G0_0_1_17_1_1 + 0.162723214285717*G0_0_1_18_1_0 + 0.542410714285731*G0_0_1_19_1_0 - 0.542410714285723*G0_0_1_19_1_1; + A[313] = A[65] - 0.0542410714285711*G0_0_1_0_0_0 - 0.054241071428571*G0_0_1_0_0_1 + 0.0542410714285698*G0_0_1_1_0_0 + 0.108482142857144*G0_0_1_2_0_1 - 0.108482142857156*G0_0_1_3_0_0 + 0.16272321428571*G0_0_1_3_0_1 - 0.108482142857153*G0_0_1_4_0_0 - 0.433928571428592*G0_0_1_4_0_1 + 0.108482142857154*G0_0_1_5_0_0 + 0.271205357142867*G0_0_1_5_0_1 + 0.108482142857153*G0_0_1_6_0_0 - 0.32544642857144*G0_0_1_6_0_1 - 0.16272321428572*G0_0_1_7_0_0 - 0.325446428571433*G0_0_1_7_0_1 + 0.162723214285722*G0_0_1_8_0_0 - 0.16272321428571*G0_0_1_8_0_1 + 0.759375000000025*G0_0_1_9_0_1 - 0.0542410714285711*G0_0_1_10_1_0 - 0.054241071428571*G0_0_1_10_1_1 + 0.0542410714285698*G0_0_1_11_1_0 + 0.108482142857144*G0_0_1_12_1_1 - 0.108482142857156*G0_0_1_13_1_0 + 0.16272321428571*G0_0_1_13_1_1 - 0.108482142857153*G0_0_1_14_1_0 - 0.433928571428592*G0_0_1_14_1_1 + 0.108482142857154*G0_0_1_15_1_0 + 0.271205357142867*G0_0_1_15_1_1 + 0.108482142857153*G0_0_1_16_1_0 - 0.32544642857144*G0_0_1_16_1_1 - 0.16272321428572*G0_0_1_17_1_0 - 0.325446428571433*G0_0_1_17_1_1 + 0.162723214285722*G0_0_1_18_1_0 - 0.16272321428571*G0_0_1_18_1_1 + 0.759375000000025*G0_0_1_19_1_1 + 0.0542410714285711*G0_1_0_0_0_0 + 0.054241071428571*G0_1_0_0_0_1 - 0.0542410714285697*G0_1_0_1_0_0 - 0.108482142857144*G0_1_0_2_0_1 + 0.108482142857156*G0_1_0_3_0_0 - 0.16272321428571*G0_1_0_3_0_1 + 0.108482142857153*G0_1_0_4_0_0 + 0.433928571428592*G0_1_0_4_0_1 - 0.108482142857154*G0_1_0_5_0_0 - 0.271205357142866*G0_1_0_5_0_1 - 0.108482142857153*G0_1_0_6_0_0 + 0.32544642857144*G0_1_0_6_0_1 + 0.16272321428572*G0_1_0_7_0_0 + 0.325446428571433*G0_1_0_7_0_1 - 0.162723214285722*G0_1_0_8_0_0 + 0.16272321428571*G0_1_0_8_0_1 - 0.759375000000025*G0_1_0_9_0_1 + 0.0542410714285711*G0_1_0_10_1_0 + 0.054241071428571*G0_1_0_10_1_1 - 0.0542410714285697*G0_1_0_11_1_0 - 0.108482142857144*G0_1_0_12_1_1 + 0.108482142857156*G0_1_0_13_1_0 - 0.16272321428571*G0_1_0_13_1_1 + 0.108482142857153*G0_1_0_14_1_0 + 0.433928571428592*G0_1_0_14_1_1 - 0.108482142857154*G0_1_0_15_1_0 - 0.271205357142866*G0_1_0_15_1_1 - 0.108482142857153*G0_1_0_16_1_0 + 0.32544642857144*G0_1_0_16_1_1 + 0.16272321428572*G0_1_0_17_1_0 + 0.325446428571433*G0_1_0_17_1_1 - 0.162723214285722*G0_1_0_18_1_0 + 0.16272321428571*G0_1_0_18_1_1 - 0.759375000000025*G0_1_0_19_1_1; + A[108] = -A[313] - 0.608705357142865*G0_0_0_0_0_0 - 0.608705357142865*G0_0_0_0_0_1 + 0.445982142857152*G0_0_0_1_0_0 - 0.25915178571429*G0_0_0_2_0_1 - 0.325446428571431*G0_0_0_3_0_0 - 0.108482142857141*G0_0_0_3_0_1 + 0.27120535714287*G0_0_0_4_0_0 + 0.759375000000022*G0_0_0_4_0_1 - 1.51875000000005*G0_0_0_5_0_0 - 0.379687500000025*G0_0_0_5_0_1 - 0.271205357142871*G0_0_0_6_0_0 + 1.24754464285718*G0_0_0_6_0_1 + 2.11540178571432*G0_0_0_7_0_0 + 0.976339285714289*G0_0_0_7_0_1 - 1.9526785714286*G0_0_0_8_0_0 + 0.108482142857141*G0_0_0_8_0_1 + 1.84419642857148*G0_0_0_9_0_0 - 1.73571428571431*G0_0_0_9_0_1 - 0.608705357142865*G0_0_0_10_1_0 - 0.608705357142865*G0_0_0_10_1_1 + 0.445982142857152*G0_0_0_11_1_0 - 0.25915178571429*G0_0_0_12_1_1 - 0.325446428571431*G0_0_0_13_1_0 - 0.108482142857141*G0_0_0_13_1_1 + 0.27120535714287*G0_0_0_14_1_0 + 0.759375000000022*G0_0_0_14_1_1 - 1.51875000000005*G0_0_0_15_1_0 - 0.379687500000025*G0_0_0_15_1_1 - 0.271205357142871*G0_0_0_16_1_0 + 1.24754464285718*G0_0_0_16_1_1 + 2.11540178571432*G0_0_0_17_1_0 + 0.976339285714289*G0_0_0_17_1_1 - 1.9526785714286*G0_0_0_18_1_0 + 0.108482142857141*G0_0_0_18_1_1 + 1.84419642857148*G0_0_0_19_1_0 - 1.73571428571431*G0_0_0_19_1_1 + 0.705133928571434*G0_1_0_0_0_0 + 0.705133928571434*G0_1_0_0_0_1 - 0.108482142857143*G0_1_0_2_0_1 - 0.162723214285706*G0_1_0_3_0_0 + 0.325446428571444*G0_1_0_4_0_0 + 0.271205357142876*G0_1_0_4_0_1 - 0.379687500000025*G0_1_0_5_0_0 - 1.51875000000002*G0_1_0_5_0_1 - 0.325446428571444*G0_1_0_6_0_0 + 0.922098214285733*G0_1_0_6_0_1 - 0.867857142857152*G0_1_0_7_0_0 + 0.271205357142846*G0_1_0_7_0_1 + 0.162723214285717*G0_1_0_8_0_0 + 0.542410714285731*G0_1_0_9_0_0 - 0.542410714285723*G0_1_0_9_0_1 + 0.705133928571434*G0_1_0_10_1_0 + 0.705133928571434*G0_1_0_10_1_1 - 0.108482142857143*G0_1_0_12_1_1 - 0.162723214285706*G0_1_0_13_1_0 + 0.325446428571444*G0_1_0_14_1_0 + 0.271205357142876*G0_1_0_14_1_1 - 0.379687500000025*G0_1_0_15_1_0 - 1.51875000000002*G0_1_0_15_1_1 - 0.325446428571444*G0_1_0_16_1_0 + 0.922098214285733*G0_1_0_16_1_1 - 0.867857142857152*G0_1_0_17_1_0 + 0.271205357142846*G0_1_0_17_1_1 + 0.162723214285717*G0_1_0_18_1_0 + 0.542410714285731*G0_1_0_19_1_0 - 0.542410714285723*G0_1_0_19_1_1; + A[278] = A[108] + 0.650892857142863*G0_0_0_0_0_0 + 0.650892857142863*G0_0_0_0_0_1 - 0.976339285714293*G0_0_0_1_0_0 - 0.108482142857159*G0_0_0_3_0_0 - 1.19330357142858*G0_0_0_3_0_1 + 0.108482142857127*G0_0_0_4_0_1 - 0.108482142857126*G0_0_0_5_0_0 - 0.54241071428571*G0_0_0_5_0_1 - 0.108482142857159*G0_0_0_6_0_1 - 2.27812500000002*G0_0_0_7_0_0 - 1.84419642857144*G0_0_0_7_0_1 + 2.60357142857145*G0_0_0_8_0_0 + 1.19330357142858*G0_0_0_8_0_1 + 0.216964285714285*G0_0_0_9_0_0 + 1.73571428571431*G0_0_0_9_0_1 + 0.650892857142863*G0_0_0_10_1_0 + 0.650892857142863*G0_0_0_10_1_1 - 0.976339285714293*G0_0_0_11_1_0 - 0.108482142857159*G0_0_0_13_1_0 - 1.19330357142858*G0_0_0_13_1_1 + 0.108482142857127*G0_0_0_14_1_1 - 0.108482142857126*G0_0_0_15_1_0 - 0.54241071428571*G0_0_0_15_1_1 - 0.108482142857159*G0_0_0_16_1_1 - 2.27812500000002*G0_0_0_17_1_0 - 1.84419642857144*G0_0_0_17_1_1 + 2.60357142857145*G0_0_0_18_1_0 + 1.19330357142858*G0_0_0_18_1_1 + 0.216964285714285*G0_0_0_19_1_0 + 1.73571428571431*G0_0_0_19_1_1 + 0.13258928571429*G0_0_1_0_0_0 + 0.13258928571429*G0_0_1_0_0_1 - 0.891964285714291*G0_0_1_1_0_0 - 0.0241071428571424*G0_0_1_2_0_1 - 1.84419642857144*G0_0_1_3_0_0 - 2.38660714285715*G0_0_1_3_0_1 - 0.325446428571435*G0_0_1_4_0_1 - 0.54241071428572*G0_0_1_5_0_0 - 0.216964285714292*G0_0_1_5_0_1 + 0.108482142857145*G0_0_1_6_0_1 - 0.433928571428585*G0_0_1_7_0_0 - 0.759375000000012*G0_0_1_7_0_1 + 1.19330357142858*G0_0_1_8_0_0 + 2.38660714285715*G0_0_1_8_0_1 + 2.38660714285716*G0_0_1_9_0_0 + 1.08482142857145*G0_0_1_9_0_1 + 0.13258928571429*G0_0_1_10_1_0 + 0.13258928571429*G0_0_1_10_1_1 - 0.891964285714291*G0_0_1_11_1_0 - 0.0241071428571424*G0_0_1_12_1_1 - 1.84419642857144*G0_0_1_13_1_0 - 2.38660714285715*G0_0_1_13_1_1 - 0.325446428571435*G0_0_1_14_1_1 - 0.54241071428572*G0_0_1_15_1_0 - 0.216964285714292*G0_0_1_15_1_1 + 0.108482142857145*G0_0_1_16_1_1 - 0.433928571428585*G0_0_1_17_1_0 - 0.759375000000012*G0_0_1_17_1_1 + 1.19330357142858*G0_0_1_18_1_0 + 2.38660714285715*G0_0_1_18_1_1 + 2.38660714285716*G0_0_1_19_1_0 + 1.08482142857145*G0_0_1_19_1_1 - 0.192857142857142*G0_1_0_0_0_0 - 0.192857142857143*G0_1_0_0_0_1 - 2.79040178571431*G0_1_0_1_0_0 - 0.349553571428573*G0_1_0_2_0_1 - 1.03058035714286*G0_1_0_3_0_0 - 5.26138392857146*G0_1_0_3_0_1 - 0.108482142857147*G0_1_0_4_0_0 + 1.68147321428572*G0_1_0_4_0_1 - 0.379687499999988*G0_1_0_5_0_0 + 1.03058035714287*G0_1_0_5_0_1 + 0.108482142857147*G0_1_0_6_0_0 - 0.488169642857153*G0_1_0_6_0_1 - 1.13906250000001*G0_1_0_7_0_0 - 2.54933035714287*G0_1_0_7_0_1 + 4.12232142857146*G0_1_0_8_0_0 + 5.26138392857146*G0_1_0_8_0_1 + 1.41026785714285*G0_1_0_9_0_0 + 0.867857142857146*G0_1_0_9_0_1 - 0.192857142857142*G0_1_0_10_1_0 - 0.192857142857143*G0_1_0_10_1_1 - 2.79040178571431*G0_1_0_11_1_0 - 0.349553571428573*G0_1_0_12_1_1 - 1.03058035714286*G0_1_0_13_1_0 - 5.26138392857146*G0_1_0_13_1_1 - 0.108482142857147*G0_1_0_14_1_0 + 1.68147321428572*G0_1_0_14_1_1 - 0.379687499999988*G0_1_0_15_1_0 + 1.03058035714287*G0_1_0_15_1_1 + 0.108482142857147*G0_1_0_16_1_0 - 0.488169642857153*G0_1_0_16_1_1 - 1.13906250000001*G0_1_0_17_1_0 - 2.54933035714287*G0_1_0_17_1_1 + 4.12232142857146*G0_1_0_18_1_0 + 5.26138392857146*G0_1_0_18_1_1 + 1.41026785714285*G0_1_0_19_1_0 + 0.867857142857146*G0_1_0_19_1_1 + 0.548437500000005*G0_1_1_0_0_0 + 0.548437500000004*G0_1_1_0_0_1 - 3.96562500000003*G0_1_1_1_0_0 - 0.602678571428578*G0_1_1_2_0_1 - 2.54933035714286*G0_1_1_3_0_0 - 8.13616071428577*G0_1_1_3_0_1 + 0.325446428571429*G0_1_1_4_0_0 + 2.54933035714288*G0_1_1_4_0_1 - 0.379687500000002*G0_1_1_5_0_0 - 0.216964285714289*G0_1_1_5_0_1 - 0.32544642857143*G0_1_1_6_0_0 + 0.271205357142863*G0_1_1_6_0_1 - 1.84419642857144*G0_1_1_7_0_0 - 2.00691964285715*G0_1_1_7_0_1 + 5.26138392857146*G0_1_1_8_0_0 + 8.13616071428577*G0_1_1_8_0_1 + 2.92901785714286*G0_1_1_9_0_0 - 0.542410714285729*G0_1_1_9_0_1 + 0.548437500000005*G0_1_1_10_1_0 + 0.548437500000004*G0_1_1_10_1_1 - 3.96562500000003*G0_1_1_11_1_0 - 0.602678571428578*G0_1_1_12_1_1 - 2.54933035714286*G0_1_1_13_1_0 - 8.13616071428577*G0_1_1_13_1_1 + 0.325446428571429*G0_1_1_14_1_0 + 2.54933035714288*G0_1_1_14_1_1 - 0.379687500000002*G0_1_1_15_1_0 - 0.216964285714289*G0_1_1_15_1_1 - 0.32544642857143*G0_1_1_16_1_0 + 0.271205357142863*G0_1_1_16_1_1 - 1.84419642857144*G0_1_1_17_1_0 - 2.00691964285715*G0_1_1_17_1_1 + 5.26138392857146*G0_1_1_18_1_0 + 8.13616071428577*G0_1_1_18_1_1 + 2.92901785714286*G0_1_1_19_1_0 - 0.542410714285729*G0_1_1_19_1_1; + A[273] = -A[278] - 0.114508928571438*G0_0_0_0_0_0 - 0.114508928571438*G0_0_0_0_0_1 - 0.156696428571421*G0_0_0_1_0_0 + 0.439955357142871*G0_0_0_2_0_1 + 2.16964285714284*G0_0_0_3_0_0 + 0.542410714285713*G0_0_0_3_0_1 + 2.22388392857147*G0_0_0_4_0_0 + 3.2544642857143*G0_0_0_4_0_1 - 0.325446428571431*G0_0_0_5_0_0 - 0.162723214285706*G0_0_0_5_0_1 - 2.22388392857147*G0_0_0_6_0_0 - 0.162723214285727*G0_0_0_6_0_1 - 0.27120535714283*G0_0_0_7_0_0 - 0.433928571428554*G0_0_0_7_0_1 + 0.542410714285688*G0_0_0_8_0_0 - 0.542410714285712*G0_0_0_8_0_1 - 1.84419642857141*G0_0_0_9_0_0 - 2.82053571428575*G0_0_0_9_0_1 - 0.114508928571438*G0_0_0_10_1_0 - 0.114508928571438*G0_0_0_10_1_1 - 0.156696428571421*G0_0_0_11_1_0 + 0.439955357142871*G0_0_0_12_1_1 + 2.16964285714284*G0_0_0_13_1_0 + 0.542410714285713*G0_0_0_13_1_1 + 2.22388392857147*G0_0_0_14_1_0 + 3.2544642857143*G0_0_0_14_1_1 - 0.325446428571431*G0_0_0_15_1_0 - 0.162723214285706*G0_0_0_15_1_1 - 2.22388392857147*G0_0_0_16_1_0 - 0.162723214285727*G0_0_0_16_1_1 - 0.27120535714283*G0_0_0_17_1_0 - 0.433928571428554*G0_0_0_17_1_1 + 0.542410714285688*G0_0_0_18_1_0 - 0.542410714285712*G0_0_0_18_1_1 - 1.84419642857141*G0_0_0_19_1_0 - 2.82053571428575*G0_0_0_19_1_1 + 0.32544642857143*G0_1_0_0_0_0 + 0.32544642857143*G0_1_0_0_0_1 - 1.84419642857145*G0_1_0_1_0_0 - 0.325446428571429*G0_1_0_2_0_1 + 0.542410714285712*G0_1_0_3_0_0 - 2.7120535714286*G0_1_0_3_0_1 + 0.108482142857145*G0_1_0_4_0_0 + 1.84419642857144*G0_1_0_4_0_1 - 0.10848214285714*G0_1_0_5_0_0 - 0.108482142857145*G0_1_0_6_0_0 - 1.7357142857143*G0_1_0_7_0_0 - 1.84419642857144*G0_1_0_7_0_1 + 3.25446428571431*G0_1_0_8_0_0 + 2.7120535714286*G0_1_0_8_0_1 - 0.433928571428572*G0_1_0_9_0_0 + 0.32544642857143*G0_1_0_10_1_0 + 0.32544642857143*G0_1_0_10_1_1 - 1.84419642857145*G0_1_0_11_1_0 - 0.325446428571429*G0_1_0_12_1_1 + 0.542410714285712*G0_1_0_13_1_0 - 2.7120535714286*G0_1_0_13_1_1 + 0.108482142857145*G0_1_0_14_1_0 + 1.84419642857144*G0_1_0_14_1_1 - 0.10848214285714*G0_1_0_15_1_0 - 0.108482142857145*G0_1_0_16_1_0 - 1.7357142857143*G0_1_0_17_1_0 - 1.84419642857144*G0_1_0_17_1_1 + 3.25446428571431*G0_1_0_18_1_0 + 2.7120535714286*G0_1_0_18_1_1 - 0.433928571428572*G0_1_0_19_1_0; + A[357] = A[273] - 2.06116071428573*G0_0_0_0_0_0 - 2.06116071428573*G0_0_0_0_0_1 + 0.433928571428576*G0_0_0_1_0_0 - 2.27812500000001*G0_0_0_3_0_0 - 0.43392857142856*G0_0_0_3_0_1 - 2.16964285714289*G0_0_0_4_0_0 - 3.57991071428576*G0_0_0_4_0_1 - 2.27812500000003*G0_0_0_5_0_0 + 2.82053571428573*G0_0_0_5_0_1 + 2.16964285714289*G0_0_0_6_0_0 - 0.759375*G0_0_0_6_0_1 + 2.38660714285714*G0_0_0_7_0_0 - 2.71205357142861*G0_0_0_7_0_1 - 0.759374999999992*G0_0_0_8_0_0 + 0.433928571428559*G0_0_0_8_0_1 + 4.55625000000003*G0_0_0_9_0_0 + 6.29196428571437*G0_0_0_9_0_1 - 2.06116071428573*G0_0_0_10_1_0 - 2.06116071428573*G0_0_0_10_1_1 + 0.433928571428576*G0_0_0_11_1_0 - 2.27812500000001*G0_0_0_13_1_0 - 0.43392857142856*G0_0_0_13_1_1 - 2.16964285714289*G0_0_0_14_1_0 - 3.57991071428576*G0_0_0_14_1_1 - 2.27812500000003*G0_0_0_15_1_0 + 2.82053571428573*G0_0_0_15_1_1 + 2.16964285714289*G0_0_0_16_1_0 - 0.759375*G0_0_0_16_1_1 + 2.38660714285714*G0_0_0_17_1_0 - 2.71205357142861*G0_0_0_17_1_1 - 0.759374999999992*G0_0_0_18_1_0 + 0.433928571428559*G0_0_0_18_1_1 + 4.55625000000003*G0_0_0_19_1_0 + 6.29196428571437*G0_0_0_19_1_1 + 0.705133928571431*G0_0_1_0_0_0 + 0.705133928571431*G0_0_1_0_0_1 - 0.596651785714283*G0_0_1_1_0_0 + 0.216964285714294*G0_0_1_2_0_1 - 0.759374999999999*G0_0_1_3_0_0 - 0.705133928571412*G0_0_1_3_0_1 - 0.867857142857163*G0_0_1_4_0_1 - 0.325446428571427*G0_0_1_5_0_0 - 0.705133928571424*G0_0_1_5_0_1 - 0.216964285714301*G0_0_1_6_0_1 - 2.44084821428574*G0_0_1_7_0_0 - 2.06116071428574*G0_0_1_7_0_1 + 2.33236607142859*G0_0_1_8_0_0 + 0.705133928571412*G0_0_1_8_0_1 + 1.08482142857143*G0_0_1_9_0_0 + 2.92901785714291*G0_0_1_9_0_1 + 0.705133928571431*G0_0_1_10_1_0 + 0.705133928571431*G0_0_1_10_1_1 - 0.596651785714283*G0_0_1_11_1_0 + 0.216964285714294*G0_0_1_12_1_1 - 0.759374999999999*G0_0_1_13_1_0 - 0.705133928571412*G0_0_1_13_1_1 - 0.867857142857163*G0_0_1_14_1_1 - 0.325446428571427*G0_0_1_15_1_0 - 0.705133928571424*G0_0_1_15_1_1 - 0.216964285714301*G0_0_1_16_1_1 - 2.44084821428574*G0_0_1_17_1_0 - 2.06116071428574*G0_0_1_17_1_1 + 2.33236607142859*G0_0_1_18_1_0 + 0.705133928571412*G0_0_1_18_1_1 + 1.08482142857143*G0_0_1_19_1_0 + 2.92901785714291*G0_0_1_19_1_1 + 0.705133928571431*G0_1_0_0_0_0 + 0.705133928571431*G0_1_0_0_0_1 - 0.596651785714283*G0_1_0_1_0_0 + 0.216964285714294*G0_1_0_2_0_1 - 0.759374999999999*G0_1_0_3_0_0 - 0.705133928571412*G0_1_0_3_0_1 - 0.867857142857163*G0_1_0_4_0_1 - 0.325446428571427*G0_1_0_5_0_0 - 0.705133928571424*G0_1_0_5_0_1 - 0.216964285714301*G0_1_0_6_0_1 - 2.44084821428574*G0_1_0_7_0_0 - 2.06116071428574*G0_1_0_7_0_1 + 2.33236607142859*G0_1_0_8_0_0 + 0.705133928571413*G0_1_0_8_0_1 + 1.08482142857143*G0_1_0_9_0_0 + 2.92901785714291*G0_1_0_9_0_1 + 0.705133928571431*G0_1_0_10_1_0 + 0.705133928571431*G0_1_0_10_1_1 - 0.596651785714283*G0_1_0_11_1_0 + 0.216964285714294*G0_1_0_12_1_1 - 0.759374999999999*G0_1_0_13_1_0 - 0.705133928571412*G0_1_0_13_1_1 - 0.867857142857163*G0_1_0_14_1_1 - 0.325446428571427*G0_1_0_15_1_0 - 0.705133928571424*G0_1_0_15_1_1 - 0.216964285714301*G0_1_0_16_1_1 - 2.44084821428574*G0_1_0_17_1_0 - 2.06116071428574*G0_1_0_17_1_1 + 2.33236607142859*G0_1_0_18_1_0 + 0.705133928571413*G0_1_0_18_1_1 + 1.08482142857143*G0_1_0_19_1_0 + 2.92901785714291*G0_1_0_19_1_1 - 0.108482142857147*G0_1_1_0_0_0 - 0.108482142857147*G0_1_1_0_0_1 - 3.57991071428574*G0_1_1_1_0_0 - 0.108482142857136*G0_1_1_2_0_1 - 1.19330357142857*G0_1_1_3_0_0 - 6.18348214285717*G0_1_1_3_0_1 + 0.108482142857145*G0_1_1_4_0_0 + 1.62723214285714*G0_1_1_4_0_1 - 1.41026785714285*G0_1_1_5_0_0 + 1.08482142857146*G0_1_1_5_0_1 - 0.108482142857145*G0_1_1_6_0_0 - 0.867857142857173*G0_1_1_6_0_1 - 3.03750000000003*G0_1_1_7_0_0 - 5.53258928571434*G0_1_1_7_0_1 + 6.72589285714291*G0_1_1_8_0_0 + 6.18348214285717*G0_1_1_8_0_1 + 2.60357142857142*G0_1_1_9_0_0 + 3.90535714285719*G0_1_1_9_0_1 - 0.108482142857147*G0_1_1_10_1_0 - 0.108482142857147*G0_1_1_10_1_1 - 3.57991071428574*G0_1_1_11_1_0 - 0.108482142857136*G0_1_1_12_1_1 - 1.19330357142857*G0_1_1_13_1_0 - 6.18348214285717*G0_1_1_13_1_1 + 0.108482142857145*G0_1_1_14_1_0 + 1.62723214285714*G0_1_1_14_1_1 - 1.41026785714285*G0_1_1_15_1_0 + 1.08482142857146*G0_1_1_15_1_1 - 0.108482142857145*G0_1_1_16_1_0 - 0.867857142857173*G0_1_1_16_1_1 - 3.03750000000003*G0_1_1_17_1_0 - 5.53258928571434*G0_1_1_17_1_1 + 6.72589285714291*G0_1_1_18_1_0 + 6.18348214285717*G0_1_1_18_1_1 + 2.60357142857142*G0_1_1_19_1_0 + 3.90535714285719*G0_1_1_19_1_1; + A[315] = A[357] + 1.84419642857144*G0_0_0_0_0_0 + 1.84419642857145*G0_0_0_0_0_1 - 0.65089285714286*G0_0_0_1_0_0 - 1.62723214285717*G0_0_0_3_0_0 - 1.9526785714286*G0_0_0_3_0_1 + 2.16964285714289*G0_0_0_4_0_0 + 1.84419642857145*G0_0_0_4_0_1 - 1.62723214285716*G0_0_0_5_0_0 - 4.33928571428576*G0_0_0_5_0_1 - 2.16964285714289*G0_0_0_6_0_0 + 2.49508928571431*G0_0_0_6_0_1 - 2.16964285714286*G0_0_0_7_0_0 + 0.542410714285734*G0_0_0_7_0_1 + 0.976339285714277*G0_0_0_8_0_0 + 1.9526785714286*G0_0_0_8_0_1 + 3.25446428571433*G0_0_0_9_0_0 - 2.38660714285719*G0_0_0_9_0_1 + 1.84419642857144*G0_0_0_10_1_0 + 1.84419642857145*G0_0_0_10_1_1 - 0.65089285714286*G0_0_0_11_1_0 - 1.62723214285717*G0_0_0_13_1_0 - 1.9526785714286*G0_0_0_13_1_1 + 2.16964285714289*G0_0_0_14_1_0 + 1.84419642857145*G0_0_0_14_1_1 - 1.62723214285716*G0_0_0_15_1_0 - 4.33928571428576*G0_0_0_15_1_1 - 2.16964285714289*G0_0_0_16_1_0 + 2.49508928571431*G0_0_0_16_1_1 - 2.16964285714286*G0_0_0_17_1_0 + 0.542410714285734*G0_0_0_17_1_1 + 0.976339285714277*G0_0_0_18_1_0 + 1.9526785714286*G0_0_0_18_1_1 + 3.25446428571433*G0_0_0_19_1_0 - 2.38660714285719*G0_0_0_19_1_1 - 0.325446428571431*G0_0_1_1_0_0 + 0.325446428571432*G0_0_1_2_0_1 - 1.73571428571431*G0_0_1_3_0_0 - 2.06116071428574*G0_0_1_3_0_1 + 2.06116071428574*G0_0_1_4_0_0 + 1.73571428571431*G0_0_1_4_0_1 - 1.08482142857145*G0_0_1_5_0_0 - 1.08482142857145*G0_0_1_5_0_1 - 2.06116071428575*G0_0_1_6_0_0 + 0.759375000000015*G0_0_1_6_0_1 + 1.08482142857145*G0_0_1_7_0_0 + 1.08482142857145*G0_0_1_7_0_1 - 0.75937500000002*G0_0_1_8_0_0 + 2.06116071428574*G0_0_1_8_0_1 + 2.82053571428576*G0_0_1_9_0_0 - 2.82053571428576*G0_0_1_9_0_1 - 0.325446428571431*G0_0_1_11_1_0 + 0.325446428571432*G0_0_1_12_1_1 - 1.73571428571431*G0_0_1_13_1_0 - 2.06116071428574*G0_0_1_13_1_1 + 2.06116071428574*G0_0_1_14_1_0 + 1.73571428571431*G0_0_1_14_1_1 - 1.08482142857145*G0_0_1_15_1_0 - 1.08482142857145*G0_0_1_15_1_1 - 2.06116071428575*G0_0_1_16_1_0 + 0.759375000000015*G0_0_1_16_1_1 + 1.08482142857145*G0_0_1_17_1_0 + 1.08482142857145*G0_0_1_17_1_1 - 0.75937500000002*G0_0_1_18_1_0 + 2.06116071428574*G0_0_1_18_1_1 + 2.82053571428576*G0_0_1_19_1_0 - 2.82053571428576*G0_0_1_19_1_1 - 0.325446428571431*G0_1_0_1_0_0 + 0.325446428571432*G0_1_0_2_0_1 - 1.73571428571431*G0_1_0_3_0_0 - 2.06116071428574*G0_1_0_3_0_1 + 2.06116071428574*G0_1_0_4_0_0 + 1.73571428571431*G0_1_0_4_0_1 - 1.08482142857145*G0_1_0_5_0_0 - 1.08482142857145*G0_1_0_5_0_1 - 2.06116071428575*G0_1_0_6_0_0 + 0.759375000000015*G0_1_0_6_0_1 + 1.08482142857145*G0_1_0_7_0_0 + 1.08482142857145*G0_1_0_7_0_1 - 0.75937500000002*G0_1_0_8_0_0 + 2.06116071428574*G0_1_0_8_0_1 + 2.82053571428576*G0_1_0_9_0_0 - 2.82053571428576*G0_1_0_9_0_1 - 0.325446428571431*G0_1_0_11_1_0 + 0.325446428571432*G0_1_0_12_1_1 - 1.73571428571431*G0_1_0_13_1_0 - 2.06116071428574*G0_1_0_13_1_1 + 2.06116071428574*G0_1_0_14_1_0 + 1.73571428571431*G0_1_0_14_1_1 - 1.08482142857145*G0_1_0_15_1_0 - 1.08482142857145*G0_1_0_15_1_1 - 2.06116071428575*G0_1_0_16_1_0 + 0.759375000000015*G0_1_0_16_1_1 + 1.08482142857145*G0_1_0_17_1_0 + 1.08482142857145*G0_1_0_17_1_1 - 0.75937500000002*G0_1_0_18_1_0 + 2.06116071428574*G0_1_0_18_1_1 + 2.82053571428576*G0_1_0_19_1_0 - 2.82053571428576*G0_1_0_19_1_1 - 1.84419642857145*G0_1_1_0_0_0 - 1.84419642857145*G0_1_1_0_0_1 + 0.650892857142862*G0_1_1_2_0_1 - 1.84419642857145*G0_1_1_3_0_0 - 2.16964285714289*G0_1_1_3_0_1 + 1.9526785714286*G0_1_1_4_0_0 + 1.62723214285717*G0_1_1_4_0_1 - 0.54241071428573*G0_1_1_5_0_0 + 2.16964285714287*G0_1_1_5_0_1 - 1.9526785714286*G0_1_1_6_0_0 - 0.976339285714286*G0_1_1_6_0_1 + 4.33928571428577*G0_1_1_7_0_0 + 1.62723214285717*G0_1_1_7_0_1 - 2.49508928571432*G0_1_1_8_0_0 + 2.16964285714289*G0_1_1_8_0_1 + 2.38660714285718*G0_1_1_9_0_0 - 3.25446428571434*G0_1_1_9_0_1 - 1.84419642857145*G0_1_1_10_1_0 - 1.84419642857145*G0_1_1_10_1_1 + 0.650892857142862*G0_1_1_12_1_1 - 1.84419642857145*G0_1_1_13_1_0 - 2.16964285714289*G0_1_1_13_1_1 + 1.9526785714286*G0_1_1_14_1_0 + 1.62723214285717*G0_1_1_14_1_1 - 0.54241071428573*G0_1_1_15_1_0 + 2.16964285714287*G0_1_1_15_1_1 - 1.9526785714286*G0_1_1_16_1_0 - 0.976339285714286*G0_1_1_16_1_1 + 4.33928571428577*G0_1_1_17_1_0 + 1.62723214285717*G0_1_1_17_1_1 - 2.49508928571432*G0_1_1_18_1_0 + 2.16964285714289*G0_1_1_18_1_1 + 2.38660714285718*G0_1_1_19_1_0 - 3.25446428571434*G0_1_1_19_1_1; + A[294] = A[315] + 0.108482142857144*G0_0_0_0_0_0 + 0.108482142857144*G0_0_0_0_0_1 + 0.108482142857139*G0_0_0_1_0_0 + 3.57991071428575*G0_0_0_2_0_1 - 1.62723214285715*G0_0_0_3_0_0 - 0.108482142857144*G0_0_0_3_0_1 + 6.18348214285719*G0_0_0_4_0_0 + 1.19330357142857*G0_0_0_4_0_1 + 5.53258928571435*G0_0_0_5_0_0 + 3.03750000000004*G0_0_0_5_0_1 - 6.18348214285719*G0_0_0_6_0_0 - 6.72589285714293*G0_0_0_6_0_1 - 1.08482142857145*G0_0_0_7_0_0 + 1.41026785714285*G0_0_0_7_0_1 + 0.867857142857169*G0_0_0_8_0_0 + 0.108482142857143*G0_0_0_8_0_1 - 3.90535714285719*G0_0_0_9_0_0 - 2.60357142857143*G0_0_0_9_0_1 + 0.108482142857144*G0_0_0_10_1_0 + 0.108482142857144*G0_0_0_10_1_1 + 0.108482142857139*G0_0_0_11_1_0 + 3.57991071428575*G0_0_0_12_1_1 - 1.62723214285715*G0_0_0_13_1_0 - 0.108482142857144*G0_0_0_13_1_1 + 6.18348214285719*G0_0_0_14_1_0 + 1.19330357142857*G0_0_0_14_1_1 + 5.53258928571435*G0_0_0_15_1_0 + 3.03750000000004*G0_0_0_15_1_1 - 6.18348214285719*G0_0_0_16_1_0 - 6.72589285714293*G0_0_0_16_1_1 - 1.08482142857145*G0_0_0_17_1_0 + 1.41026785714285*G0_0_0_17_1_1 + 0.867857142857169*G0_0_0_18_1_0 + 0.108482142857143*G0_0_0_18_1_1 - 3.90535714285719*G0_0_0_19_1_0 - 2.60357142857143*G0_0_0_19_1_1 - 0.705133928571433*G0_0_1_0_0_0 - 0.705133928571433*G0_0_1_0_0_1 - 0.216964285714293*G0_0_1_1_0_0 + 0.596651785714284*G0_0_1_2_0_1 + 0.867857142857163*G0_0_1_3_0_0 + 0.705133928571415*G0_0_1_4_0_0 + 0.759375000000001*G0_0_1_4_0_1 + 2.06116071428574*G0_0_1_5_0_0 + 2.44084821428574*G0_0_1_5_0_1 - 0.705133928571415*G0_0_1_6_0_0 - 2.33236607142859*G0_0_1_6_0_1 + 0.705133928571426*G0_0_1_7_0_0 + 0.325446428571427*G0_0_1_7_0_1 + 0.216964285714299*G0_0_1_8_0_0 - 2.92901785714291*G0_0_1_9_0_0 - 1.08482142857143*G0_0_1_9_0_1 - 0.705133928571433*G0_0_1_10_1_0 - 0.705133928571433*G0_0_1_10_1_1 - 0.216964285714293*G0_0_1_11_1_0 + 0.596651785714284*G0_0_1_12_1_1 + 0.867857142857163*G0_0_1_13_1_0 + 0.705133928571415*G0_0_1_14_1_0 + 0.759375000000001*G0_0_1_14_1_1 + 2.06116071428574*G0_0_1_15_1_0 + 2.44084821428574*G0_0_1_15_1_1 - 0.705133928571415*G0_0_1_16_1_0 - 2.33236607142859*G0_0_1_16_1_1 + 0.705133928571426*G0_0_1_17_1_0 + 0.325446428571427*G0_0_1_17_1_1 + 0.216964285714299*G0_0_1_18_1_0 - 2.92901785714291*G0_0_1_19_1_0 - 1.08482142857143*G0_0_1_19_1_1 - 0.705133928571433*G0_1_0_0_0_0 - 0.705133928571433*G0_1_0_0_0_1 - 0.216964285714293*G0_1_0_1_0_0 + 0.596651785714284*G0_1_0_2_0_1 + 0.867857142857163*G0_1_0_3_0_0 + 0.705133928571415*G0_1_0_4_0_0 + 0.759375000000001*G0_1_0_4_0_1 + 2.06116071428574*G0_1_0_5_0_0 + 2.44084821428574*G0_1_0_5_0_1 - 0.705133928571415*G0_1_0_6_0_0 - 2.33236607142859*G0_1_0_6_0_1 + 0.705133928571426*G0_1_0_7_0_0 + 0.325446428571427*G0_1_0_7_0_1 + 0.2169642857143*G0_1_0_8_0_0 - 2.92901785714291*G0_1_0_9_0_0 - 1.08482142857143*G0_1_0_9_0_1 - 0.705133928571433*G0_1_0_10_1_0 - 0.705133928571433*G0_1_0_10_1_1 - 0.216964285714293*G0_1_0_11_1_0 + 0.596651785714284*G0_1_0_12_1_1 + 0.867857142857163*G0_1_0_13_1_0 + 0.705133928571415*G0_1_0_14_1_0 + 0.759375000000001*G0_1_0_14_1_1 + 2.06116071428574*G0_1_0_15_1_0 + 2.44084821428574*G0_1_0_15_1_1 - 0.705133928571415*G0_1_0_16_1_0 - 2.33236607142859*G0_1_0_16_1_1 + 0.705133928571426*G0_1_0_17_1_0 + 0.325446428571427*G0_1_0_17_1_1 + 0.2169642857143*G0_1_0_18_1_0 - 2.92901785714291*G0_1_0_19_1_0 - 1.08482142857143*G0_1_0_19_1_1 + 2.06116071428573*G0_1_1_0_0_0 + 2.06116071428573*G0_1_1_0_0_1 - 0.433928571428579*G0_1_1_2_0_1 + 3.57991071428576*G0_1_1_3_0_0 + 2.16964285714288*G0_1_1_3_0_1 + 0.433928571428562*G0_1_1_4_0_0 + 2.27812500000002*G0_1_1_4_0_1 + 2.71205357142861*G0_1_1_5_0_0 - 2.38660714285715*G0_1_1_5_0_1 - 0.433928571428561*G0_1_1_6_0_0 + 0.759375000000001*G0_1_1_6_0_1 - 2.82053571428573*G0_1_1_7_0_0 + 2.27812500000002*G0_1_1_7_0_1 + 0.759375000000003*G0_1_1_8_0_0 - 2.16964285714288*G0_1_1_8_0_1 - 6.29196428571437*G0_1_1_9_0_0 - 4.55625000000004*G0_1_1_9_0_1 + 2.06116071428573*G0_1_1_10_1_0 + 2.06116071428573*G0_1_1_10_1_1 - 0.433928571428579*G0_1_1_12_1_1 + 3.57991071428576*G0_1_1_13_1_0 + 2.16964285714288*G0_1_1_13_1_1 + 0.433928571428562*G0_1_1_14_1_0 + 2.27812500000002*G0_1_1_14_1_1 + 2.71205357142861*G0_1_1_15_1_0 - 2.38660714285715*G0_1_1_15_1_1 - 0.433928571428561*G0_1_1_16_1_0 + 0.759375000000001*G0_1_1_16_1_1 - 2.82053571428573*G0_1_1_17_1_0 + 2.27812500000002*G0_1_1_17_1_1 + 0.759375000000003*G0_1_1_18_1_0 - 2.16964285714288*G0_1_1_18_1_1 - 6.29196428571437*G0_1_1_19_1_0 - 4.55625000000004*G0_1_1_19_1_1; + A[378] = -A[278] - 0.765401785714298*G0_0_0_0_0_0 - 0.765401785714298*G0_0_0_0_0_1 + 1.68750000000002*G0_0_0_1_0_0 + 0.439955357142867*G0_0_0_2_0_1 + 0.542410714285688*G0_0_0_3_0_0 + 3.25446428571431*G0_0_0_3_0_1 + 0.0542410714285764*G0_0_0_4_0_0 - 1.41026785714289*G0_0_0_4_0_1 - 1.9526785714286*G0_0_0_5_0_0 + 0.162723214285717*G0_0_0_5_0_1 - 0.0542410714285763*G0_0_0_6_0_0 + 0.162723214285713*G0_0_0_6_0_1 + 0.705133928571446*G0_0_0_7_0_0 - 1.41026785714287*G0_0_0_7_0_1 - 1.62723214285717*G0_0_0_8_0_0 - 3.25446428571431*G0_0_0_8_0_1 + 1.41026785714291*G0_0_0_9_0_0 + 2.82053571428577*G0_0_0_9_0_1 - 0.765401785714298*G0_0_0_10_1_0 - 0.765401785714298*G0_0_0_10_1_1 + 1.68750000000002*G0_0_0_11_1_0 + 0.439955357142867*G0_0_0_12_1_1 + 0.542410714285688*G0_0_0_13_1_0 + 3.25446428571431*G0_0_0_13_1_1 + 0.0542410714285764*G0_0_0_14_1_0 - 1.41026785714289*G0_0_0_14_1_1 - 1.9526785714286*G0_0_0_15_1_0 + 0.162723214285717*G0_0_0_15_1_1 - 0.0542410714285763*G0_0_0_16_1_0 + 0.162723214285713*G0_0_0_16_1_1 + 0.705133928571446*G0_0_0_17_1_0 - 1.41026785714287*G0_0_0_17_1_1 - 1.62723214285717*G0_0_0_18_1_0 - 3.25446428571431*G0_0_0_18_1_1 + 1.41026785714291*G0_0_0_19_1_0 + 2.82053571428577*G0_0_0_19_1_1 - 0.325446428571431*G0_0_1_0_0_0 - 0.32544642857143*G0_0_1_0_0_1 + 1.84419642857145*G0_0_1_1_0_0 + 0.32544642857143*G0_0_1_2_0_1 - 0.542410714285712*G0_0_1_3_0_0 + 2.7120535714286*G0_0_1_3_0_1 - 0.108482142857146*G0_0_1_4_0_0 - 1.84419642857144*G0_0_1_4_0_1 + 0.108482142857141*G0_0_1_5_0_0 + 0.108482142857145*G0_0_1_6_0_0 + 1.7357142857143*G0_0_1_7_0_0 + 1.84419642857144*G0_0_1_7_0_1 - 3.25446428571431*G0_0_1_8_0_0 - 2.7120535714286*G0_0_1_8_0_1 + 0.433928571428571*G0_0_1_9_0_0 - 0.325446428571431*G0_0_1_10_1_0 - 0.32544642857143*G0_0_1_10_1_1 + 1.84419642857145*G0_0_1_11_1_0 + 0.32544642857143*G0_0_1_12_1_1 - 0.542410714285712*G0_0_1_13_1_0 + 2.7120535714286*G0_0_1_13_1_1 - 0.108482142857146*G0_0_1_14_1_0 - 1.84419642857144*G0_0_1_14_1_1 + 0.108482142857141*G0_0_1_15_1_0 + 0.108482142857145*G0_0_1_16_1_0 + 1.7357142857143*G0_0_1_17_1_0 + 1.84419642857144*G0_0_1_17_1_1 - 3.25446428571431*G0_0_1_18_1_0 - 2.7120535714286*G0_0_1_18_1_1 + 0.433928571428571*G0_0_1_19_1_0; + A[63] = A[273]; + A[84] = A[294]; + A[373] = A[278] + 0.32544642857143*G0_0_1_0_0_0 + 0.32544642857143*G0_0_1_0_0_1 - 1.84419642857144*G0_0_1_1_0_0 - 0.325446428571429*G0_0_1_2_0_1 + 0.542410714285712*G0_0_1_3_0_0 - 2.7120535714286*G0_0_1_3_0_1 + 0.108482142857145*G0_0_1_4_0_0 + 1.84419642857144*G0_0_1_4_0_1 - 0.108482142857141*G0_0_1_5_0_0 - 0.108482142857145*G0_0_1_6_0_0 - 1.7357142857143*G0_0_1_7_0_0 - 1.84419642857144*G0_0_1_7_0_1 + 3.25446428571431*G0_0_1_8_0_0 + 2.7120535714286*G0_0_1_8_0_1 - 0.433928571428572*G0_0_1_9_0_0 + 0.32544642857143*G0_0_1_10_1_0 + 0.32544642857143*G0_0_1_10_1_1 - 1.84419642857144*G0_0_1_11_1_0 - 0.325446428571429*G0_0_1_12_1_1 + 0.542410714285712*G0_0_1_13_1_0 - 2.7120535714286*G0_0_1_13_1_1 + 0.108482142857145*G0_0_1_14_1_0 + 1.84419642857144*G0_0_1_14_1_1 - 0.108482142857141*G0_0_1_15_1_0 - 0.108482142857145*G0_0_1_16_1_0 - 1.7357142857143*G0_0_1_17_1_0 - 1.84419642857144*G0_0_1_17_1_1 + 3.25446428571431*G0_0_1_18_1_0 + 2.7120535714286*G0_0_1_18_1_1 - 0.433928571428572*G0_0_1_19_1_0 - 0.32544642857143*G0_1_0_0_0_0 - 0.32544642857143*G0_1_0_0_0_1 + 1.84419642857144*G0_1_0_1_0_0 + 0.325446428571429*G0_1_0_2_0_1 - 0.542410714285712*G0_1_0_3_0_0 + 2.7120535714286*G0_1_0_3_0_1 - 0.108482142857145*G0_1_0_4_0_0 - 1.84419642857144*G0_1_0_4_0_1 + 0.108482142857141*G0_1_0_5_0_0 + 0.108482142857145*G0_1_0_6_0_0 + 1.7357142857143*G0_1_0_7_0_0 + 1.84419642857144*G0_1_0_7_0_1 - 3.25446428571431*G0_1_0_8_0_0 - 2.7120535714286*G0_1_0_8_0_1 + 0.433928571428572*G0_1_0_9_0_0 - 0.32544642857143*G0_1_0_10_1_0 - 0.32544642857143*G0_1_0_10_1_1 + 1.84419642857144*G0_1_0_11_1_0 + 0.325446428571429*G0_1_0_12_1_1 - 0.542410714285712*G0_1_0_13_1_0 + 2.7120535714286*G0_1_0_13_1_1 - 0.108482142857145*G0_1_0_14_1_0 - 1.84419642857144*G0_1_0_14_1_1 + 0.108482142857141*G0_1_0_15_1_0 + 0.108482142857145*G0_1_0_16_1_0 + 1.7357142857143*G0_1_0_17_1_0 + 1.84419642857144*G0_1_0_17_1_1 - 3.25446428571431*G0_1_0_18_1_0 - 2.7120535714286*G0_1_0_18_1_1 + 0.433928571428572*G0_1_0_19_1_0; + A[68] = A[278]; + A[376] = -A[65] - 0.120535714285718*G0_0_0_0_0_0 - 0.120535714285718*G0_0_0_0_0_1 + 0.174776785714291*G0_0_0_1_0_0 - 0.313392857142857*G0_0_0_2_0_1 + 0.379687500000012*G0_0_0_3_0_0 + 0.162723214285721*G0_0_0_3_0_1 + 0.705133928571458*G0_0_0_4_0_1 - 0.922098214285735*G0_0_0_5_0_0 - 0.596651785714299*G0_0_0_5_0_1 + 1.03058035714287*G0_0_0_6_0_1 + 0.705133928571446*G0_0_0_7_0_0 + 0.379687500000009*G0_0_0_7_0_1 - 0.759375000000019*G0_0_0_8_0_0 - 0.16272321428572*G0_0_0_8_0_1 + 0.542410714285724*G0_0_0_9_0_0 - 1.08482142857147*G0_0_0_9_0_1 - 0.120535714285718*G0_0_0_10_1_0 - 0.120535714285718*G0_0_0_10_1_1 + 0.174776785714291*G0_0_0_11_1_0 - 0.313392857142857*G0_0_0_12_1_1 + 0.379687500000012*G0_0_0_13_1_0 + 0.162723214285721*G0_0_0_13_1_1 + 0.705133928571458*G0_0_0_14_1_1 - 0.922098214285735*G0_0_0_15_1_0 - 0.596651785714299*G0_0_0_15_1_1 + 1.03058035714287*G0_0_0_16_1_1 + 0.705133928571446*G0_0_0_17_1_0 + 0.379687500000009*G0_0_0_17_1_1 - 0.759375000000019*G0_0_0_18_1_0 - 0.16272321428572*G0_0_0_18_1_1 + 0.542410714285724*G0_0_0_19_1_0 - 1.08482142857147*G0_0_0_19_1_1 - 0.162723214285715*G0_0_1_0_0_0 - 0.162723214285715*G0_0_1_0_0_1 - 0.325446428571432*G0_0_1_2_0_1 + 0.705133928571454*G0_0_1_3_0_0 - 0.108482142857133*G0_0_1_4_0_0 + 0.922098214285748*G0_0_1_4_0_1 + 0.0542410714285849*G0_0_1_5_0_0 + 0.108482142857133*G0_0_1_6_0_0 + 0.488169642857148*G0_0_1_6_0_1 + 0.867857142857161*G0_0_1_7_0_0 + 0.922098214285746*G0_0_1_7_0_1 - 0.705133928571447*G0_0_1_8_0_0 - 0.759375000000039*G0_0_1_9_0_0 - 1.84419642857149*G0_0_1_9_0_1 - 0.162723214285715*G0_0_1_10_1_0 - 0.162723214285715*G0_0_1_10_1_1 - 0.325446428571432*G0_0_1_12_1_1 + 0.705133928571454*G0_0_1_13_1_0 - 0.108482142857133*G0_0_1_14_1_0 + 0.922098214285748*G0_0_1_14_1_1 + 0.0542410714285849*G0_0_1_15_1_0 + 0.108482142857133*G0_0_1_16_1_0 + 0.488169642857148*G0_0_1_16_1_1 + 0.867857142857161*G0_0_1_17_1_0 + 0.922098214285746*G0_0_1_17_1_1 - 0.705133928571447*G0_0_1_18_1_0 - 0.759375000000039*G0_0_1_19_1_0 - 1.84419642857149*G0_0_1_19_1_1 - 0.108482142857144*G0_1_0_0_0_0 - 0.108482142857144*G0_1_0_0_0_1 - 0.271205357142858*G0_1_0_2_0_1 + 0.271205357142866*G0_1_0_3_0_0 - 0.379687499999998*G0_1_0_4_0_0 + 0.162723214285723*G0_1_0_4_0_1 - 0.271205357142854*G0_1_0_5_0_0 - 0.0542410714285692*G0_1_0_5_0_1 + 0.379687499999998*G0_1_0_6_0_0 + 0.433928571428571*G0_1_0_6_0_1 + 0.379687500000005*G0_1_0_7_0_0 + 0.16272321428572*G0_1_0_7_0_1 - 0.271205357142861*G0_1_0_8_0_0 - 0.325446428571444*G0_1_0_9_0_1 - 0.108482142857144*G0_1_0_10_1_0 - 0.108482142857144*G0_1_0_10_1_1 - 0.271205357142858*G0_1_0_12_1_1 + 0.271205357142866*G0_1_0_13_1_0 - 0.379687499999998*G0_1_0_14_1_0 + 0.162723214285723*G0_1_0_14_1_1 - 0.271205357142854*G0_1_0_15_1_0 - 0.0542410714285692*G0_1_0_15_1_1 + 0.379687499999998*G0_1_0_16_1_0 + 0.433928571428571*G0_1_0_16_1_1 + 0.379687500000005*G0_1_0_17_1_0 + 0.16272321428572*G0_1_0_17_1_1 - 0.271205357142861*G0_1_0_18_1_0 - 0.325446428571444*G0_1_0_19_1_1 + 0.162723214285713*G0_1_1_0_0_0 + 0.162723214285713*G0_1_1_0_0_1 - 0.162723214285714*G0_1_1_2_0_1 - 0.162723214285714*G0_1_1_4_0_0 - 0.325446428571427*G0_1_1_5_0_0 - 0.488169642857141*G0_1_1_5_0_1 + 0.162723214285715*G0_1_1_6_0_0 + 0.488169642857141*G0_1_1_6_0_1 - 0.162723214285715*G0_1_1_7_0_0 + 0.325446428571417*G0_1_1_9_0_0 + 0.162723214285713*G0_1_1_10_1_0 + 0.162723214285713*G0_1_1_10_1_1 - 0.162723214285714*G0_1_1_12_1_1 - 0.162723214285714*G0_1_1_14_1_0 - 0.325446428571427*G0_1_1_15_1_0 - 0.488169642857141*G0_1_1_15_1_1 + 0.162723214285715*G0_1_1_16_1_0 + 0.488169642857141*G0_1_1_16_1_1 - 0.162723214285715*G0_1_1_17_1_0 + 0.325446428571417*G0_1_1_19_1_0; + A[144] = -A[376] + 0.162723214285715*G0_0_0_0_0_0 + 0.162723214285715*G0_0_0_0_0_1 - 0.162723214285715*G0_0_0_1_0_0 - 0.162723214285716*G0_0_0_3_0_1 - 0.162723214285716*G0_0_0_5_0_1 - 0.488169642857144*G0_0_0_7_0_0 - 0.325446428571427*G0_0_0_7_0_1 + 0.488169642857144*G0_0_0_8_0_0 + 0.162723214285716*G0_0_0_8_0_1 + 0.325446428571413*G0_0_0_9_0_1 + 0.162723214285715*G0_0_0_10_1_0 + 0.162723214285715*G0_0_0_10_1_1 - 0.162723214285715*G0_0_0_11_1_0 - 0.162723214285716*G0_0_0_13_1_1 - 0.162723214285716*G0_0_0_15_1_1 - 0.488169642857144*G0_0_0_17_1_0 - 0.325446428571427*G0_0_0_17_1_1 + 0.488169642857144*G0_0_0_18_1_0 + 0.162723214285716*G0_0_0_18_1_1 + 0.325446428571413*G0_0_0_19_1_1 - 0.162723214285716*G0_0_1_0_0_0 - 0.162723214285716*G0_0_1_0_0_1 - 0.325446428571431*G0_0_1_1_0_0 + 0.922098214285747*G0_0_1_3_0_0 - 0.108482142857132*G0_0_1_3_0_1 + 0.705133928571455*G0_0_1_4_0_1 + 0.922098214285747*G0_0_1_5_0_0 + 0.867857142857162*G0_0_1_5_0_1 - 0.705133928571448*G0_0_1_6_0_1 + 0.0542410714285857*G0_0_1_7_0_1 + 0.488169642857146*G0_0_1_8_0_0 + 0.108482142857131*G0_0_1_8_0_1 - 1.84419642857149*G0_0_1_9_0_0 - 0.75937500000004*G0_0_1_9_0_1 - 0.162723214285716*G0_0_1_10_1_0 - 0.162723214285716*G0_0_1_10_1_1 - 0.325446428571431*G0_0_1_11_1_0 + 0.922098214285747*G0_0_1_13_1_0 - 0.108482142857132*G0_0_1_13_1_1 + 0.705133928571455*G0_0_1_14_1_1 + 0.922098214285747*G0_0_1_15_1_0 + 0.867857142857162*G0_0_1_15_1_1 - 0.705133928571448*G0_0_1_16_1_1 + 0.0542410714285857*G0_0_1_17_1_1 + 0.488169642857146*G0_0_1_18_1_0 + 0.108482142857131*G0_0_1_18_1_1 - 1.84419642857149*G0_0_1_19_1_0 - 0.75937500000004*G0_0_1_19_1_1 - 0.108482142857145*G0_1_0_0_0_0 - 0.108482142857145*G0_1_0_0_0_1 - 0.271205357142859*G0_1_0_1_0_0 + 0.16272321428572*G0_1_0_3_0_0 - 0.379687500000001*G0_1_0_3_0_1 + 0.271205357142869*G0_1_0_4_0_1 + 0.162723214285721*G0_1_0_5_0_0 + 0.379687500000007*G0_1_0_5_0_1 - 0.271205357142865*G0_1_0_6_0_1 - 0.0542410714285697*G0_1_0_7_0_0 - 0.271205357142855*G0_1_0_7_0_1 + 0.433928571428573*G0_1_0_8_0_0 + 0.379687500000002*G0_1_0_8_0_1 - 0.325446428571441*G0_1_0_9_0_0 - 0.108482142857145*G0_1_0_10_1_0 - 0.108482142857145*G0_1_0_10_1_1 - 0.271205357142859*G0_1_0_11_1_0 + 0.16272321428572*G0_1_0_13_1_0 - 0.379687500000001*G0_1_0_13_1_1 + 0.271205357142869*G0_1_0_14_1_1 + 0.162723214285721*G0_1_0_15_1_0 + 0.379687500000007*G0_1_0_15_1_1 - 0.271205357142865*G0_1_0_16_1_1 - 0.0542410714285697*G0_1_0_17_1_0 - 0.271205357142855*G0_1_0_17_1_1 + 0.433928571428573*G0_1_0_18_1_0 + 0.379687500000002*G0_1_0_18_1_1 - 0.325446428571441*G0_1_0_19_1_0 - 0.120535714285719*G0_1_1_0_0_0 - 0.12053571428572*G0_1_1_0_0_1 - 0.313392857142856*G0_1_1_1_0_0 + 0.174776785714293*G0_1_1_2_0_1 + 0.705133928571457*G0_1_1_3_0_0 + 0.162723214285723*G0_1_1_4_0_0 + 0.37968750000001*G0_1_1_4_0_1 + 0.37968750000001*G0_1_1_5_0_0 + 0.705133928571448*G0_1_1_5_0_1 - 0.162723214285723*G0_1_1_6_0_0 - 0.759375000000022*G0_1_1_6_0_1 - 0.596651785714298*G0_1_1_7_0_0 - 0.922098214285737*G0_1_1_7_0_1 + 1.03058035714287*G0_1_1_8_0_0 - 1.08482142857147*G0_1_1_9_0_0 + 0.542410714285728*G0_1_1_9_0_1 - 0.120535714285719*G0_1_1_10_1_0 - 0.12053571428572*G0_1_1_10_1_1 - 0.313392857142856*G0_1_1_11_1_0 + 0.174776785714293*G0_1_1_12_1_1 + 0.705133928571457*G0_1_1_13_1_0 + 0.162723214285723*G0_1_1_14_1_0 + 0.37968750000001*G0_1_1_14_1_1 + 0.37968750000001*G0_1_1_15_1_0 + 0.705133928571448*G0_1_1_15_1_1 - 0.162723214285723*G0_1_1_16_1_0 - 0.759375000000022*G0_1_1_16_1_1 - 0.596651785714298*G0_1_1_17_1_0 - 0.922098214285737*G0_1_1_17_1_1 + 1.03058035714287*G0_1_1_18_1_0 - 1.08482142857147*G0_1_1_19_1_0 + 0.542410714285728*G0_1_1_19_1_1; + A[87] = A[144] - 0.0542410714285714*G0_0_1_0_0_0 - 0.0542410714285714*G0_0_1_0_0_1 + 0.108482142857143*G0_0_1_1_0_0 + 0.0542410714285709*G0_0_1_2_0_1 - 0.433928571428595*G0_0_1_3_0_0 - 0.108482142857157*G0_0_1_3_0_1 + 0.162723214285713*G0_0_1_4_0_0 - 0.108482142857153*G0_0_1_4_0_1 - 0.325446428571434*G0_0_1_5_0_0 - 0.162723214285719*G0_0_1_5_0_1 - 0.162723214285713*G0_0_1_6_0_0 + 0.162723214285719*G0_0_1_6_0_1 + 0.271205357142866*G0_0_1_7_0_0 + 0.108482142857152*G0_0_1_7_0_1 - 0.325446428571437*G0_0_1_8_0_0 + 0.108482142857157*G0_0_1_8_0_1 + 0.759375000000029*G0_0_1_9_0_0 - 0.0542410714285714*G0_0_1_10_1_0 - 0.0542410714285714*G0_0_1_10_1_1 + 0.108482142857143*G0_0_1_11_1_0 + 0.0542410714285709*G0_0_1_12_1_1 - 0.433928571428595*G0_0_1_13_1_0 - 0.108482142857157*G0_0_1_13_1_1 + 0.162723214285713*G0_0_1_14_1_0 - 0.108482142857153*G0_0_1_14_1_1 - 0.325446428571434*G0_0_1_15_1_0 - 0.162723214285719*G0_0_1_15_1_1 - 0.162723214285713*G0_0_1_16_1_0 + 0.162723214285719*G0_0_1_16_1_1 + 0.271205357142866*G0_0_1_17_1_0 + 0.108482142857152*G0_0_1_17_1_1 - 0.325446428571437*G0_0_1_18_1_0 + 0.108482142857157*G0_0_1_18_1_1 + 0.759375000000029*G0_0_1_19_1_0 + 0.0542410714285714*G0_1_0_0_0_0 + 0.0542410714285714*G0_1_0_0_0_1 - 0.108482142857143*G0_1_0_1_0_0 - 0.0542410714285709*G0_1_0_2_0_1 + 0.433928571428595*G0_1_0_3_0_0 + 0.108482142857157*G0_1_0_3_0_1 - 0.162723214285713*G0_1_0_4_0_0 + 0.108482142857153*G0_1_0_4_0_1 + 0.325446428571434*G0_1_0_5_0_0 + 0.162723214285719*G0_1_0_5_0_1 + 0.162723214285713*G0_1_0_6_0_0 - 0.162723214285719*G0_1_0_6_0_1 - 0.271205357142866*G0_1_0_7_0_0 - 0.108482142857152*G0_1_0_7_0_1 + 0.325446428571437*G0_1_0_8_0_0 - 0.108482142857157*G0_1_0_8_0_1 - 0.759375000000028*G0_1_0_9_0_0 + 0.0542410714285714*G0_1_0_10_1_0 + 0.0542410714285714*G0_1_0_10_1_1 - 0.108482142857143*G0_1_0_11_1_0 - 0.0542410714285709*G0_1_0_12_1_1 + 0.433928571428595*G0_1_0_13_1_0 + 0.108482142857157*G0_1_0_13_1_1 - 0.162723214285713*G0_1_0_14_1_0 + 0.108482142857153*G0_1_0_14_1_1 + 0.325446428571434*G0_1_0_15_1_0 + 0.162723214285719*G0_1_0_15_1_1 + 0.162723214285713*G0_1_0_16_1_0 - 0.162723214285719*G0_1_0_16_1_1 - 0.271205357142866*G0_1_0_17_1_0 - 0.108482142857152*G0_1_0_17_1_1 + 0.325446428571437*G0_1_0_18_1_0 - 0.108482142857157*G0_1_0_18_1_1 - 0.759375000000028*G0_1_0_19_1_0; + A[297] = A[87]; + A[127] = -A[87] + 0.705133928571434*G0_1_0_0_0_0 + 0.705133928571434*G0_1_0_0_0_1 - 0.10848214285714*G0_1_0_1_0_0 + 0.271205357142878*G0_1_0_3_0_0 + 0.325446428571449*G0_1_0_3_0_1 - 0.162723214285709*G0_1_0_4_0_1 + 0.271205357142849*G0_1_0_5_0_0 - 0.867857142857153*G0_1_0_5_0_1 + 0.162723214285716*G0_1_0_6_0_1 - 1.51875000000002*G0_1_0_7_0_0 - 0.379687500000024*G0_1_0_7_0_1 + 0.92209821428573*G0_1_0_8_0_0 - 0.325446428571448*G0_1_0_8_0_1 - 0.542410714285726*G0_1_0_9_0_0 + 0.542410714285732*G0_1_0_9_0_1 + 0.705133928571434*G0_1_0_10_1_0 + 0.705133928571434*G0_1_0_10_1_1 - 0.10848214285714*G0_1_0_11_1_0 + 0.271205357142878*G0_1_0_13_1_0 + 0.325446428571449*G0_1_0_13_1_1 - 0.162723214285709*G0_1_0_14_1_1 + 0.271205357142849*G0_1_0_15_1_0 - 0.867857142857153*G0_1_0_15_1_1 + 0.162723214285716*G0_1_0_16_1_1 - 1.51875000000002*G0_1_0_17_1_0 - 0.379687500000024*G0_1_0_17_1_1 + 0.92209821428573*G0_1_0_18_1_0 - 0.325446428571448*G0_1_0_18_1_1 - 0.542410714285726*G0_1_0_19_1_0 + 0.542410714285732*G0_1_0_19_1_1 - 0.608705357142866*G0_1_1_0_0_0 - 0.608705357142867*G0_1_1_0_0_1 - 0.259151785714288*G0_1_1_1_0_0 + 0.445982142857153*G0_1_1_2_0_1 + 0.759375000000025*G0_1_1_3_0_0 + 0.271205357142878*G0_1_1_3_0_1 - 0.108482142857142*G0_1_1_4_0_0 - 0.325446428571435*G0_1_1_4_0_1 + 0.976339285714288*G0_1_1_5_0_0 + 2.11540178571432*G0_1_1_5_0_1 + 0.108482142857143*G0_1_1_6_0_0 - 1.9526785714286*G0_1_1_6_0_1 - 0.379687500000024*G0_1_1_7_0_0 - 1.51875000000005*G0_1_1_7_0_1 + 1.24754464285718*G0_1_1_8_0_0 - 0.271205357142877*G0_1_1_8_0_1 - 1.73571428571431*G0_1_1_9_0_0 + 1.84419642857149*G0_1_1_9_0_1 - 0.608705357142866*G0_1_1_10_1_0 - 0.608705357142867*G0_1_1_10_1_1 - 0.259151785714288*G0_1_1_11_1_0 + 0.445982142857153*G0_1_1_12_1_1 + 0.759375000000025*G0_1_1_13_1_0 + 0.271205357142878*G0_1_1_13_1_1 - 0.108482142857142*G0_1_1_14_1_0 - 0.325446428571435*G0_1_1_14_1_1 + 0.976339285714288*G0_1_1_15_1_0 + 2.11540178571432*G0_1_1_15_1_1 + 0.108482142857143*G0_1_1_16_1_0 - 1.9526785714286*G0_1_1_16_1_1 - 0.379687500000024*G0_1_1_17_1_0 - 1.51875000000005*G0_1_1_17_1_1 + 1.24754464285718*G0_1_1_18_1_0 - 0.271205357142877*G0_1_1_18_1_1 - 1.73571428571431*G0_1_1_19_1_0 + 1.84419642857149*G0_1_1_19_1_1; + A[146] = -A[144] + 0.705133928571434*G0_0_1_0_0_0 + 0.705133928571434*G0_0_1_0_0_1 - 0.10848214285714*G0_0_1_1_0_0 + 0.271205357142878*G0_0_1_3_0_0 + 0.325446428571449*G0_0_1_3_0_1 - 0.162723214285708*G0_0_1_4_0_1 + 0.271205357142849*G0_0_1_5_0_0 - 0.867857142857152*G0_0_1_5_0_1 + 0.162723214285717*G0_0_1_6_0_1 - 1.51875000000002*G0_0_1_7_0_0 - 0.379687500000024*G0_0_1_7_0_1 + 0.92209821428573*G0_0_1_8_0_0 - 0.325446428571448*G0_0_1_8_0_1 - 0.542410714285727*G0_0_1_9_0_0 + 0.542410714285732*G0_0_1_9_0_1 + 0.705133928571434*G0_0_1_10_1_0 + 0.705133928571434*G0_0_1_10_1_1 - 0.10848214285714*G0_0_1_11_1_0 + 0.271205357142878*G0_0_1_13_1_0 + 0.325446428571449*G0_0_1_13_1_1 - 0.162723214285708*G0_0_1_14_1_1 + 0.271205357142849*G0_0_1_15_1_0 - 0.867857142857152*G0_0_1_15_1_1 + 0.162723214285717*G0_0_1_16_1_1 - 1.51875000000002*G0_0_1_17_1_0 - 0.379687500000024*G0_0_1_17_1_1 + 0.92209821428573*G0_0_1_18_1_0 - 0.325446428571448*G0_0_1_18_1_1 - 0.542410714285727*G0_0_1_19_1_0 + 0.542410714285732*G0_0_1_19_1_1 - 0.608705357142866*G0_1_1_0_0_0 - 0.608705357142867*G0_1_1_0_0_1 - 0.259151785714288*G0_1_1_1_0_0 + 0.445982142857153*G0_1_1_2_0_1 + 0.759375000000025*G0_1_1_3_0_0 + 0.271205357142878*G0_1_1_3_0_1 - 0.108482142857142*G0_1_1_4_0_0 - 0.325446428571435*G0_1_1_4_0_1 + 0.976339285714288*G0_1_1_5_0_0 + 2.11540178571432*G0_1_1_5_0_1 + 0.108482142857143*G0_1_1_6_0_0 - 1.9526785714286*G0_1_1_6_0_1 - 0.379687500000024*G0_1_1_7_0_0 - 1.51875000000005*G0_1_1_7_0_1 + 1.24754464285718*G0_1_1_8_0_0 - 0.271205357142877*G0_1_1_8_0_1 - 1.73571428571431*G0_1_1_9_0_0 + 1.84419642857149*G0_1_1_9_0_1 - 0.608705357142866*G0_1_1_10_1_0 - 0.608705357142867*G0_1_1_10_1_1 - 0.259151785714288*G0_1_1_11_1_0 + 0.445982142857153*G0_1_1_12_1_1 + 0.759375000000025*G0_1_1_13_1_0 + 0.271205357142878*G0_1_1_13_1_1 - 0.108482142857142*G0_1_1_14_1_0 - 0.325446428571435*G0_1_1_14_1_1 + 0.976339285714288*G0_1_1_15_1_0 + 2.11540178571432*G0_1_1_15_1_1 + 0.108482142857143*G0_1_1_16_1_0 - 1.9526785714286*G0_1_1_16_1_1 - 0.379687500000024*G0_1_1_17_1_0 - 1.51875000000005*G0_1_1_17_1_1 + 1.24754464285718*G0_1_1_18_1_0 - 0.271205357142877*G0_1_1_18_1_1 - 1.73571428571431*G0_1_1_19_1_0 + 1.84419642857149*G0_1_1_19_1_1; + A[276] = -A[376] + 0.150669642857147*G0_0_0_0_0_0 + 0.150669642857147*G0_0_0_0_0_1 + 0.445982142857151*G0_0_0_1_0_0 + 1.3138392857143*G0_0_0_2_0_1 - 2.22388392857147*G0_0_0_3_0_0 - 0.108482142857145*G0_0_0_3_0_1 + 2.27812500000004*G0_0_0_4_0_0 - 0.705133928571437*G0_0_0_4_0_1 - 0.271205357142871*G0_0_0_5_0_0 - 0.325446428571444*G0_0_0_5_0_1 - 2.27812500000004*G0_0_0_6_0_0 - 1.13906250000001*G0_0_0_6_0_1 - 0.542410714285722*G0_0_0_7_0_0 - 0.488169642857148*G0_0_0_7_0_1 - 0.0542410714285762*G0_0_0_8_0_0 + 0.108482142857145*G0_0_0_8_0_1 + 2.49508928571434*G0_0_0_9_0_0 + 1.19330357142859*G0_0_0_9_0_1 + 0.150669642857147*G0_0_0_10_1_0 + 0.150669642857147*G0_0_0_10_1_1 + 0.445982142857151*G0_0_0_11_1_0 + 1.3138392857143*G0_0_0_12_1_1 - 2.22388392857147*G0_0_0_13_1_0 - 0.108482142857145*G0_0_0_13_1_1 + 2.27812500000004*G0_0_0_14_1_0 - 0.705133928571437*G0_0_0_14_1_1 - 0.271205357142871*G0_0_0_15_1_0 - 0.325446428571444*G0_0_0_15_1_1 - 2.27812500000004*G0_0_0_16_1_0 - 1.13906250000001*G0_0_0_16_1_1 - 0.542410714285722*G0_0_0_17_1_0 - 0.488169642857148*G0_0_0_17_1_1 - 0.0542410714285762*G0_0_0_18_1_0 + 0.108482142857145*G0_0_0_18_1_1 + 2.49508928571434*G0_0_0_19_1_0 + 1.19330357142859*G0_0_0_19_1_1 - 0.108482142857142*G0_0_1_0_0_0 - 0.108482142857142*G0_0_1_0_0_1 + 0.705133928571438*G0_0_1_2_0_1 - 0.162723214285726*G0_0_1_3_0_0 + 1.13906250000001*G0_0_1_4_0_0 + 0.271205357142849*G0_0_1_4_0_1 + 1.24754464285718*G0_0_1_5_0_0 + 0.922098214285733*G0_0_1_5_0_1 - 1.13906250000001*G0_0_1_6_0_0 - 1.51875000000003*G0_0_1_6_0_1 - 0.0542410714285714*G0_0_1_7_0_0 + 0.271205357142877*G0_0_1_7_0_1 + 0.162723214285713*G0_0_1_8_0_0 - 1.08482142857145*G0_0_1_9_0_0 - 0.542410714285725*G0_0_1_9_0_1 - 0.108482142857142*G0_0_1_10_1_0 - 0.108482142857142*G0_0_1_10_1_1 + 0.705133928571438*G0_0_1_12_1_1 - 0.162723214285726*G0_0_1_13_1_0 + 1.13906250000001*G0_0_1_14_1_0 + 0.271205357142849*G0_0_1_14_1_1 + 1.24754464285718*G0_0_1_15_1_0 + 0.922098214285733*G0_0_1_15_1_1 - 1.13906250000001*G0_0_1_16_1_0 - 1.51875000000003*G0_0_1_16_1_1 - 0.0542410714285714*G0_0_1_17_1_0 + 0.271205357142877*G0_0_1_17_1_1 + 0.162723214285713*G0_0_1_18_1_0 - 1.08482142857145*G0_0_1_19_1_0 - 0.542410714285725*G0_0_1_19_1_1; + A[85] = -A[276] - 0.45803571428572*G0_0_0_0_0_0 - 0.45803571428572*G0_0_0_0_0_1 + 0.45803571428572*G0_0_0_1_0_0 + 2.6276785714286*G0_0_0_2_0_1 - 1.9526785714286*G0_0_0_3_0_0 + 4.55625000000006*G0_0_0_4_0_0 + 0.43392857142858*G0_0_0_4_0_1 + 1.9526785714286*G0_0_0_5_0_0 + 1.95267857142859*G0_0_0_5_0_1 - 4.55625000000006*G0_0_0_6_0_0 - 4.12232142857148*G0_0_0_6_0_1 - 0.433928571428581*G0_0_0_9_0_1 - 0.45803571428572*G0_0_0_10_1_0 - 0.45803571428572*G0_0_0_10_1_1 + 0.45803571428572*G0_0_0_11_1_0 + 2.6276785714286*G0_0_0_12_1_1 - 1.9526785714286*G0_0_0_13_1_0 + 4.55625000000006*G0_0_0_14_1_0 + 0.43392857142858*G0_0_0_14_1_1 + 1.9526785714286*G0_0_0_15_1_0 + 1.95267857142859*G0_0_0_15_1_1 - 4.55625000000006*G0_0_0_16_1_0 - 4.12232142857148*G0_0_0_16_1_1 - 0.433928571428581*G0_0_0_19_1_1 - 0.337500000000006*G0_0_1_0_0_0 - 0.337500000000006*G0_0_1_0_0_1 + 0.0662946428571418*G0_0_1_1_0_0 + 1.96473214285717*G0_0_1_2_0_1 - 0.379687500000007*G0_0_1_3_0_0 + 0.162723214285713*G0_0_1_3_0_1 + 3.25446428571432*G0_0_1_4_0_0 + 0.813616071428579*G0_0_1_4_0_1 + 2.87477678571434*G0_0_1_5_0_0 + 2.33236607142861*G0_0_1_5_0_1 - 3.25446428571432*G0_0_1_6_0_0 - 3.95959821428578*G0_0_1_6_0_1 - 0.271205357142861*G0_0_1_7_0_0 + 0.271205357142862*G0_0_1_7_0_1 + 0.542410714285724*G0_0_1_8_0_0 - 0.162723214285713*G0_0_1_8_0_1 - 2.49508928571433*G0_0_1_9_0_0 - 1.08482142857144*G0_0_1_9_0_1 - 0.337500000000006*G0_0_1_10_1_0 - 0.337500000000006*G0_0_1_10_1_1 + 0.0662946428571418*G0_0_1_11_1_0 + 1.96473214285717*G0_0_1_12_1_1 - 0.379687500000007*G0_0_1_13_1_0 + 0.162723214285713*G0_0_1_13_1_1 + 3.25446428571432*G0_0_1_14_1_0 + 0.813616071428579*G0_0_1_14_1_1 + 2.87477678571434*G0_0_1_15_1_0 + 2.33236607142861*G0_0_1_15_1_1 - 3.25446428571432*G0_0_1_16_1_0 - 3.95959821428578*G0_0_1_16_1_1 - 0.271205357142861*G0_0_1_17_1_0 + 0.271205357142862*G0_0_1_17_1_1 + 0.542410714285724*G0_0_1_18_1_0 - 0.162723214285713*G0_0_1_18_1_1 - 2.49508928571433*G0_0_1_19_1_0 - 1.08482142857144*G0_0_1_19_1_1 - 0.391741071428579*G0_1_0_0_0_0 - 0.391741071428579*G0_1_0_0_0_1 + 0.120535714285714*G0_1_0_1_0_0 + 0.662946428571434*G0_1_0_2_0_1 + 0.922098214285739*G0_1_0_3_0_0 + 0.542410714285722*G0_1_0_3_0_1 + 1.30178571428573*G0_1_0_4_0_0 + 1.13906250000003*G0_1_0_4_0_1 + 1.57299107142859*G0_1_0_5_0_0 + 1.41026785714288*G0_1_0_5_0_1 - 1.30178571428573*G0_1_0_6_0_0 - 1.68147321428573*G0_1_0_6_0_1 + 0.542410714285726*G0_1_0_7_0_0 + 0.705133928571439*G0_1_0_7_0_1 - 0.271205357142862*G0_1_0_8_0_0 - 0.542410714285722*G0_1_0_8_0_1 - 2.49508928571433*G0_1_0_9_0_0 - 1.84419642857147*G0_1_0_9_0_1 - 0.391741071428579*G0_1_0_10_1_0 - 0.391741071428579*G0_1_0_10_1_1 + 0.120535714285714*G0_1_0_11_1_0 + 0.662946428571434*G0_1_0_12_1_1 + 0.922098214285739*G0_1_0_13_1_0 + 0.542410714285722*G0_1_0_13_1_1 + 1.30178571428573*G0_1_0_14_1_0 + 1.13906250000003*G0_1_0_14_1_1 + 1.57299107142859*G0_1_0_15_1_0 + 1.41026785714288*G0_1_0_15_1_1 - 1.30178571428573*G0_1_0_16_1_0 - 1.68147321428573*G0_1_0_16_1_1 + 0.542410714285726*G0_1_0_17_1_0 + 0.705133928571439*G0_1_0_17_1_1 - 0.271205357142862*G0_1_0_18_1_0 - 0.542410714285722*G0_1_0_18_1_1 - 2.49508928571433*G0_1_0_19_1_0 - 1.84419642857147*G0_1_0_19_1_1 - 0.325446428571433*G0_1_1_0_0_0 - 0.325446428571433*G0_1_1_0_0_1 + 0.0542410714285691*G0_1_1_1_0_0 + 0.433928571428574*G0_1_1_2_0_1 + 0.813616071428597*G0_1_1_3_0_0 + 0.271205357142857*G0_1_1_3_0_1 + 0.976339285714308*G0_1_1_4_0_0 + 1.13906250000004*G0_1_1_4_0_1 + 1.68147321428573*G0_1_1_5_0_0 + 1.24754464285715*G0_1_1_5_0_1 - 0.976339285714308*G0_1_1_6_0_0 - 1.35602678571429*G0_1_1_6_0_1 + 0.813616071428588*G0_1_1_7_0_0 + 1.24754464285717*G0_1_1_7_0_1 - 0.542410714285725*G0_1_1_8_0_0 - 0.271205357142857*G0_1_1_8_0_1 - 2.49508928571433*G0_1_1_9_0_0 - 2.38660714285721*G0_1_1_9_0_1 - 0.325446428571433*G0_1_1_10_1_0 - 0.325446428571433*G0_1_1_10_1_1 + 0.0542410714285691*G0_1_1_11_1_0 + 0.433928571428574*G0_1_1_12_1_1 + 0.813616071428597*G0_1_1_13_1_0 + 0.271205357142857*G0_1_1_13_1_1 + 0.976339285714308*G0_1_1_14_1_0 + 1.13906250000004*G0_1_1_14_1_1 + 1.68147321428573*G0_1_1_15_1_0 + 1.24754464285715*G0_1_1_15_1_1 - 0.976339285714308*G0_1_1_16_1_0 - 1.35602678571429*G0_1_1_16_1_1 + 0.813616071428588*G0_1_1_17_1_0 + 1.24754464285717*G0_1_1_17_1_1 - 0.542410714285725*G0_1_1_18_1_0 - 0.271205357142857*G0_1_1_18_1_1 - 2.49508928571433*G0_1_1_19_1_0 - 2.38660714285721*G0_1_1_19_1_1; + A[64] = -A[276] - 0.307366071428583*G0_0_1_0_0_0 - 0.307366071428583*G0_0_1_0_0_1 - 0.235044642857139*G0_0_1_1_0_0 + 0.470089285714298*G0_0_1_2_0_1 + 2.82053571428573*G0_0_1_3_0_0 + 0.70513392857144*G0_0_1_3_0_1 + 1.84419642857145*G0_0_1_4_0_0 + 3.25446428571431*G0_0_1_4_0_1 + 1.73571428571433*G0_0_1_5_0_0 + 1.24754464285718*G0_0_1_5_0_1 - 1.84419642857145*G0_0_1_6_0_0 - 1.4102678571429*G0_0_1_6_0_1 + 0.271205357142878*G0_0_1_7_0_0 + 0.759375000000025*G0_0_1_7_0_1 + 0.271205357142843*G0_0_1_8_0_0 - 0.70513392857144*G0_0_1_8_0_1 - 4.55625000000006*G0_0_1_9_0_0 - 4.01383928571433*G0_0_1_9_0_1 - 0.307366071428583*G0_0_1_10_1_0 - 0.307366071428583*G0_0_1_10_1_1 - 0.235044642857139*G0_0_1_11_1_0 + 0.470089285714298*G0_0_1_12_1_1 + 2.82053571428573*G0_0_1_13_1_0 + 0.70513392857144*G0_0_1_13_1_1 + 1.84419642857145*G0_0_1_14_1_0 + 3.25446428571431*G0_0_1_14_1_1 + 1.73571428571433*G0_0_1_15_1_0 + 1.24754464285718*G0_0_1_15_1_1 - 1.84419642857145*G0_0_1_16_1_0 - 1.4102678571429*G0_0_1_16_1_1 + 0.271205357142878*G0_0_1_17_1_0 + 0.759375000000025*G0_0_1_17_1_1 + 0.271205357142843*G0_0_1_18_1_0 - 0.70513392857144*G0_0_1_18_1_1 - 4.55625000000006*G0_0_1_19_1_0 - 4.01383928571433*G0_0_1_19_1_1 - 0.150669642857147*G0_1_1_0_0_0 - 0.150669642857147*G0_1_1_0_0_1 - 1.3138392857143*G0_1_1_1_0_0 - 0.44598214285715*G0_1_1_2_0_1 + 0.70513392857144*G0_1_1_3_0_0 - 2.27812500000002*G0_1_1_3_0_1 + 0.108482142857146*G0_1_1_4_0_0 + 2.22388392857146*G0_1_1_4_0_1 + 0.488169642857149*G0_1_1_5_0_0 + 0.54241071428572*G0_1_1_5_0_1 - 0.108482142857146*G0_1_1_6_0_0 + 0.0542410714285783*G0_1_1_6_0_1 + 0.325446428571449*G0_1_1_7_0_0 + 0.271205357142878*G0_1_1_7_0_1 + 1.13906249999999*G0_1_1_8_0_0 + 2.27812500000002*G0_1_1_8_0_1 - 1.19330357142859*G0_1_1_9_0_0 - 2.49508928571434*G0_1_1_9_0_1 - 0.150669642857147*G0_1_1_10_1_0 - 0.150669642857147*G0_1_1_10_1_1 - 1.3138392857143*G0_1_1_11_1_0 - 0.44598214285715*G0_1_1_12_1_1 + 0.70513392857144*G0_1_1_13_1_0 - 2.27812500000002*G0_1_1_13_1_1 + 0.108482142857146*G0_1_1_14_1_0 + 2.22388392857146*G0_1_1_14_1_1 + 0.488169642857149*G0_1_1_15_1_0 + 0.54241071428572*G0_1_1_15_1_1 - 0.108482142857146*G0_1_1_16_1_0 + 0.0542410714285783*G0_1_1_16_1_1 + 0.325446428571449*G0_1_1_17_1_0 + 0.271205357142878*G0_1_1_17_1_1 + 1.13906249999999*G0_1_1_18_1_0 + 2.27812500000002*G0_1_1_18_1_1 - 1.19330357142859*G0_1_1_19_1_0 - 2.49508928571434*G0_1_1_19_1_1; + A[333] = A[276] + 0.054241071428571*G0_0_1_1_0_0 - 0.650892857142868*G0_0_1_2_0_1 + 0.488169642857159*G0_0_1_3_0_0 + 0.162723214285717*G0_0_1_3_0_1 - 0.976339285714297*G0_0_1_4_0_0 + 0.0542410714285835*G0_0_1_4_0_1 - 0.813616071428588*G0_0_1_5_0_0 - 0.596651785714297*G0_0_1_5_0_1 + 0.976339285714297*G0_0_1_6_0_0 + 1.24754464285717*G0_0_1_6_0_1 + 0.379687500000008*G0_0_1_7_0_0 + 0.162723214285716*G0_0_1_7_0_1 - 0.433928571428578*G0_0_1_8_0_0 - 0.162723214285717*G0_0_1_8_0_1 + 0.32544642857143*G0_0_1_9_0_0 - 0.2169642857143*G0_0_1_9_0_1 + 0.054241071428571*G0_0_1_11_1_0 - 0.650892857142868*G0_0_1_12_1_1 + 0.488169642857159*G0_0_1_13_1_0 + 0.162723214285717*G0_0_1_13_1_1 - 0.976339285714297*G0_0_1_14_1_0 + 0.0542410714285835*G0_0_1_14_1_1 - 0.813616071428588*G0_0_1_15_1_0 - 0.596651785714297*G0_0_1_15_1_1 + 0.976339285714297*G0_0_1_16_1_0 + 1.24754464285717*G0_0_1_16_1_1 + 0.379687500000008*G0_0_1_17_1_0 + 0.162723214285716*G0_0_1_17_1_1 - 0.433928571428578*G0_0_1_18_1_0 - 0.162723214285717*G0_0_1_18_1_1 + 0.32544642857143*G0_0_1_19_1_0 - 0.2169642857143*G0_0_1_19_1_1 - 0.0542410714285709*G0_1_0_1_0_0 + 0.650892857142868*G0_1_0_2_0_1 - 0.488169642857159*G0_1_0_3_0_0 - 0.162723214285717*G0_1_0_3_0_1 + 0.976339285714297*G0_1_0_4_0_0 - 0.0542410714285836*G0_1_0_4_0_1 + 0.813616071428589*G0_1_0_5_0_0 + 0.596651785714297*G0_1_0_5_0_1 - 0.976339285714297*G0_1_0_6_0_0 - 1.24754464285717*G0_1_0_6_0_1 - 0.379687500000008*G0_1_0_7_0_0 - 0.162723214285716*G0_1_0_7_0_1 + 0.433928571428578*G0_1_0_8_0_0 + 0.162723214285717*G0_1_0_8_0_1 - 0.32544642857143*G0_1_0_9_0_0 + 0.2169642857143*G0_1_0_9_0_1 - 0.0542410714285709*G0_1_0_11_1_0 + 0.650892857142868*G0_1_0_12_1_1 - 0.488169642857159*G0_1_0_13_1_0 - 0.162723214285717*G0_1_0_13_1_1 + 0.976339285714297*G0_1_0_14_1_0 - 0.0542410714285836*G0_1_0_14_1_1 + 0.813616071428589*G0_1_0_15_1_0 + 0.596651785714297*G0_1_0_15_1_1 - 0.976339285714297*G0_1_0_16_1_0 - 1.24754464285717*G0_1_0_16_1_1 - 0.379687500000008*G0_1_0_17_1_0 - 0.162723214285716*G0_1_0_17_1_1 + 0.433928571428578*G0_1_0_18_1_0 + 0.162723214285717*G0_1_0_18_1_1 - 0.32544642857143*G0_1_0_19_1_0 + 0.2169642857143*G0_1_0_19_1_1; + A[66] = A[276]; + A[104] = A[85] - 0.054241071428572*G0_0_1_0_0_0 - 0.0542410714285722*G0_0_1_0_0_1 - 0.650892857142867*G0_0_1_2_0_1 + 0.813616071428587*G0_0_1_3_0_0 + 0.216964285714292*G0_0_1_3_0_1 - 0.976339285714295*G0_0_1_4_0_0 + 0.271205357142867*G0_0_1_4_0_1 - 0.488169642857158*G0_0_1_5_0_0 - 0.325446428571439*G0_0_1_5_0_1 + 0.976339285714296*G0_0_1_6_0_0 + 1.03058035714288*G0_0_1_6_0_1 + 0.433928571428579*G0_0_1_7_0_0 + 0.271205357142861*G0_0_1_7_0_1 - 0.379687500000009*G0_0_1_8_0_0 - 0.216964285714292*G0_0_1_8_0_1 - 0.32544642857143*G0_0_1_9_0_0 - 0.542410714285728*G0_0_1_9_0_1 - 0.054241071428572*G0_0_1_10_1_0 - 0.0542410714285722*G0_0_1_10_1_1 - 0.650892857142867*G0_0_1_12_1_1 + 0.813616071428587*G0_0_1_13_1_0 + 0.216964285714292*G0_0_1_13_1_1 - 0.976339285714295*G0_0_1_14_1_0 + 0.271205357142867*G0_0_1_14_1_1 - 0.488169642857158*G0_0_1_15_1_0 - 0.325446428571439*G0_0_1_15_1_1 + 0.976339285714296*G0_0_1_16_1_0 + 1.03058035714288*G0_0_1_16_1_1 + 0.433928571428579*G0_0_1_17_1_0 + 0.271205357142861*G0_0_1_17_1_1 - 0.379687500000009*G0_0_1_18_1_0 - 0.216964285714292*G0_0_1_18_1_1 - 0.32544642857143*G0_0_1_19_1_0 - 0.542410714285728*G0_0_1_19_1_1 + 0.054241071428572*G0_1_0_0_0_0 + 0.0542410714285722*G0_1_0_0_0_1 + 0.650892857142867*G0_1_0_2_0_1 - 0.813616071428587*G0_1_0_3_0_0 - 0.216964285714292*G0_1_0_3_0_1 + 0.976339285714295*G0_1_0_4_0_0 - 0.271205357142867*G0_1_0_4_0_1 + 0.488169642857158*G0_1_0_5_0_0 + 0.325446428571439*G0_1_0_5_0_1 - 0.976339285714296*G0_1_0_6_0_0 - 1.03058035714288*G0_1_0_6_0_1 - 0.433928571428579*G0_1_0_7_0_0 - 0.271205357142861*G0_1_0_7_0_1 + 0.379687500000009*G0_1_0_8_0_0 + 0.216964285714292*G0_1_0_8_0_1 + 0.32544642857143*G0_1_0_9_0_0 + 0.542410714285728*G0_1_0_9_0_1 + 0.054241071428572*G0_1_0_10_1_0 + 0.0542410714285722*G0_1_0_10_1_1 + 0.650892857142867*G0_1_0_12_1_1 - 0.813616071428587*G0_1_0_13_1_0 - 0.216964285714292*G0_1_0_13_1_1 + 0.976339285714295*G0_1_0_14_1_0 - 0.271205357142867*G0_1_0_14_1_1 + 0.488169642857158*G0_1_0_15_1_0 + 0.325446428571439*G0_1_0_15_1_1 - 0.976339285714296*G0_1_0_16_1_0 - 1.03058035714288*G0_1_0_16_1_1 - 0.433928571428579*G0_1_0_17_1_0 - 0.271205357142861*G0_1_0_17_1_1 + 0.379687500000009*G0_1_0_18_1_0 + 0.216964285714292*G0_1_0_18_1_1 + 0.32544642857143*G0_1_0_19_1_0 + 0.542410714285728*G0_1_0_19_1_1; + A[106] = -A[104] - 0.235044642857142*G0_0_1_0_0_0 - 0.235044642857142*G0_0_1_0_0_1 - 0.307366071428581*G0_0_1_1_0_0 - 0.470089285714296*G0_0_1_2_0_1 + 1.73571428571433*G0_0_1_3_0_0 + 0.488169642857149*G0_0_1_3_0_1 - 1.84419642857145*G0_0_1_4_0_0 - 0.433928571428557*G0_0_1_4_0_1 + 2.82053571428574*G0_0_1_5_0_0 + 2.1154017857143*G0_0_1_5_0_1 + 1.84419642857145*G0_0_1_6_0_0 - 1.41026785714286*G0_0_1_6_0_1 + 0.271205357142849*G0_0_1_7_0_0 + 0.976339285714288*G0_0_1_7_0_1 + 0.271205357142875*G0_0_1_8_0_0 - 0.48816964285715*G0_0_1_8_0_1 - 4.55625000000007*G0_0_1_9_0_0 - 0.54241071428573*G0_0_1_9_0_1 - 0.235044642857142*G0_0_1_10_1_0 - 0.235044642857142*G0_0_1_10_1_1 - 0.307366071428581*G0_0_1_11_1_0 - 0.470089285714296*G0_0_1_12_1_1 + 1.73571428571433*G0_0_1_13_1_0 + 0.488169642857149*G0_0_1_13_1_1 - 1.84419642857145*G0_0_1_14_1_0 - 0.433928571428557*G0_0_1_14_1_1 + 2.82053571428574*G0_0_1_15_1_0 + 2.1154017857143*G0_0_1_15_1_1 + 1.84419642857145*G0_0_1_16_1_0 - 1.41026785714286*G0_0_1_16_1_1 + 0.271205357142849*G0_0_1_17_1_0 + 0.976339285714288*G0_0_1_17_1_1 + 0.271205357142875*G0_0_1_18_1_0 - 0.48816964285715*G0_0_1_18_1_1 - 4.55625000000007*G0_0_1_19_1_0 - 0.54241071428573*G0_0_1_19_1_1 + 1.07879464285716*G0_1_1_0_0_0 + 1.07879464285716*G0_1_1_0_0_1 - 0.156696428571434*G0_1_1_1_0_0 - 0.916071428571446*G0_1_1_2_0_1 + 1.24754464285718*G0_1_1_3_0_0 + 0.54241071428572*G0_1_1_3_0_1 - 1.7357142857143*G0_1_1_4_0_0 - 0.271205357142829*G0_1_1_4_0_1 + 2.1154017857143*G0_1_1_5_0_0 - 0.867857142857168*G0_1_1_5_0_1 + 1.7357142857143*G0_1_1_6_0_0 + 0.705133928571457*G0_1_1_6_0_1 - 0.867857142857152*G0_1_1_7_0_0 + 2.11540178571432*G0_1_1_7_0_1 - 0.0542410714285718*G0_1_1_8_0_0 - 0.54241071428572*G0_1_1_8_0_1 - 3.36294642857148*G0_1_1_9_0_0 - 1.84419642857149*G0_1_1_9_0_1 + 1.07879464285716*G0_1_1_10_1_0 + 1.07879464285716*G0_1_1_10_1_1 - 0.156696428571434*G0_1_1_11_1_0 - 0.916071428571446*G0_1_1_12_1_1 + 1.24754464285718*G0_1_1_13_1_0 + 0.54241071428572*G0_1_1_13_1_1 - 1.7357142857143*G0_1_1_14_1_0 - 0.271205357142829*G0_1_1_14_1_1 + 2.1154017857143*G0_1_1_15_1_0 - 0.867857142857168*G0_1_1_15_1_1 + 1.7357142857143*G0_1_1_16_1_0 + 0.705133928571457*G0_1_1_16_1_1 - 0.867857142857152*G0_1_1_17_1_0 + 2.11540178571432*G0_1_1_17_1_1 - 0.0542410714285718*G0_1_1_18_1_0 - 0.54241071428572*G0_1_1_18_1_1 - 3.36294642857148*G0_1_1_19_1_0 - 1.84419642857149*G0_1_1_19_1_1; + A[337] = A[127]; + A[125] = A[106] + 0.18080357142857*G0_0_1_0_0_0 + 0.18080357142857*G0_0_1_0_0_1 + 0.307366071428583*G0_0_1_1_0_0 - 0.180803571428571*G0_0_1_2_0_1 - 0.922098214285741*G0_0_1_3_0_0 - 0.271205357142857*G0_0_1_3_0_1 + 0.867857142857155*G0_0_1_4_0_0 + 0.705133928571424*G0_0_1_4_0_1 - 3.3087053571429*G0_0_1_5_0_0 - 2.44084821428574*G0_0_1_5_0_1 - 0.867857142857156*G0_0_1_6_0_0 + 2.44084821428574*G0_0_1_6_0_1 + 0.162723214285731*G0_0_1_7_0_0 - 0.705133928571427*G0_0_1_7_0_1 - 0.650892857142883*G0_0_1_8_0_0 + 0.271205357142858*G0_0_1_8_0_1 + 4.23080357142864*G0_0_1_9_0_0 + 0.18080357142857*G0_0_1_10_1_0 + 0.18080357142857*G0_0_1_10_1_1 + 0.307366071428583*G0_0_1_11_1_0 - 0.180803571428571*G0_0_1_12_1_1 - 0.922098214285741*G0_0_1_13_1_0 - 0.271205357142857*G0_0_1_13_1_1 + 0.867857142857155*G0_0_1_14_1_0 + 0.705133928571424*G0_0_1_14_1_1 - 3.3087053571429*G0_0_1_15_1_0 - 2.44084821428574*G0_0_1_15_1_1 - 0.867857142857156*G0_0_1_16_1_0 + 2.44084821428574*G0_0_1_16_1_1 + 0.162723214285731*G0_0_1_17_1_0 - 0.705133928571427*G0_0_1_17_1_1 - 0.650892857142883*G0_0_1_18_1_0 + 0.271205357142858*G0_0_1_18_1_1 + 4.23080357142864*G0_0_1_19_1_0 - 0.18080357142857*G0_1_0_0_0_0 - 0.18080357142857*G0_1_0_0_0_1 - 0.307366071428583*G0_1_0_1_0_0 + 0.180803571428571*G0_1_0_2_0_1 + 0.922098214285741*G0_1_0_3_0_0 + 0.271205357142857*G0_1_0_3_0_1 - 0.867857142857155*G0_1_0_4_0_0 - 0.705133928571424*G0_1_0_4_0_1 + 3.3087053571429*G0_1_0_5_0_0 + 2.44084821428574*G0_1_0_5_0_1 + 0.867857142857156*G0_1_0_6_0_0 - 2.44084821428574*G0_1_0_6_0_1 - 0.162723214285731*G0_1_0_7_0_0 + 0.705133928571427*G0_1_0_7_0_1 + 0.650892857142884*G0_1_0_8_0_0 - 0.271205357142858*G0_1_0_8_0_1 - 4.23080357142864*G0_1_0_9_0_0 - 0.18080357142857*G0_1_0_10_1_0 - 0.18080357142857*G0_1_0_10_1_1 - 0.307366071428583*G0_1_0_11_1_0 + 0.180803571428571*G0_1_0_12_1_1 + 0.922098214285741*G0_1_0_13_1_0 + 0.271205357142857*G0_1_0_13_1_1 - 0.867857142857155*G0_1_0_14_1_0 - 0.705133928571424*G0_1_0_14_1_1 + 3.3087053571429*G0_1_0_15_1_0 + 2.44084821428574*G0_1_0_15_1_1 + 0.867857142857156*G0_1_0_16_1_0 - 2.44084821428574*G0_1_0_16_1_1 - 0.162723214285731*G0_1_0_17_1_0 + 0.705133928571427*G0_1_0_17_1_1 + 0.650892857142884*G0_1_0_18_1_0 - 0.271205357142858*G0_1_0_18_1_1 - 4.23080357142864*G0_1_0_19_1_0; + A[164] = -A[376] - 0.108482142857141*G0_0_1_0_0_0 - 0.108482142857141*G0_0_1_0_0_1 + 0.705133928571432*G0_0_1_1_0_0 + 0.271205357142843*G0_0_1_3_0_0 + 1.13906249999999*G0_0_1_3_0_1 - 0.162723214285721*G0_0_1_4_0_1 + 0.271205357142875*G0_0_1_5_0_0 - 0.0542410714285719*G0_0_1_5_0_1 + 0.162723214285714*G0_0_1_6_0_1 + 0.92209821428573*G0_0_1_7_0_0 + 1.24754464285718*G0_0_1_7_0_1 - 1.51875000000002*G0_0_1_8_0_0 - 1.1390625*G0_0_1_8_0_1 - 0.542410714285717*G0_0_1_9_0_0 - 1.08482142857146*G0_0_1_9_0_1 - 0.108482142857141*G0_0_1_10_1_0 - 0.108482142857141*G0_0_1_10_1_1 + 0.705133928571432*G0_0_1_11_1_0 + 0.271205357142843*G0_0_1_13_1_0 + 1.13906249999999*G0_0_1_13_1_1 - 0.162723214285721*G0_0_1_14_1_1 + 0.271205357142875*G0_0_1_15_1_0 - 0.0542410714285719*G0_0_1_15_1_1 + 0.162723214285714*G0_0_1_16_1_1 + 0.92209821428573*G0_0_1_17_1_0 + 1.24754464285718*G0_0_1_17_1_1 - 1.51875000000002*G0_0_1_18_1_0 - 1.1390625*G0_0_1_18_1_1 - 0.542410714285717*G0_0_1_19_1_0 - 1.08482142857146*G0_0_1_19_1_1 + 0.150669642857147*G0_1_1_0_0_0 + 0.150669642857147*G0_1_1_0_0_1 + 1.3138392857143*G0_1_1_1_0_0 + 0.44598214285715*G0_1_1_2_0_1 - 0.70513392857144*G0_1_1_3_0_0 + 2.27812500000002*G0_1_1_3_0_1 - 0.108482142857146*G0_1_1_4_0_0 - 2.22388392857146*G0_1_1_4_0_1 - 0.48816964285715*G0_1_1_5_0_0 - 0.54241071428572*G0_1_1_5_0_1 + 0.108482142857146*G0_1_1_6_0_0 - 0.0542410714285776*G0_1_1_6_0_1 - 0.325446428571448*G0_1_1_7_0_0 - 0.271205357142877*G0_1_1_7_0_1 - 1.1390625*G0_1_1_8_0_0 - 2.27812500000002*G0_1_1_8_0_1 + 1.19330357142859*G0_1_1_9_0_0 + 2.49508928571434*G0_1_1_9_0_1 + 0.150669642857147*G0_1_1_10_1_0 + 0.150669642857147*G0_1_1_10_1_1 + 1.3138392857143*G0_1_1_11_1_0 + 0.44598214285715*G0_1_1_12_1_1 - 0.70513392857144*G0_1_1_13_1_0 + 2.27812500000002*G0_1_1_13_1_1 - 0.108482142857146*G0_1_1_14_1_0 - 2.22388392857146*G0_1_1_14_1_1 - 0.48816964285715*G0_1_1_15_1_0 - 0.54241071428572*G0_1_1_15_1_1 + 0.108482142857146*G0_1_1_16_1_0 - 0.0542410714285776*G0_1_1_16_1_1 - 0.325446428571448*G0_1_1_17_1_0 - 0.271205357142877*G0_1_1_17_1_1 - 1.1390625*G0_1_1_18_1_0 - 2.27812500000002*G0_1_1_18_1_1 + 1.19330357142859*G0_1_1_19_1_0 + 2.49508928571434*G0_1_1_19_1_1; + A[88] = A[164] - 0.650892857142862*G0_0_1_1_0_0 + 0.0542410714285717*G0_0_1_2_0_1 + 0.054241071428589*G0_0_1_3_0_0 - 0.976339285714283*G0_0_1_3_0_1 + 0.162723214285716*G0_0_1_4_0_0 + 0.488169642857154*G0_0_1_4_0_1 + 0.162723214285718*G0_0_1_5_0_0 + 0.379687500000008*G0_0_1_5_0_1 - 0.162723214285716*G0_0_1_6_0_0 - 0.433928571428578*G0_0_1_6_0_1 - 0.596651785714294*G0_0_1_7_0_0 - 0.813616071428585*G0_0_1_7_0_1 + 1.24754464285716*G0_0_1_8_0_0 + 0.976339285714284*G0_0_1_8_0_1 - 0.216964285714307*G0_0_1_9_0_0 + 0.32544642857143*G0_0_1_9_0_1 - 0.650892857142862*G0_0_1_11_1_0 + 0.0542410714285717*G0_0_1_12_1_1 + 0.054241071428589*G0_0_1_13_1_0 - 0.976339285714283*G0_0_1_13_1_1 + 0.162723214285716*G0_0_1_14_1_0 + 0.488169642857154*G0_0_1_14_1_1 + 0.162723214285718*G0_0_1_15_1_0 + 0.379687500000008*G0_0_1_15_1_1 - 0.162723214285716*G0_0_1_16_1_0 - 0.433928571428578*G0_0_1_16_1_1 - 0.596651785714294*G0_0_1_17_1_0 - 0.813616071428585*G0_0_1_17_1_1 + 1.24754464285716*G0_0_1_18_1_0 + 0.976339285714284*G0_0_1_18_1_1 - 0.216964285714307*G0_0_1_19_1_0 + 0.32544642857143*G0_0_1_19_1_1 + 0.650892857142862*G0_1_0_1_0_0 - 0.0542410714285718*G0_1_0_2_0_1 - 0.0542410714285889*G0_1_0_3_0_0 + 0.976339285714283*G0_1_0_3_0_1 - 0.162723214285716*G0_1_0_4_0_0 - 0.488169642857154*G0_1_0_4_0_1 - 0.162723214285718*G0_1_0_5_0_0 - 0.379687500000008*G0_1_0_5_0_1 + 0.162723214285716*G0_1_0_6_0_0 + 0.433928571428578*G0_1_0_6_0_1 + 0.596651785714294*G0_1_0_7_0_0 + 0.813616071428585*G0_1_0_7_0_1 - 1.24754464285716*G0_1_0_8_0_0 - 0.976339285714284*G0_1_0_8_0_1 + 0.216964285714306*G0_1_0_9_0_0 - 0.325446428571431*G0_1_0_9_0_1 + 0.650892857142862*G0_1_0_11_1_0 - 0.0542410714285718*G0_1_0_12_1_1 - 0.0542410714285889*G0_1_0_13_1_0 + 0.976339285714283*G0_1_0_13_1_1 - 0.162723214285716*G0_1_0_14_1_0 - 0.488169642857154*G0_1_0_14_1_1 - 0.162723214285718*G0_1_0_15_1_0 - 0.379687500000008*G0_1_0_15_1_1 + 0.162723214285716*G0_1_0_16_1_0 + 0.433928571428578*G0_1_0_16_1_1 + 0.596651785714294*G0_1_0_17_1_0 + 0.813616071428585*G0_1_0_17_1_1 - 1.24754464285716*G0_1_0_18_1_0 - 0.976339285714284*G0_1_0_18_1_1 + 0.216964285714306*G0_1_0_19_1_0 - 0.325446428571431*G0_1_0_19_1_1; + A[335] = A[125]; + A[354] = A[144]; + A[274] = A[64]; + A[83] = -A[333] - 0.307366071428583*G0_1_0_0_0_0 - 0.307366071428583*G0_1_0_0_0_1 - 0.235044642857139*G0_1_0_1_0_0 + 0.470089285714298*G0_1_0_2_0_1 + 2.82053571428573*G0_1_0_3_0_0 + 0.70513392857144*G0_1_0_3_0_1 + 1.84419642857145*G0_1_0_4_0_0 + 3.25446428571431*G0_1_0_4_0_1 + 1.73571428571433*G0_1_0_5_0_0 + 1.24754464285718*G0_1_0_5_0_1 - 1.84419642857145*G0_1_0_6_0_0 - 1.4102678571429*G0_1_0_6_0_1 + 0.271205357142878*G0_1_0_7_0_0 + 0.759375000000025*G0_1_0_7_0_1 + 0.271205357142843*G0_1_0_8_0_0 - 0.70513392857144*G0_1_0_8_0_1 - 4.55625000000006*G0_1_0_9_0_0 - 4.01383928571433*G0_1_0_9_0_1 - 0.307366071428583*G0_1_0_10_1_0 - 0.307366071428583*G0_1_0_10_1_1 - 0.235044642857139*G0_1_0_11_1_0 + 0.470089285714298*G0_1_0_12_1_1 + 2.82053571428573*G0_1_0_13_1_0 + 0.70513392857144*G0_1_0_13_1_1 + 1.84419642857145*G0_1_0_14_1_0 + 3.25446428571431*G0_1_0_14_1_1 + 1.73571428571433*G0_1_0_15_1_0 + 1.24754464285718*G0_1_0_15_1_1 - 1.84419642857145*G0_1_0_16_1_0 - 1.4102678571429*G0_1_0_16_1_1 + 0.271205357142878*G0_1_0_17_1_0 + 0.759375000000025*G0_1_0_17_1_1 + 0.271205357142843*G0_1_0_18_1_0 - 0.70513392857144*G0_1_0_18_1_1 - 4.55625000000006*G0_1_0_19_1_0 - 4.01383928571433*G0_1_0_19_1_1 - 0.150669642857147*G0_1_1_0_0_0 - 0.150669642857147*G0_1_1_0_0_1 - 1.3138392857143*G0_1_1_1_0_0 - 0.44598214285715*G0_1_1_2_0_1 + 0.70513392857144*G0_1_1_3_0_0 - 2.27812500000002*G0_1_1_3_0_1 + 0.108482142857146*G0_1_1_4_0_0 + 2.22388392857146*G0_1_1_4_0_1 + 0.488169642857149*G0_1_1_5_0_0 + 0.54241071428572*G0_1_1_5_0_1 - 0.108482142857146*G0_1_1_6_0_0 + 0.0542410714285783*G0_1_1_6_0_1 + 0.325446428571449*G0_1_1_7_0_0 + 0.271205357142878*G0_1_1_7_0_1 + 1.13906249999999*G0_1_1_8_0_0 + 2.27812500000002*G0_1_1_8_0_1 - 1.19330357142859*G0_1_1_9_0_0 - 2.49508928571434*G0_1_1_9_0_1 - 0.150669642857147*G0_1_1_10_1_0 - 0.150669642857147*G0_1_1_10_1_1 - 1.3138392857143*G0_1_1_11_1_0 - 0.44598214285715*G0_1_1_12_1_1 + 0.70513392857144*G0_1_1_13_1_0 - 2.27812500000002*G0_1_1_13_1_1 + 0.108482142857146*G0_1_1_14_1_0 + 2.22388392857146*G0_1_1_14_1_1 + 0.488169642857149*G0_1_1_15_1_0 + 0.54241071428572*G0_1_1_15_1_1 - 0.108482142857146*G0_1_1_16_1_0 + 0.0542410714285783*G0_1_1_16_1_1 + 0.325446428571449*G0_1_1_17_1_0 + 0.271205357142878*G0_1_1_17_1_1 + 1.13906249999999*G0_1_1_18_1_0 + 2.27812500000002*G0_1_1_18_1_1 - 1.19330357142859*G0_1_1_19_1_0 - 2.49508928571434*G0_1_1_19_1_1; + A[298] = A[88]; + A[316] = A[106]; + A[166] = A[376]; + A[86] = -A[294] + 0.325446428571431*G0_0_1_0_0_0 + 0.325446428571431*G0_0_1_0_0_1 - 0.325446428571432*G0_0_1_1_0_0 - 1.84419642857145*G0_0_1_2_0_1 + 1.84419642857145*G0_0_1_3_0_0 + 0.108482142857146*G0_0_1_3_0_1 - 2.71205357142862*G0_0_1_4_0_0 + 0.542410714285711*G0_0_1_4_0_1 - 1.84419642857145*G0_0_1_5_0_0 - 1.7357142857143*G0_0_1_5_0_1 + 2.71205357142862*G0_0_1_6_0_0 + 3.25446428571433*G0_0_1_6_0_1 - 0.108482142857142*G0_0_1_7_0_1 - 0.108482142857146*G0_0_1_8_0_1 - 0.433928571428568*G0_0_1_9_0_1 + 0.325446428571431*G0_0_1_10_1_0 + 0.325446428571431*G0_0_1_10_1_1 - 0.325446428571432*G0_0_1_11_1_0 - 1.84419642857145*G0_0_1_12_1_1 + 1.84419642857145*G0_0_1_13_1_0 + 0.108482142857146*G0_0_1_13_1_1 - 2.71205357142862*G0_0_1_14_1_0 + 0.542410714285711*G0_0_1_14_1_1 - 1.84419642857145*G0_0_1_15_1_0 - 1.7357142857143*G0_0_1_15_1_1 + 2.71205357142862*G0_0_1_16_1_0 + 3.25446428571433*G0_0_1_16_1_1 - 0.108482142857142*G0_0_1_17_1_1 - 0.108482142857146*G0_0_1_18_1_1 - 0.433928571428568*G0_0_1_19_1_1 - 0.114508928571438*G0_1_1_0_0_0 - 0.114508928571438*G0_1_1_0_0_1 + 0.439955357142868*G0_1_1_1_0_0 - 0.156696428571423*G0_1_1_2_0_1 + 3.25446428571431*G0_1_1_3_0_0 + 2.22388392857146*G0_1_1_3_0_1 + 0.542410714285711*G0_1_1_4_0_0 + 2.16964285714285*G0_1_1_4_0_1 - 0.433928571428557*G0_1_1_5_0_0 - 0.27120535714283*G0_1_1_5_0_1 - 0.54241071428571*G0_1_1_6_0_0 + 0.542410714285692*G0_1_1_6_0_1 - 0.162723214285709*G0_1_1_7_0_0 - 0.325446428571435*G0_1_1_7_0_1 - 0.162723214285721*G0_1_1_8_0_0 - 2.22388392857146*G0_1_1_8_0_1 - 2.82053571428575*G0_1_1_9_0_0 - 1.84419642857141*G0_1_1_9_0_1 - 0.114508928571438*G0_1_1_10_1_0 - 0.114508928571438*G0_1_1_10_1_1 + 0.439955357142868*G0_1_1_11_1_0 - 0.156696428571423*G0_1_1_12_1_1 + 3.25446428571431*G0_1_1_13_1_0 + 2.22388392857146*G0_1_1_13_1_1 + 0.542410714285711*G0_1_1_14_1_0 + 2.16964285714285*G0_1_1_14_1_1 - 0.433928571428557*G0_1_1_15_1_0 - 0.27120535714283*G0_1_1_15_1_1 - 0.54241071428571*G0_1_1_16_1_0 + 0.542410714285692*G0_1_1_16_1_1 - 0.162723214285709*G0_1_1_17_1_0 - 0.325446428571435*G0_1_1_17_1_1 - 0.162723214285721*G0_1_1_18_1_0 - 2.22388392857146*G0_1_1_18_1_1 - 2.82053571428575*G0_1_1_19_1_0 - 1.84419642857141*G0_1_1_19_1_1; + A[296] = A[86]; + A[126] = -A[86] - 0.325446428571431*G0_1_0_0_0_0 - 0.325446428571431*G0_1_0_0_0_1 + 0.325446428571432*G0_1_0_1_0_0 + 1.84419642857145*G0_1_0_2_0_1 - 1.84419642857145*G0_1_0_3_0_0 - 0.108482142857146*G0_1_0_3_0_1 + 2.71205357142862*G0_1_0_4_0_0 - 0.54241071428571*G0_1_0_4_0_1 + 1.84419642857145*G0_1_0_5_0_0 + 1.7357142857143*G0_1_0_5_0_1 - 2.71205357142862*G0_1_0_6_0_0 - 3.25446428571433*G0_1_0_6_0_1 + 0.108482142857143*G0_1_0_7_0_1 + 0.108482142857146*G0_1_0_8_0_1 + 0.433928571428567*G0_1_0_9_0_1 - 0.325446428571431*G0_1_0_10_1_0 - 0.325446428571431*G0_1_0_10_1_1 + 0.325446428571432*G0_1_0_11_1_0 + 1.84419642857145*G0_1_0_12_1_1 - 1.84419642857145*G0_1_0_13_1_0 - 0.108482142857146*G0_1_0_13_1_1 + 2.71205357142862*G0_1_0_14_1_0 - 0.54241071428571*G0_1_0_14_1_1 + 1.84419642857145*G0_1_0_15_1_0 + 1.7357142857143*G0_1_0_15_1_1 - 2.71205357142862*G0_1_0_16_1_0 - 3.25446428571433*G0_1_0_16_1_1 + 0.108482142857143*G0_1_0_17_1_1 + 0.108482142857146*G0_1_0_18_1_1 + 0.433928571428567*G0_1_0_19_1_1 - 0.765401785714301*G0_1_1_0_0_0 - 0.765401785714301*G0_1_1_0_0_1 + 0.439955357142869*G0_1_1_1_0_0 + 1.68750000000003*G0_1_1_2_0_1 - 1.4102678571429*G0_1_1_3_0_0 + 0.0542410714285783*G0_1_1_3_0_1 + 3.25446428571433*G0_1_1_4_0_0 + 0.542410714285692*G0_1_1_4_0_1 - 1.41026785714286*G0_1_1_5_0_0 + 0.705133928571457*G0_1_1_5_0_1 - 3.25446428571433*G0_1_1_6_0_0 - 1.62723214285719*G0_1_1_6_0_1 + 0.162723214285717*G0_1_1_7_0_0 - 1.9526785714286*G0_1_1_7_0_1 + 0.162723214285714*G0_1_1_8_0_0 - 0.0542410714285776*G0_1_1_8_0_1 + 2.82053571428576*G0_1_1_9_0_0 + 1.41026785714291*G0_1_1_9_0_1 - 0.765401785714301*G0_1_1_10_1_0 - 0.765401785714301*G0_1_1_10_1_1 + 0.439955357142869*G0_1_1_11_1_0 + 1.68750000000003*G0_1_1_12_1_1 - 1.4102678571429*G0_1_1_13_1_0 + 0.0542410714285783*G0_1_1_13_1_1 + 3.25446428571433*G0_1_1_14_1_0 + 0.542410714285692*G0_1_1_14_1_1 - 1.41026785714286*G0_1_1_15_1_0 + 0.705133928571457*G0_1_1_15_1_1 - 3.25446428571433*G0_1_1_16_1_0 - 1.62723214285719*G0_1_1_16_1_1 + 0.162723214285717*G0_1_1_17_1_0 - 1.9526785714286*G0_1_1_17_1_1 + 0.162723214285714*G0_1_1_18_1_0 - 0.0542410714285776*G0_1_1_18_1_1 + 2.82053571428576*G0_1_1_19_1_0 + 1.41026785714291*G0_1_1_19_1_1; + A[147] = A[357]; + A[356] = A[146]; + A[318] = A[108]; + A[374] = A[164]; + A[168] = A[378]; + A[10] = 0.0; + A[67] = A[277]; + A[31] = 0.0; + A[105] = A[315]; + A[323] = 0.0; + A[130] = 0.0; + A[394] = A[184]; + A[342] = 0.0; + A[159] = 0.0; + A[369] = 0.0; + A[175] = 0.0; + A[194] = 0.0; + A[213] = -A[218] - 0.649553571428578*G0_0_0_0_0_0 - 0.649553571428578*G0_0_0_0_0_1 + 0.336160714285719*G0_0_0_1_0_0 + 0.0529017857142859*G0_0_0_2_0_1 - 0.114508928571438*G0_0_0_3_0_0 + 0.32544642857143*G0_0_0_3_0_1 - 0.150669642857147*G0_0_0_4_0_0 - 0.307366071428582*G0_0_0_4_0_1 - 0.608705357142865*G0_0_0_5_0_0 + 0.705133928571434*G0_0_0_5_0_1 + 0.150669642857147*G0_0_0_6_0_0 - 0.108482142857142*G0_0_0_6_0_1 + 1.07879464285716*G0_0_0_7_0_0 - 0.235044642857141*G0_0_0_7_0_1 - 0.765401785714298*G0_0_0_8_0_0 - 0.325446428571431*G0_0_0_8_0_1 + 0.723214285714303*G0_0_0_9_0_0 + 0.542410714285724*G0_0_0_9_0_1 - 0.649553571428578*G0_0_0_10_1_0 - 0.649553571428578*G0_0_0_10_1_1 + 0.336160714285719*G0_0_0_11_1_0 + 0.0529017857142859*G0_0_0_12_1_1 - 0.114508928571438*G0_0_0_13_1_0 + 0.32544642857143*G0_0_0_13_1_1 - 0.150669642857147*G0_0_0_14_1_0 - 0.307366071428582*G0_0_0_14_1_1 - 0.608705357142865*G0_0_0_15_1_0 + 0.705133928571434*G0_0_0_15_1_1 + 0.150669642857147*G0_0_0_16_1_0 - 0.108482142857142*G0_0_0_16_1_1 + 1.07879464285716*G0_0_0_17_1_0 - 0.235044642857141*G0_0_0_17_1_1 - 0.765401785714298*G0_0_0_18_1_0 - 0.325446428571431*G0_0_0_18_1_1 + 0.723214285714303*G0_0_0_19_1_0 + 0.542410714285724*G0_0_0_19_1_1 - 0.649553571428578*G0_1_0_0_0_0 - 0.649553571428578*G0_1_0_0_0_1 + 0.336160714285719*G0_1_0_1_0_0 + 0.0529017857142857*G0_1_0_2_0_1 - 0.114508928571438*G0_1_0_3_0_0 + 0.32544642857143*G0_1_0_3_0_1 - 0.150669642857147*G0_1_0_4_0_0 - 0.307366071428581*G0_1_0_4_0_1 - 0.608705357142865*G0_1_0_5_0_0 + 0.705133928571434*G0_1_0_5_0_1 + 0.150669642857147*G0_1_0_6_0_0 - 0.108482142857142*G0_1_0_6_0_1 + 1.07879464285716*G0_1_0_7_0_0 - 0.235044642857141*G0_1_0_7_0_1 - 0.765401785714298*G0_1_0_8_0_0 - 0.32544642857143*G0_1_0_8_0_1 + 0.723214285714303*G0_1_0_9_0_0 + 0.542410714285724*G0_1_0_9_0_1 - 0.649553571428578*G0_1_0_10_1_0 - 0.649553571428578*G0_1_0_10_1_1 + 0.336160714285719*G0_1_0_11_1_0 + 0.0529017857142857*G0_1_0_12_1_1 - 0.114508928571438*G0_1_0_13_1_0 + 0.32544642857143*G0_1_0_13_1_1 - 0.150669642857147*G0_1_0_14_1_0 - 0.307366071428581*G0_1_0_14_1_1 - 0.608705357142865*G0_1_0_15_1_0 + 0.705133928571434*G0_1_0_15_1_1 + 0.150669642857147*G0_1_0_16_1_0 - 0.108482142857142*G0_1_0_16_1_1 + 1.07879464285716*G0_1_0_17_1_0 - 0.235044642857141*G0_1_0_17_1_1 - 0.765401785714298*G0_1_0_18_1_0 - 0.32544642857143*G0_1_0_18_1_1 + 0.723214285714303*G0_1_0_19_1_0 + 0.542410714285724*G0_1_0_19_1_1; + A[214] = A[213] + 0.108482142857144*G0_0_0_1_0_0 - 0.307366071428577*G0_0_0_2_0_1 + 0.343526785714296*G0_0_0_3_0_0 + 0.253125000000006*G0_0_0_3_0_1 - 0.452008928571435*G0_0_0_4_0_0 + 0.0542410714285756*G0_0_0_4_0_1 - 0.27120535714286*G0_0_0_5_0_0 - 0.271205357142862*G0_0_0_5_0_1 + 0.452008928571435*G0_0_0_6_0_0 + 0.578571428571438*G0_0_0_6_0_1 + 0.27120535714286*G0_0_0_7_0_0 + 0.271205357142862*G0_0_0_7_0_1 - 0.379687500000005*G0_0_0_8_0_0 - 0.253125000000006*G0_0_0_8_0_1 - 0.0723214285714362*G0_0_0_9_0_0 - 0.325446428571437*G0_0_0_9_0_1 + 0.108482142857144*G0_0_0_11_1_0 - 0.307366071428577*G0_0_0_12_1_1 + 0.343526785714296*G0_0_0_13_1_0 + 0.253125000000006*G0_0_0_13_1_1 - 0.452008928571435*G0_0_0_14_1_0 + 0.0542410714285756*G0_0_0_14_1_1 - 0.27120535714286*G0_0_0_15_1_0 - 0.271205357142862*G0_0_0_15_1_1 + 0.452008928571435*G0_0_0_16_1_0 + 0.578571428571438*G0_0_0_16_1_1 + 0.27120535714286*G0_0_0_17_1_0 + 0.271205357142862*G0_0_0_17_1_1 - 0.379687500000005*G0_0_0_18_1_0 - 0.253125000000006*G0_0_0_18_1_1 - 0.0723214285714362*G0_0_0_19_1_0 - 0.325446428571437*G0_0_0_19_1_1 + 0.307366071428575*G0_0_1_1_0_0 - 0.108482142857145*G0_0_1_2_0_1 - 0.0542410714285768*G0_0_1_3_0_0 + 0.452008928571432*G0_0_1_3_0_1 - 0.253125000000008*G0_0_1_4_0_0 - 0.343526785714296*G0_0_1_4_0_1 - 0.271205357142863*G0_0_1_5_0_0 - 0.271205357142859*G0_0_1_5_0_1 + 0.253125000000008*G0_0_1_6_0_0 + 0.379687500000005*G0_0_1_6_0_1 + 0.271205357142862*G0_0_1_7_0_0 + 0.271205357142858*G0_0_1_7_0_1 - 0.578571428571435*G0_0_1_8_0_0 - 0.452008928571432*G0_0_1_8_0_1 + 0.325446428571439*G0_0_1_9_0_0 + 0.0723214285714384*G0_0_1_9_0_1 + 0.307366071428575*G0_0_1_11_1_0 - 0.108482142857145*G0_0_1_12_1_1 - 0.0542410714285768*G0_0_1_13_1_0 + 0.452008928571432*G0_0_1_13_1_1 - 0.253125000000008*G0_0_1_14_1_0 - 0.343526785714296*G0_0_1_14_1_1 - 0.271205357142863*G0_0_1_15_1_0 - 0.271205357142859*G0_0_1_15_1_1 + 0.253125000000008*G0_0_1_16_1_0 + 0.379687500000005*G0_0_1_16_1_1 + 0.271205357142862*G0_0_1_17_1_0 + 0.271205357142858*G0_0_1_17_1_1 - 0.578571428571435*G0_0_1_18_1_0 - 0.452008928571432*G0_0_1_18_1_1 + 0.325446428571439*G0_0_1_19_1_0 + 0.0723214285714384*G0_0_1_19_1_1 + 0.108482142857144*G0_1_0_1_0_0 - 0.307366071428577*G0_1_0_2_0_1 + 0.343526785714296*G0_1_0_3_0_0 + 0.253125000000006*G0_1_0_3_0_1 - 0.452008928571435*G0_1_0_4_0_0 + 0.0542410714285756*G0_1_0_4_0_1 - 0.27120535714286*G0_1_0_5_0_0 - 0.271205357142862*G0_1_0_5_0_1 + 0.452008928571435*G0_1_0_6_0_0 + 0.578571428571438*G0_1_0_6_0_1 + 0.27120535714286*G0_1_0_7_0_0 + 0.271205357142861*G0_1_0_7_0_1 - 0.379687500000005*G0_1_0_8_0_0 - 0.253125000000006*G0_1_0_8_0_1 - 0.072321428571436*G0_1_0_9_0_0 - 0.325446428571437*G0_1_0_9_0_1 + 0.108482142857144*G0_1_0_11_1_0 - 0.307366071428577*G0_1_0_12_1_1 + 0.343526785714296*G0_1_0_13_1_0 + 0.253125000000006*G0_1_0_13_1_1 - 0.452008928571435*G0_1_0_14_1_0 + 0.0542410714285756*G0_1_0_14_1_1 - 0.27120535714286*G0_1_0_15_1_0 - 0.271205357142862*G0_1_0_15_1_1 + 0.452008928571435*G0_1_0_16_1_0 + 0.578571428571438*G0_1_0_16_1_1 + 0.27120535714286*G0_1_0_17_1_0 + 0.271205357142861*G0_1_0_17_1_1 - 0.379687500000005*G0_1_0_18_1_0 - 0.253125000000006*G0_1_0_18_1_1 - 0.072321428571436*G0_1_0_19_1_0 - 0.325446428571437*G0_1_0_19_1_1 + 0.307366071428575*G0_1_1_1_0_0 - 0.108482142857145*G0_1_1_2_0_1 - 0.0542410714285771*G0_1_1_3_0_0 + 0.452008928571431*G0_1_1_3_0_1 - 0.253125000000008*G0_1_1_4_0_0 - 0.343526785714296*G0_1_1_4_0_1 - 0.271205357142863*G0_1_1_5_0_0 - 0.271205357142859*G0_1_1_5_0_1 + 0.253125000000008*G0_1_1_6_0_0 + 0.379687500000005*G0_1_1_6_0_1 + 0.271205357142861*G0_1_1_7_0_0 + 0.271205357142857*G0_1_1_7_0_1 - 0.578571428571434*G0_1_1_8_0_0 - 0.452008928571431*G0_1_1_8_0_1 + 0.32544642857144*G0_1_1_9_0_0 + 0.072321428571439*G0_1_1_9_0_1 + 0.307366071428575*G0_1_1_11_1_0 - 0.108482142857145*G0_1_1_12_1_1 - 0.0542410714285771*G0_1_1_13_1_0 + 0.452008928571431*G0_1_1_13_1_1 - 0.253125000000008*G0_1_1_14_1_0 - 0.343526785714296*G0_1_1_14_1_1 - 0.271205357142863*G0_1_1_15_1_0 - 0.271205357142859*G0_1_1_15_1_1 + 0.253125000000008*G0_1_1_16_1_0 + 0.379687500000005*G0_1_1_16_1_1 + 0.271205357142861*G0_1_1_17_1_0 + 0.271205357142857*G0_1_1_17_1_1 - 0.578571428571434*G0_1_1_18_1_0 - 0.452008928571431*G0_1_1_18_1_1 + 0.32544642857144*G0_1_1_19_1_0 + 0.072321428571439*G0_1_1_19_1_1; + A[4] = A[214]; + A[216] = -A[214] - 0.649553571428579*G0_0_1_0_0_0 - 0.649553571428579*G0_0_1_0_0_1 + 0.0529017857142856*G0_0_1_1_0_0 + 0.33616071428572*G0_0_1_2_0_1 - 0.307366071428583*G0_0_1_3_0_0 - 0.150669642857147*G0_0_1_3_0_1 + 0.325446428571431*G0_0_1_4_0_0 - 0.114508928571438*G0_0_1_4_0_1 - 0.235044642857142*G0_0_1_5_0_0 + 1.07879464285716*G0_0_1_5_0_1 - 0.325446428571431*G0_0_1_6_0_0 - 0.765401785714301*G0_0_1_6_0_1 + 0.705133928571434*G0_0_1_7_0_0 - 0.608705357142866*G0_0_1_7_0_1 - 0.108482142857141*G0_0_1_8_0_0 + 0.150669642857147*G0_0_1_8_0_1 + 0.542410714285724*G0_0_1_9_0_0 + 0.723214285714305*G0_0_1_9_0_1 - 0.649553571428579*G0_0_1_10_1_0 - 0.649553571428579*G0_0_1_10_1_1 + 0.0529017857142856*G0_0_1_11_1_0 + 0.33616071428572*G0_0_1_12_1_1 - 0.307366071428583*G0_0_1_13_1_0 - 0.150669642857147*G0_0_1_13_1_1 + 0.325446428571431*G0_0_1_14_1_0 - 0.114508928571438*G0_0_1_14_1_1 - 0.235044642857142*G0_0_1_15_1_0 + 1.07879464285716*G0_0_1_15_1_1 - 0.325446428571431*G0_0_1_16_1_0 - 0.765401785714301*G0_0_1_16_1_1 + 0.705133928571434*G0_0_1_17_1_0 - 0.608705357142866*G0_0_1_17_1_1 - 0.108482142857141*G0_0_1_18_1_0 + 0.150669642857147*G0_0_1_18_1_1 + 0.542410714285724*G0_0_1_19_1_0 + 0.723214285714305*G0_0_1_19_1_1 - 0.649553571428579*G0_1_1_0_0_0 - 0.64955357142858*G0_1_1_0_0_1 + 0.0529017857142855*G0_1_1_1_0_0 + 0.33616071428572*G0_1_1_2_0_1 - 0.307366071428583*G0_1_1_3_0_0 - 0.150669642857147*G0_1_1_3_0_1 + 0.325446428571431*G0_1_1_4_0_0 - 0.114508928571438*G0_1_1_4_0_1 - 0.235044642857142*G0_1_1_5_0_0 + 1.07879464285716*G0_1_1_5_0_1 - 0.325446428571431*G0_1_1_6_0_0 - 0.765401785714301*G0_1_1_6_0_1 + 0.705133928571434*G0_1_1_7_0_0 - 0.608705357142867*G0_1_1_7_0_1 - 0.108482142857141*G0_1_1_8_0_0 + 0.150669642857147*G0_1_1_8_0_1 + 0.542410714285725*G0_1_1_9_0_0 + 0.723214285714306*G0_1_1_9_0_1 - 0.649553571428579*G0_1_1_10_1_0 - 0.64955357142858*G0_1_1_10_1_1 + 0.0529017857142855*G0_1_1_11_1_0 + 0.33616071428572*G0_1_1_12_1_1 - 0.307366071428583*G0_1_1_13_1_0 - 0.150669642857147*G0_1_1_13_1_1 + 0.325446428571431*G0_1_1_14_1_0 - 0.114508928571438*G0_1_1_14_1_1 - 0.235044642857142*G0_1_1_15_1_0 + 1.07879464285716*G0_1_1_15_1_1 - 0.325446428571431*G0_1_1_16_1_0 - 0.765401785714301*G0_1_1_16_1_1 + 0.705133928571434*G0_1_1_17_1_0 - 0.608705357142867*G0_1_1_17_1_1 - 0.108482142857141*G0_1_1_18_1_0 + 0.150669642857147*G0_1_1_18_1_1 + 0.542410714285725*G0_1_1_19_1_0 + 0.723214285714306*G0_1_1_19_1_1; + A[6] = A[216]; + A[80] = A[214] - 0.0120535714285711*G0_0_1_1_0_0 - 0.18683035714286*G0_0_1_2_0_1 + 0.259151785714294*G0_0_1_3_0_0 + 0.0482142857142891*G0_0_1_3_0_1 - 0.247098214285716*G0_0_1_4_0_0 + 0.138616071428578*G0_0_1_4_0_1 - 0.11450892857143*G0_0_1_5_0_0 - 0.114508928571432*G0_0_1_5_0_1 + 0.247098214285716*G0_0_1_6_0_0 + 0.301339285714292*G0_0_1_6_0_1 + 0.11450892857143*G0_0_1_7_0_0 + 0.114508928571432*G0_0_1_7_0_1 - 0.10245535714286*G0_0_1_8_0_0 - 0.048214285714289*G0_0_1_8_0_1 - 0.144642857142865*G0_0_1_9_0_0 - 0.25312500000001*G0_0_1_9_0_1 - 0.0120535714285711*G0_0_1_11_1_0 - 0.18683035714286*G0_0_1_12_1_1 + 0.259151785714294*G0_0_1_13_1_0 + 0.0482142857142891*G0_0_1_13_1_1 - 0.247098214285716*G0_0_1_14_1_0 + 0.138616071428578*G0_0_1_14_1_1 - 0.11450892857143*G0_0_1_15_1_0 - 0.114508928571432*G0_0_1_15_1_1 + 0.247098214285716*G0_0_1_16_1_0 + 0.301339285714292*G0_0_1_16_1_1 + 0.11450892857143*G0_0_1_17_1_0 + 0.114508928571432*G0_0_1_17_1_1 - 0.10245535714286*G0_0_1_18_1_0 - 0.048214285714289*G0_0_1_18_1_1 - 0.144642857142865*G0_0_1_19_1_0 - 0.25312500000001*G0_0_1_19_1_1 + 0.0120535714285711*G0_1_0_1_0_0 + 0.18683035714286*G0_1_0_2_0_1 - 0.259151785714294*G0_1_0_3_0_0 - 0.0482142857142891*G0_1_0_3_0_1 + 0.247098214285717*G0_1_0_4_0_0 - 0.138616071428578*G0_1_0_4_0_1 + 0.11450892857143*G0_1_0_5_0_0 + 0.114508928571432*G0_1_0_5_0_1 - 0.247098214285716*G0_1_0_6_0_0 - 0.301339285714292*G0_1_0_6_0_1 - 0.11450892857143*G0_1_0_7_0_0 - 0.114508928571432*G0_1_0_7_0_1 + 0.10245535714286*G0_1_0_8_0_0 + 0.048214285714289*G0_1_0_8_0_1 + 0.144642857142865*G0_1_0_9_0_0 + 0.25312500000001*G0_1_0_9_0_1 + 0.0120535714285711*G0_1_0_11_1_0 + 0.18683035714286*G0_1_0_12_1_1 - 0.259151785714294*G0_1_0_13_1_0 - 0.0482142857142891*G0_1_0_13_1_1 + 0.247098214285717*G0_1_0_14_1_0 - 0.138616071428578*G0_1_0_14_1_1 + 0.11450892857143*G0_1_0_15_1_0 + 0.114508928571432*G0_1_0_15_1_1 - 0.247098214285716*G0_1_0_16_1_0 - 0.301339285714292*G0_1_0_16_1_1 - 0.11450892857143*G0_1_0_17_1_0 - 0.114508928571432*G0_1_0_17_1_1 + 0.10245535714286*G0_1_0_18_1_0 + 0.048214285714289*G0_1_0_18_1_1 + 0.144642857142865*G0_1_0_19_1_0 + 0.25312500000001*G0_1_0_19_1_1; + A[350] = -A[80] + 1.59241071428573*G0_0_0_0_0_0 + 1.59241071428573*G0_0_0_0_0_1 - 0.387053571428576*G0_0_0_1_0_0 - 0.45334821428572*G0_0_0_2_0_1 - 0.259151785714292*G0_0_0_3_0_0 - 0.325446428571435*G0_0_0_3_0_1 - 0.439955357142867*G0_0_0_4_0_0 - 0.307366071428581*G0_0_0_4_0_1 + 0.259151785714281*G0_0_0_5_0_0 - 2.47700892857146*G0_0_0_5_0_1 + 0.439955357142867*G0_0_0_6_0_0 + 1.33794642857145*G0_0_0_6_0_1 - 2.39263392857146*G0_0_0_7_0_0 + 0.34352678571428*G0_0_0_7_0_1 + 1.1872767857143*G0_0_0_8_0_0 + 0.325446428571435*G0_0_0_8_0_1 - 0.036160714285701*G0_0_0_9_0_1 + 1.59241071428573*G0_0_0_10_1_0 + 1.59241071428573*G0_0_0_10_1_1 - 0.387053571428576*G0_0_0_11_1_0 - 0.45334821428572*G0_0_0_12_1_1 - 0.259151785714292*G0_0_0_13_1_0 - 0.325446428571435*G0_0_0_13_1_1 - 0.439955357142867*G0_0_0_14_1_0 - 0.307366071428581*G0_0_0_14_1_1 + 0.259151785714281*G0_0_0_15_1_0 - 2.47700892857146*G0_0_0_15_1_1 + 0.439955357142867*G0_0_0_16_1_0 + 1.33794642857145*G0_0_0_16_1_1 - 2.39263392857146*G0_0_0_17_1_0 + 0.34352678571428*G0_0_0_17_1_1 + 1.1872767857143*G0_0_0_18_1_0 + 0.325446428571435*G0_0_0_18_1_1 - 0.036160714285701*G0_0_0_19_1_1 + 1.59241071428573*G0_0_1_0_0_0 + 1.59241071428573*G0_0_1_0_0_1 - 0.387053571428576*G0_0_1_1_0_0 - 0.45334821428572*G0_0_1_2_0_1 - 0.259151785714292*G0_0_1_3_0_0 - 0.325446428571435*G0_0_1_3_0_1 - 0.439955357142867*G0_0_1_4_0_0 - 0.307366071428581*G0_0_1_4_0_1 + 0.259151785714281*G0_0_1_5_0_0 - 2.47700892857146*G0_0_1_5_0_1 + 0.439955357142867*G0_0_1_6_0_0 + 1.33794642857145*G0_0_1_6_0_1 - 2.39263392857146*G0_0_1_7_0_0 + 0.34352678571428*G0_0_1_7_0_1 + 1.1872767857143*G0_0_1_8_0_0 + 0.325446428571435*G0_0_1_8_0_1 - 0.0361607142857007*G0_0_1_9_0_1 + 1.59241071428573*G0_0_1_10_1_0 + 1.59241071428573*G0_0_1_10_1_1 - 0.387053571428576*G0_0_1_11_1_0 - 0.45334821428572*G0_0_1_12_1_1 - 0.259151785714292*G0_0_1_13_1_0 - 0.325446428571435*G0_0_1_13_1_1 - 0.439955357142867*G0_0_1_14_1_0 - 0.307366071428581*G0_0_1_14_1_1 + 0.259151785714281*G0_0_1_15_1_0 - 2.47700892857146*G0_0_1_15_1_1 + 0.439955357142867*G0_0_1_16_1_0 + 1.33794642857145*G0_0_1_16_1_1 - 2.39263392857146*G0_0_1_17_1_0 + 0.34352678571428*G0_0_1_17_1_1 + 1.1872767857143*G0_0_1_18_1_0 + 0.325446428571435*G0_0_1_18_1_1 - 0.0361607142857007*G0_0_1_19_1_1 - 0.433928571428572*G0_1_0_0_0_0 - 0.433928571428573*G0_1_0_0_0_1 - 0.108482142857146*G0_1_0_1_0_0 - 0.687053571428589*G0_1_0_3_0_0 - 0.542410714285724*G0_1_0_3_0_1 - 0.361607142857152*G0_1_0_4_0_0 - 0.614732142857162*G0_1_0_4_0_1 - 0.687053571428582*G0_1_0_5_0_0 + 0.542410714285715*G0_1_0_5_0_1 + 0.361607142857152*G0_1_0_6_0_0 - 0.108482142857142*G0_1_0_6_0_1 + 0.397767857142852*G0_1_0_7_0_0 - 0.831696428571445*G0_1_0_7_0_1 + 0.144642857142866*G0_1_0_8_0_0 + 0.542410714285724*G0_1_0_8_0_1 + 1.37410714285717*G0_1_0_9_0_0 + 1.44642857142861*G0_1_0_9_0_1 - 0.433928571428572*G0_1_0_10_1_0 - 0.433928571428573*G0_1_0_10_1_1 - 0.108482142857146*G0_1_0_11_1_0 - 0.687053571428589*G0_1_0_13_1_0 - 0.542410714285724*G0_1_0_13_1_1 - 0.361607142857152*G0_1_0_14_1_0 - 0.614732142857162*G0_1_0_14_1_1 - 0.687053571428582*G0_1_0_15_1_0 + 0.542410714285715*G0_1_0_15_1_1 + 0.361607142857152*G0_1_0_16_1_0 - 0.108482142857142*G0_1_0_16_1_1 + 0.397767857142852*G0_1_0_17_1_0 - 0.831696428571445*G0_1_0_17_1_1 + 0.144642857142866*G0_1_0_18_1_0 + 0.542410714285724*G0_1_0_18_1_1 + 1.37410714285717*G0_1_0_19_1_0 + 1.44642857142861*G0_1_0_19_1_1 - 0.433928571428573*G0_1_1_0_0_0 - 0.433928571428573*G0_1_1_0_0_1 - 0.108482142857146*G0_1_1_1_0_0 - 0.687053571428589*G0_1_1_3_0_0 - 0.542410714285724*G0_1_1_3_0_1 - 0.361607142857152*G0_1_1_4_0_0 - 0.614732142857163*G0_1_1_4_0_1 - 0.687053571428582*G0_1_1_5_0_0 + 0.542410714285715*G0_1_1_5_0_1 + 0.361607142857152*G0_1_1_6_0_0 - 0.108482142857142*G0_1_1_6_0_1 + 0.397767857142852*G0_1_1_7_0_0 - 0.831696428571445*G0_1_1_7_0_1 + 0.144642857142867*G0_1_1_8_0_0 + 0.542410714285724*G0_1_1_8_0_1 + 1.37410714285717*G0_1_1_9_0_0 + 1.44642857142861*G0_1_1_9_0_1 - 0.433928571428573*G0_1_1_10_1_0 - 0.433928571428573*G0_1_1_10_1_1 - 0.108482142857146*G0_1_1_11_1_0 - 0.687053571428589*G0_1_1_13_1_0 - 0.542410714285724*G0_1_1_13_1_1 - 0.361607142857152*G0_1_1_14_1_0 - 0.614732142857163*G0_1_1_14_1_1 - 0.687053571428582*G0_1_1_15_1_0 + 0.542410714285715*G0_1_1_15_1_1 + 0.361607142857152*G0_1_1_16_1_0 - 0.108482142857142*G0_1_1_16_1_1 + 0.397767857142852*G0_1_1_17_1_0 - 0.831696428571445*G0_1_1_17_1_1 + 0.144642857142867*G0_1_1_18_1_0 + 0.542410714285724*G0_1_1_18_1_1 + 1.37410714285717*G0_1_1_19_1_0 + 1.44642857142861*G0_1_1_19_1_1; + A[217] = A[350] - 2.0263392857143*G0_0_1_0_0_0 - 2.0263392857143*G0_0_1_0_0_1 + 0.26651785714286*G0_0_1_1_0_0 + 0.26651785714286*G0_0_1_2_0_1 - 0.168750000000003*G0_0_1_3_0_0 - 0.16875*G0_0_1_3_0_1 - 0.168750000000001*G0_0_1_4_0_0 - 0.168750000000004*G0_0_1_4_0_1 - 1.06071428571429*G0_0_1_5_0_0 + 2.90491071428574*G0_0_1_5_0_1 + 0.168750000000001*G0_0_1_6_0_0 - 1.1450892857143*G0_0_1_6_0_1 + 2.90491071428574*G0_0_1_7_0_0 - 1.06071428571429*G0_0_1_7_0_1 - 1.14508928571429*G0_0_1_8_0_0 + 0.16875*G0_0_1_8_0_1 + 1.2294642857143*G0_0_1_9_0_0 + 1.2294642857143*G0_0_1_9_0_1 - 2.0263392857143*G0_0_1_10_1_0 - 2.0263392857143*G0_0_1_10_1_1 + 0.26651785714286*G0_0_1_11_1_0 + 0.26651785714286*G0_0_1_12_1_1 - 0.168750000000003*G0_0_1_13_1_0 - 0.16875*G0_0_1_13_1_1 - 0.168750000000001*G0_0_1_14_1_0 - 0.168750000000004*G0_0_1_14_1_1 - 1.06071428571429*G0_0_1_15_1_0 + 2.90491071428574*G0_0_1_15_1_1 + 0.168750000000001*G0_0_1_16_1_0 - 1.1450892857143*G0_0_1_16_1_1 + 2.90491071428574*G0_0_1_17_1_0 - 1.06071428571429*G0_0_1_17_1_1 - 1.14508928571429*G0_0_1_18_1_0 + 0.16875*G0_0_1_18_1_1 + 1.2294642857143*G0_0_1_19_1_0 + 1.2294642857143*G0_0_1_19_1_1 + 2.0263392857143*G0_1_0_0_0_0 + 2.0263392857143*G0_1_0_0_0_1 - 0.26651785714286*G0_1_0_1_0_0 - 0.26651785714286*G0_1_0_2_0_1 + 0.168750000000003*G0_1_0_3_0_0 + 0.16875*G0_1_0_3_0_1 + 0.168750000000001*G0_1_0_4_0_0 + 0.168750000000004*G0_1_0_4_0_1 + 1.06071428571429*G0_1_0_5_0_0 - 2.90491071428574*G0_1_0_5_0_1 - 0.168750000000001*G0_1_0_6_0_0 + 1.1450892857143*G0_1_0_6_0_1 - 2.90491071428574*G0_1_0_7_0_0 + 1.06071428571429*G0_1_0_7_0_1 + 1.14508928571429*G0_1_0_8_0_0 - 0.16875*G0_1_0_8_0_1 - 1.2294642857143*G0_1_0_9_0_0 - 1.2294642857143*G0_1_0_9_0_1 + 2.0263392857143*G0_1_0_10_1_0 + 2.0263392857143*G0_1_0_10_1_1 - 0.26651785714286*G0_1_0_11_1_0 - 0.26651785714286*G0_1_0_12_1_1 + 0.168750000000003*G0_1_0_13_1_0 + 0.16875*G0_1_0_13_1_1 + 0.168750000000001*G0_1_0_14_1_0 + 0.168750000000004*G0_1_0_14_1_1 + 1.06071428571429*G0_1_0_15_1_0 - 2.90491071428574*G0_1_0_15_1_1 - 0.168750000000001*G0_1_0_16_1_0 + 1.1450892857143*G0_1_0_16_1_1 - 2.90491071428574*G0_1_0_17_1_0 + 1.06071428571429*G0_1_0_17_1_1 + 1.14508928571429*G0_1_0_18_1_0 - 0.16875*G0_1_0_18_1_1 - 1.2294642857143*G0_1_0_19_1_0 - 1.2294642857143*G0_1_0_19_1_1; + A[7] = A[217]; + A[140] = A[350]; + A[120] = -A[80] - 0.649553571428579*G0_1_0_0_0_0 - 0.649553571428579*G0_1_0_0_0_1 + 0.0529017857142857*G0_1_0_1_0_0 + 0.33616071428572*G0_1_0_2_0_1 - 0.307366071428583*G0_1_0_3_0_0 - 0.150669642857147*G0_1_0_3_0_1 + 0.325446428571431*G0_1_0_4_0_0 - 0.114508928571438*G0_1_0_4_0_1 - 0.235044642857142*G0_1_0_5_0_0 + 1.07879464285716*G0_1_0_5_0_1 - 0.325446428571431*G0_1_0_6_0_0 - 0.765401785714301*G0_1_0_6_0_1 + 0.705133928571434*G0_1_0_7_0_0 - 0.608705357142866*G0_1_0_7_0_1 - 0.108482142857141*G0_1_0_8_0_0 + 0.150669642857147*G0_1_0_8_0_1 + 0.542410714285724*G0_1_0_9_0_0 + 0.723214285714305*G0_1_0_9_0_1 - 0.649553571428579*G0_1_0_10_1_0 - 0.649553571428579*G0_1_0_10_1_1 + 0.0529017857142857*G0_1_0_11_1_0 + 0.33616071428572*G0_1_0_12_1_1 - 0.307366071428583*G0_1_0_13_1_0 - 0.150669642857147*G0_1_0_13_1_1 + 0.325446428571431*G0_1_0_14_1_0 - 0.114508928571438*G0_1_0_14_1_1 - 0.235044642857142*G0_1_0_15_1_0 + 1.07879464285716*G0_1_0_15_1_1 - 0.325446428571431*G0_1_0_16_1_0 - 0.765401785714301*G0_1_0_16_1_1 + 0.705133928571434*G0_1_0_17_1_0 - 0.608705357142866*G0_1_0_17_1_1 - 0.108482142857141*G0_1_0_18_1_0 + 0.150669642857147*G0_1_0_18_1_1 + 0.542410714285724*G0_1_0_19_1_0 + 0.723214285714305*G0_1_0_19_1_1 - 0.649553571428579*G0_1_1_0_0_0 - 0.64955357142858*G0_1_1_0_0_1 + 0.0529017857142855*G0_1_1_1_0_0 + 0.33616071428572*G0_1_1_2_0_1 - 0.307366071428583*G0_1_1_3_0_0 - 0.150669642857147*G0_1_1_3_0_1 + 0.325446428571431*G0_1_1_4_0_0 - 0.114508928571438*G0_1_1_4_0_1 - 0.235044642857142*G0_1_1_5_0_0 + 1.07879464285716*G0_1_1_5_0_1 - 0.325446428571431*G0_1_1_6_0_0 - 0.765401785714301*G0_1_1_6_0_1 + 0.705133928571434*G0_1_1_7_0_0 - 0.608705357142867*G0_1_1_7_0_1 - 0.108482142857141*G0_1_1_8_0_0 + 0.150669642857147*G0_1_1_8_0_1 + 0.542410714285725*G0_1_1_9_0_0 + 0.723214285714306*G0_1_1_9_0_1 - 0.649553571428579*G0_1_1_10_1_0 - 0.64955357142858*G0_1_1_10_1_1 + 0.0529017857142855*G0_1_1_11_1_0 + 0.33616071428572*G0_1_1_12_1_1 - 0.307366071428583*G0_1_1_13_1_0 - 0.150669642857147*G0_1_1_13_1_1 + 0.325446428571431*G0_1_1_14_1_0 - 0.114508928571438*G0_1_1_14_1_1 - 0.235044642857142*G0_1_1_15_1_0 + 1.07879464285716*G0_1_1_15_1_1 - 0.325446428571431*G0_1_1_16_1_0 - 0.765401785714301*G0_1_1_16_1_1 + 0.705133928571434*G0_1_1_17_1_0 - 0.608705357142867*G0_1_1_17_1_1 - 0.108482142857141*G0_1_1_18_1_0 + 0.150669642857147*G0_1_1_18_1_1 + 0.542410714285725*G0_1_1_19_1_0 + 0.723214285714306*G0_1_1_19_1_1; + A[330] = A[120]; + A[220] = 0.0; + A[196] = 0.0; + A[295] = A[85]; + A[251] = A[41]; + A[314] = A[104]; + A[270] = A[213] + 0.18683035714286*G0_0_1_1_0_0 + 0.0120535714285714*G0_0_1_2_0_1 - 0.138616071428579*G0_0_1_3_0_0 + 0.247098214285715*G0_0_1_3_0_1 - 0.0482142857142888*G0_0_1_4_0_0 - 0.259151785714294*G0_0_1_4_0_1 - 0.114508928571432*G0_0_1_5_0_0 - 0.114508928571429*G0_0_1_5_0_1 + 0.0482142857142888*G0_0_1_6_0_0 + 0.102455357142858*G0_0_1_6_0_1 + 0.114508928571432*G0_0_1_7_0_0 + 0.114508928571429*G0_0_1_7_0_1 - 0.30133928571429*G0_0_1_8_0_0 - 0.247098214285715*G0_0_1_8_0_1 + 0.253125000000011*G0_0_1_9_0_0 + 0.144642857142865*G0_0_1_9_0_1 + 0.18683035714286*G0_0_1_11_1_0 + 0.0120535714285714*G0_0_1_12_1_1 - 0.138616071428579*G0_0_1_13_1_0 + 0.247098214285715*G0_0_1_13_1_1 - 0.0482142857142888*G0_0_1_14_1_0 - 0.259151785714294*G0_0_1_14_1_1 - 0.114508928571432*G0_0_1_15_1_0 - 0.114508928571429*G0_0_1_15_1_1 + 0.0482142857142888*G0_0_1_16_1_0 + 0.102455357142858*G0_0_1_16_1_1 + 0.114508928571432*G0_0_1_17_1_0 + 0.114508928571429*G0_0_1_17_1_1 - 0.30133928571429*G0_0_1_18_1_0 - 0.247098214285715*G0_0_1_18_1_1 + 0.253125000000011*G0_0_1_19_1_0 + 0.144642857142865*G0_0_1_19_1_1 - 0.18683035714286*G0_1_0_1_0_0 - 0.0120535714285714*G0_1_0_2_0_1 + 0.138616071428579*G0_1_0_3_0_0 - 0.247098214285715*G0_1_0_3_0_1 + 0.0482142857142888*G0_1_0_4_0_0 + 0.259151785714294*G0_1_0_4_0_1 + 0.114508928571432*G0_1_0_5_0_0 + 0.114508928571429*G0_1_0_5_0_1 - 0.0482142857142888*G0_1_0_6_0_0 - 0.102455357142858*G0_1_0_6_0_1 - 0.114508928571432*G0_1_0_7_0_0 - 0.114508928571429*G0_1_0_7_0_1 + 0.30133928571429*G0_1_0_8_0_0 + 0.247098214285715*G0_1_0_8_0_1 - 0.253125000000011*G0_1_0_9_0_0 - 0.144642857142865*G0_1_0_9_0_1 - 0.18683035714286*G0_1_0_11_1_0 - 0.0120535714285714*G0_1_0_12_1_1 + 0.138616071428579*G0_1_0_13_1_0 - 0.247098214285715*G0_1_0_13_1_1 + 0.0482142857142888*G0_1_0_14_1_0 + 0.259151785714294*G0_1_0_14_1_1 + 0.114508928571432*G0_1_0_15_1_0 + 0.114508928571429*G0_1_0_15_1_1 - 0.0482142857142888*G0_1_0_16_1_0 - 0.102455357142858*G0_1_0_16_1_1 - 0.114508928571432*G0_1_0_17_1_0 - 0.114508928571429*G0_1_0_17_1_1 + 0.30133928571429*G0_1_0_18_1_0 + 0.247098214285715*G0_1_0_18_1_1 - 0.253125000000011*G0_1_0_19_1_0 - 0.144642857142865*G0_1_0_19_1_1; + A[310] = -A[270] - 0.433928571428572*G0_0_0_0_0_0 - 0.433928571428573*G0_0_0_0_0_1 - 0.108482142857145*G0_0_0_2_0_1 - 0.614732142857161*G0_0_0_3_0_0 - 0.36160714285715*G0_0_0_3_0_1 - 0.542410714285725*G0_0_0_4_0_0 - 0.68705357142859*G0_0_0_4_0_1 - 0.831696428571444*G0_0_0_5_0_0 + 0.397767857142852*G0_0_0_5_0_1 + 0.542410714285725*G0_0_0_6_0_0 + 0.144642857142866*G0_0_0_6_0_1 + 0.542410714285715*G0_0_0_7_0_0 - 0.687053571428581*G0_0_0_7_0_1 - 0.108482142857142*G0_0_0_8_0_0 + 0.36160714285715*G0_0_0_8_0_1 + 1.44642857142861*G0_0_0_9_0_0 + 1.37410714285717*G0_0_0_9_0_1 - 0.433928571428572*G0_0_0_10_1_0 - 0.433928571428573*G0_0_0_10_1_1 - 0.108482142857145*G0_0_0_12_1_1 - 0.614732142857161*G0_0_0_13_1_0 - 0.36160714285715*G0_0_0_13_1_1 - 0.542410714285725*G0_0_0_14_1_0 - 0.68705357142859*G0_0_0_14_1_1 - 0.831696428571444*G0_0_0_15_1_0 + 0.397767857142852*G0_0_0_15_1_1 + 0.542410714285725*G0_0_0_16_1_0 + 0.144642857142866*G0_0_0_16_1_1 + 0.542410714285715*G0_0_0_17_1_0 - 0.687053571428581*G0_0_0_17_1_1 - 0.108482142857142*G0_0_0_18_1_0 + 0.36160714285715*G0_0_0_18_1_1 + 1.44642857142861*G0_0_0_19_1_0 + 1.37410714285717*G0_0_0_19_1_1 - 0.433928571428573*G0_0_1_0_0_0 - 0.433928571428573*G0_0_1_0_0_1 - 0.108482142857146*G0_0_1_2_0_1 - 0.614732142857161*G0_0_1_3_0_0 - 0.36160714285715*G0_0_1_3_0_1 - 0.542410714285725*G0_0_1_4_0_0 - 0.68705357142859*G0_0_1_4_0_1 - 0.831696428571444*G0_0_1_5_0_0 + 0.397767857142852*G0_0_1_5_0_1 + 0.542410714285725*G0_0_1_6_0_0 + 0.144642857142865*G0_0_1_6_0_1 + 0.542410714285715*G0_0_1_7_0_0 - 0.687053571428581*G0_0_1_7_0_1 - 0.108482142857142*G0_0_1_8_0_0 + 0.36160714285715*G0_0_1_8_0_1 + 1.44642857142861*G0_0_1_9_0_0 + 1.37410714285717*G0_0_1_9_0_1 - 0.433928571428573*G0_0_1_10_1_0 - 0.433928571428573*G0_0_1_10_1_1 - 0.108482142857146*G0_0_1_12_1_1 - 0.614732142857161*G0_0_1_13_1_0 - 0.36160714285715*G0_0_1_13_1_1 - 0.542410714285725*G0_0_1_14_1_0 - 0.68705357142859*G0_0_1_14_1_1 - 0.831696428571444*G0_0_1_15_1_0 + 0.397767857142852*G0_0_1_15_1_1 + 0.542410714285725*G0_0_1_16_1_0 + 0.144642857142865*G0_0_1_16_1_1 + 0.542410714285715*G0_0_1_17_1_0 - 0.687053571428581*G0_0_1_17_1_1 - 0.108482142857142*G0_0_1_18_1_0 + 0.36160714285715*G0_0_1_18_1_1 + 1.44642857142861*G0_0_1_19_1_0 + 1.37410714285717*G0_0_1_19_1_1 + 1.59241071428573*G0_1_0_0_0_0 + 1.59241071428573*G0_1_0_0_0_1 - 0.45334821428572*G0_1_0_1_0_0 - 0.387053571428577*G0_1_0_2_0_1 - 0.307366071428579*G0_1_0_3_0_0 - 0.439955357142865*G0_1_0_3_0_1 - 0.325446428571435*G0_1_0_4_0_0 - 0.259151785714292*G0_1_0_4_0_1 + 0.343526785714281*G0_1_0_5_0_0 - 2.39263392857146*G0_1_0_5_0_1 + 0.325446428571435*G0_1_0_6_0_0 + 1.1872767857143*G0_1_0_6_0_1 - 2.47700892857146*G0_1_0_7_0_0 + 0.259151785714283*G0_1_0_7_0_1 + 1.33794642857144*G0_1_0_8_0_0 + 0.439955357142866*G0_1_0_8_0_1 - 0.0361607142857013*G0_1_0_9_0_0 + 1.59241071428573*G0_1_0_10_1_0 + 1.59241071428573*G0_1_0_10_1_1 - 0.45334821428572*G0_1_0_11_1_0 - 0.387053571428577*G0_1_0_12_1_1 - 0.307366071428579*G0_1_0_13_1_0 - 0.439955357142865*G0_1_0_13_1_1 - 0.325446428571435*G0_1_0_14_1_0 - 0.259151785714292*G0_1_0_14_1_1 + 0.343526785714281*G0_1_0_15_1_0 - 2.39263392857146*G0_1_0_15_1_1 + 0.325446428571435*G0_1_0_16_1_0 + 1.1872767857143*G0_1_0_16_1_1 - 2.47700892857146*G0_1_0_17_1_0 + 0.259151785714283*G0_1_0_17_1_1 + 1.33794642857144*G0_1_0_18_1_0 + 0.439955357142866*G0_1_0_18_1_1 - 0.0361607142857013*G0_1_0_19_1_0 + 1.59241071428573*G0_1_1_0_0_0 + 1.59241071428573*G0_1_1_0_0_1 - 0.453348214285719*G0_1_1_1_0_0 - 0.387053571428577*G0_1_1_2_0_1 - 0.307366071428579*G0_1_1_3_0_0 - 0.439955357142865*G0_1_1_3_0_1 - 0.325446428571435*G0_1_1_4_0_0 - 0.259151785714292*G0_1_1_4_0_1 + 0.343526785714281*G0_1_1_5_0_0 - 2.39263392857146*G0_1_1_5_0_1 + 0.325446428571435*G0_1_1_6_0_0 + 1.1872767857143*G0_1_1_6_0_1 - 2.47700892857146*G0_1_1_7_0_0 + 0.259151785714284*G0_1_1_7_0_1 + 1.33794642857144*G0_1_1_8_0_0 + 0.439955357142865*G0_1_1_8_0_1 - 0.0361607142857018*G0_1_1_9_0_0 + 1.59241071428573*G0_1_1_10_1_0 + 1.59241071428573*G0_1_1_10_1_1 - 0.453348214285719*G0_1_1_11_1_0 - 0.387053571428577*G0_1_1_12_1_1 - 0.307366071428579*G0_1_1_13_1_0 - 0.439955357142865*G0_1_1_13_1_1 - 0.325446428571435*G0_1_1_14_1_0 - 0.259151785714292*G0_1_1_14_1_1 + 0.343526785714281*G0_1_1_15_1_0 - 2.39263392857146*G0_1_1_15_1_1 + 0.325446428571435*G0_1_1_16_1_0 + 1.1872767857143*G0_1_1_16_1_1 - 2.47700892857146*G0_1_1_17_1_0 + 0.259151785714284*G0_1_1_17_1_1 + 1.33794642857144*G0_1_1_18_1_0 + 0.439955357142865*G0_1_1_18_1_1 - 0.0361607142857018*G0_1_1_19_1_0; + A[5] = A[310] + 2.0263392857143*G0_0_1_0_0_0 + 2.0263392857143*G0_0_1_0_0_1 - 0.26651785714286*G0_0_1_1_0_0 - 0.26651785714286*G0_0_1_2_0_1 + 0.168750000000003*G0_0_1_3_0_0 + 0.16875*G0_0_1_3_0_1 + 0.168750000000002*G0_0_1_4_0_0 + 0.168750000000004*G0_0_1_4_0_1 + 1.06071428571429*G0_0_1_5_0_0 - 2.90491071428574*G0_0_1_5_0_1 - 0.168750000000001*G0_0_1_6_0_0 + 1.1450892857143*G0_0_1_6_0_1 - 2.90491071428574*G0_0_1_7_0_0 + 1.06071428571429*G0_0_1_7_0_1 + 1.1450892857143*G0_0_1_8_0_0 - 0.16875*G0_0_1_8_0_1 - 1.2294642857143*G0_0_1_9_0_0 - 1.2294642857143*G0_0_1_9_0_1 + 2.0263392857143*G0_0_1_10_1_0 + 2.0263392857143*G0_0_1_10_1_1 - 0.26651785714286*G0_0_1_11_1_0 - 0.26651785714286*G0_0_1_12_1_1 + 0.168750000000003*G0_0_1_13_1_0 + 0.16875*G0_0_1_13_1_1 + 0.168750000000002*G0_0_1_14_1_0 + 0.168750000000004*G0_0_1_14_1_1 + 1.06071428571429*G0_0_1_15_1_0 - 2.90491071428574*G0_0_1_15_1_1 - 0.168750000000001*G0_0_1_16_1_0 + 1.1450892857143*G0_0_1_16_1_1 - 2.90491071428574*G0_0_1_17_1_0 + 1.06071428571429*G0_0_1_17_1_1 + 1.1450892857143*G0_0_1_18_1_0 - 0.16875*G0_0_1_18_1_1 - 1.2294642857143*G0_0_1_19_1_0 - 1.2294642857143*G0_0_1_19_1_1 - 2.0263392857143*G0_1_0_0_0_0 - 2.0263392857143*G0_1_0_0_0_1 + 0.26651785714286*G0_1_0_1_0_0 + 0.26651785714286*G0_1_0_2_0_1 - 0.168750000000003*G0_1_0_3_0_0 - 0.16875*G0_1_0_3_0_1 - 0.168750000000002*G0_1_0_4_0_0 - 0.168750000000004*G0_1_0_4_0_1 - 1.06071428571429*G0_1_0_5_0_0 + 2.90491071428574*G0_1_0_5_0_1 + 0.168750000000002*G0_1_0_6_0_0 - 1.1450892857143*G0_1_0_6_0_1 + 2.90491071428574*G0_1_0_7_0_0 - 1.06071428571429*G0_1_0_7_0_1 - 1.1450892857143*G0_1_0_8_0_0 + 0.16875*G0_1_0_8_0_1 + 1.2294642857143*G0_1_0_9_0_0 + 1.2294642857143*G0_1_0_9_0_1 - 2.0263392857143*G0_1_0_10_1_0 - 2.0263392857143*G0_1_0_10_1_1 + 0.26651785714286*G0_1_0_11_1_0 + 0.26651785714286*G0_1_0_12_1_1 - 0.168750000000003*G0_1_0_13_1_0 - 0.16875*G0_1_0_13_1_1 - 0.168750000000002*G0_1_0_14_1_0 - 0.168750000000004*G0_1_0_14_1_1 - 1.06071428571429*G0_1_0_15_1_0 + 2.90491071428574*G0_1_0_15_1_1 + 0.168750000000002*G0_1_0_16_1_0 - 1.1450892857143*G0_1_0_16_1_1 + 2.90491071428574*G0_1_0_17_1_0 - 1.06071428571429*G0_1_0_17_1_1 - 1.1450892857143*G0_1_0_18_1_0 + 0.16875*G0_1_0_18_1_1 + 1.2294642857143*G0_1_0_19_1_0 + 1.2294642857143*G0_1_0_19_1_1; + A[215] = A[5]; + A[100] = A[310]; + A[57] = 0.0; + A[1] = -A[41] + 0.182589285714288*G0_0_0_0_0_0 + 0.182589285714288*G0_0_0_0_0_1 - 0.182589285714288*G0_0_0_1_0_0 - 0.00781249999999974*G0_0_0_2_0_1 - 0.0796875000000009*G0_0_0_3_0_0 - 0.266517857142861*G0_0_0_3_0_1 + 0.0287946428571436*G0_0_0_4_0_0 + 0.0408482142857147*G0_0_0_4_0_1 + 0.0796875000000008*G0_0_0_5_0_0 - 0.186830357142859*G0_0_0_5_0_1 - 0.0287946428571436*G0_0_0_6_0_0 + 0.0120535714285709*G0_0_0_6_0_1 - 0.41584821428572*G0_0_0_7_0_0 - 0.14933035714286*G0_0_0_7_0_1 + 0.41584821428572*G0_0_0_8_0_0 + 0.266517857142861*G0_0_0_8_0_1 + 0.108482142857145*G0_0_0_9_0_1 + 0.182589285714288*G0_0_0_10_1_0 + 0.182589285714288*G0_0_0_10_1_1 - 0.182589285714288*G0_0_0_11_1_0 - 0.00781249999999974*G0_0_0_12_1_1 - 0.0796875000000009*G0_0_0_13_1_0 - 0.266517857142861*G0_0_0_13_1_1 + 0.0287946428571436*G0_0_0_14_1_0 + 0.0408482142857147*G0_0_0_14_1_1 + 0.0796875000000008*G0_0_0_15_1_0 - 0.186830357142859*G0_0_0_15_1_1 - 0.0287946428571436*G0_0_0_16_1_0 + 0.0120535714285709*G0_0_0_16_1_1 - 0.41584821428572*G0_0_0_17_1_0 - 0.14933035714286*G0_0_0_17_1_1 + 0.41584821428572*G0_0_0_18_1_0 + 0.266517857142861*G0_0_0_18_1_1 + 0.108482142857145*G0_0_0_19_1_1 + 0.174776785714288*G0_1_0_0_0_0 + 0.174776785714288*G0_1_0_0_0_1 + 0.174776785714289*G0_1_0_2_0_1 - 0.229017857142862*G0_1_0_3_0_0 + 0.295312500000005*G0_1_0_4_0_0 - 0.108482142857145*G0_1_0_4_0_1 + 0.120535714285716*G0_1_0_5_0_0 - 0.174776785714288*G0_1_0_5_0_1 - 0.295312500000005*G0_1_0_6_0_0 - 0.174776785714289*G0_1_0_6_0_1 - 0.403794642857149*G0_1_0_7_0_0 - 0.108482142857146*G0_1_0_7_0_1 + 0.229017857142861*G0_1_0_8_0_0 + 0.108482142857146*G0_1_0_9_0_0 + 0.216964285714291*G0_1_0_9_0_1 + 0.174776785714288*G0_1_0_10_1_0 + 0.174776785714288*G0_1_0_10_1_1 + 0.174776785714289*G0_1_0_12_1_1 - 0.229017857142862*G0_1_0_13_1_0 + 0.295312500000005*G0_1_0_14_1_0 - 0.108482142857145*G0_1_0_14_1_1 + 0.120535714285716*G0_1_0_15_1_0 - 0.174776785714288*G0_1_0_15_1_1 - 0.295312500000005*G0_1_0_16_1_0 - 0.174776785714289*G0_1_0_16_1_1 - 0.403794642857149*G0_1_0_17_1_0 - 0.108482142857146*G0_1_0_17_1_1 + 0.229017857142861*G0_1_0_18_1_0 + 0.108482142857146*G0_1_0_19_1_0 + 0.216964285714291*G0_1_0_19_1_1; + A[72] = 0.0; + A[32] = 0.0; + A[95] = 0.0; + A[51] = 0.0; + A[114] = 0.0; + A[78] = 0.0; + A[133] = 0.0; + A[148] = A[358]; + A[360] = 0.0; + A[336] = A[126]; + A[242] = 0.0; + A[263] = 0.0; + A[25] = A[235]; + A[42] = A[252]; + A[124] = A[86] - 0.325446428571431*G0_0_1_0_0_0 - 0.325446428571431*G0_0_1_0_0_1 + 0.325446428571432*G0_0_1_1_0_0 + 1.84419642857145*G0_0_1_2_0_1 - 1.84419642857145*G0_0_1_3_0_0 - 0.108482142857146*G0_0_1_3_0_1 + 2.71205357142862*G0_0_1_4_0_0 - 0.54241071428571*G0_0_1_4_0_1 + 1.84419642857145*G0_0_1_5_0_0 + 1.7357142857143*G0_0_1_5_0_1 - 2.71205357142862*G0_0_1_6_0_0 - 3.25446428571433*G0_0_1_6_0_1 + 0.108482142857143*G0_0_1_7_0_1 + 0.108482142857146*G0_0_1_8_0_1 + 0.433928571428567*G0_0_1_9_0_1 - 0.325446428571431*G0_0_1_10_1_0 - 0.325446428571431*G0_0_1_10_1_1 + 0.325446428571432*G0_0_1_11_1_0 + 1.84419642857145*G0_0_1_12_1_1 - 1.84419642857145*G0_0_1_13_1_0 - 0.108482142857146*G0_0_1_13_1_1 + 2.71205357142862*G0_0_1_14_1_0 - 0.54241071428571*G0_0_1_14_1_1 + 1.84419642857145*G0_0_1_15_1_0 + 1.7357142857143*G0_0_1_15_1_1 - 2.71205357142862*G0_0_1_16_1_0 - 3.25446428571433*G0_0_1_16_1_1 + 0.108482142857143*G0_0_1_17_1_1 + 0.108482142857146*G0_0_1_18_1_1 + 0.433928571428567*G0_0_1_19_1_1 + 0.325446428571431*G0_1_0_0_0_0 + 0.325446428571431*G0_1_0_0_0_1 - 0.325446428571432*G0_1_0_1_0_0 - 1.84419642857145*G0_1_0_2_0_1 + 1.84419642857145*G0_1_0_3_0_0 + 0.108482142857146*G0_1_0_3_0_1 - 2.71205357142862*G0_1_0_4_0_0 + 0.54241071428571*G0_1_0_4_0_1 - 1.84419642857145*G0_1_0_5_0_0 - 1.7357142857143*G0_1_0_5_0_1 + 2.71205357142862*G0_1_0_6_0_0 + 3.25446428571433*G0_1_0_6_0_1 - 0.108482142857143*G0_1_0_7_0_1 - 0.108482142857146*G0_1_0_8_0_1 - 0.433928571428567*G0_1_0_9_0_1 + 0.325446428571431*G0_1_0_10_1_0 + 0.325446428571431*G0_1_0_10_1_1 - 0.325446428571432*G0_1_0_11_1_0 - 1.84419642857145*G0_1_0_12_1_1 + 1.84419642857145*G0_1_0_13_1_0 + 0.108482142857146*G0_1_0_13_1_1 - 2.71205357142862*G0_1_0_14_1_0 + 0.54241071428571*G0_1_0_14_1_1 - 1.84419642857145*G0_1_0_15_1_0 - 1.7357142857143*G0_1_0_15_1_1 + 2.71205357142862*G0_1_0_16_1_0 + 3.25446428571433*G0_1_0_16_1_1 - 0.108482142857143*G0_1_0_17_1_1 - 0.108482142857146*G0_1_0_18_1_1 - 0.433928571428567*G0_1_0_19_1_1; + A[141] = A[351]; + A[117] = 0.0; + A[382] = 0.0; + A[163] = A[373]; + A[182] = A[392]; + A[283] = 0.0; + A[60] = A[270]; + A[334] = A[124]; + A[137] = 0.0; + A[391] = A[181]; + A[355] = A[145]; + A[372] = A[162]; + A[170] = 0.0; + A[191] = 0.0; + A[200] = 0.0; + A[176] = 0.0; + A[233] = A[23]; + A[290] = A[80]; + A[254] = A[44]; + A[303] = 0.0; + A[275] = A[65]; + A[12] = 0.0; + A[69] = A[279]; + A[29] = A[239]; + A[82] = A[292]; + A[54] = 0.0; + A[103] = A[313]; + A[325] = 0.0; + A[128] = -A[333] + 0.150669642857147*G0_0_0_0_0_0 + 0.150669642857147*G0_0_0_0_0_1 + 0.445982142857151*G0_0_0_1_0_0 + 1.3138392857143*G0_0_0_2_0_1 - 2.22388392857147*G0_0_0_3_0_0 - 0.108482142857145*G0_0_0_3_0_1 + 2.27812500000004*G0_0_0_4_0_0 - 0.705133928571437*G0_0_0_4_0_1 - 0.271205357142871*G0_0_0_5_0_0 - 0.325446428571444*G0_0_0_5_0_1 - 2.27812500000004*G0_0_0_6_0_0 - 1.13906250000001*G0_0_0_6_0_1 - 0.542410714285722*G0_0_0_7_0_0 - 0.488169642857148*G0_0_0_7_0_1 - 0.0542410714285762*G0_0_0_8_0_0 + 0.108482142857145*G0_0_0_8_0_1 + 2.49508928571434*G0_0_0_9_0_0 + 1.19330357142859*G0_0_0_9_0_1 + 0.150669642857147*G0_0_0_10_1_0 + 0.150669642857147*G0_0_0_10_1_1 + 0.445982142857151*G0_0_0_11_1_0 + 1.3138392857143*G0_0_0_12_1_1 - 2.22388392857147*G0_0_0_13_1_0 - 0.108482142857145*G0_0_0_13_1_1 + 2.27812500000004*G0_0_0_14_1_0 - 0.705133928571437*G0_0_0_14_1_1 - 0.271205357142871*G0_0_0_15_1_0 - 0.325446428571444*G0_0_0_15_1_1 - 2.27812500000004*G0_0_0_16_1_0 - 1.13906250000001*G0_0_0_16_1_1 - 0.542410714285722*G0_0_0_17_1_0 - 0.488169642857148*G0_0_0_17_1_1 - 0.0542410714285762*G0_0_0_18_1_0 + 0.108482142857145*G0_0_0_18_1_1 + 2.49508928571434*G0_0_0_19_1_0 + 1.19330357142859*G0_0_0_19_1_1 - 0.108482142857142*G0_1_0_0_0_0 - 0.108482142857142*G0_1_0_0_0_1 + 0.705133928571438*G0_1_0_2_0_1 - 0.162723214285726*G0_1_0_3_0_0 + 1.13906250000001*G0_1_0_4_0_0 + 0.271205357142849*G0_1_0_4_0_1 + 1.24754464285718*G0_1_0_5_0_0 + 0.922098214285733*G0_1_0_5_0_1 - 1.13906250000001*G0_1_0_6_0_0 - 1.51875000000003*G0_1_0_6_0_1 - 0.0542410714285712*G0_1_0_7_0_0 + 0.271205357142877*G0_1_0_7_0_1 + 0.162723214285713*G0_1_0_8_0_0 - 1.08482142857145*G0_1_0_9_0_0 - 0.542410714285726*G0_1_0_9_0_1 - 0.108482142857142*G0_1_0_10_1_0 - 0.108482142857142*G0_1_0_10_1_1 + 0.705133928571438*G0_1_0_12_1_1 - 0.162723214285726*G0_1_0_13_1_0 + 1.13906250000001*G0_1_0_14_1_0 + 0.271205357142849*G0_1_0_14_1_1 + 1.24754464285718*G0_1_0_15_1_0 + 0.922098214285733*G0_1_0_15_1_1 - 1.13906250000001*G0_1_0_16_1_0 - 1.51875000000003*G0_1_0_16_1_1 - 0.0542410714285712*G0_1_0_17_1_0 + 0.271205357142877*G0_1_0_17_1_1 + 0.162723214285713*G0_1_0_18_1_0 - 1.08482142857145*G0_1_0_19_1_0 - 0.542410714285726*G0_1_0_19_1_1; + A[396] = A[186]; + A[340] = 0.0; + A[153] = 0.0; + A[367] = 0.0; + A[192] = 0.0; + A[211] = A[1]; + A[222] = 0.0; + A[293] = A[83]; + A[245] = 0.0; + A[308] = 0.0; + A[268] = 0.0; + A[3] = A[213]; + A[74] = 0.0; + A[22] = A[232]; + A[89] = A[299]; + A[49] = A[259]; + A[112] = 0.0; + A[123] = A[333]; + A[150] = 0.0; + A[338] = A[128]; + A[359] = A[149]; + A[317] = A[107]; + A[261] = 0.0; + A[237] = A[27]; + A[40] = A[250]; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p3_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q3_tensor_finite_element_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q3_tensor_finite_element_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q3_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q3_tensor_dofmap_1(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q3_tensor_dofmap_1(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q3_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q3_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q4_excafe.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q4_excafe.h new file mode 100644 index 0000000..5ae96f7 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q4_excafe.h @@ -0,0 +1,2377 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 234 minutes and 38.29 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = var_1*w[0][3] + -var_3*w[0][13]; + const double var_5 = var_3*w[0][17] + -var_1*w[0][7]; + const double var_6 = var_5 + var_4; + const double var_7 = x[1][0] + var_2; + const double var_8 = x[1][1] + var_0; + const double var_9 = var_1*var_1*var_7*w[0][16] + -var_3*var_3*var_8*w[0][6]; + const double var_10 = 0.0476190476190476164042309*var_9; + const double var_11 = var_1*var_7 + -var_3*var_8; + const double var_12 = var_11; + const double var_13 = std::abs(var_12); + const double var_14 = var_11; + const double var_15 = var_3*var_3 + var_1*var_1; + const double var_16 = var_7*var_7 + var_8*var_8; + const double var_17 = var_1*w[0][0] + -var_3*w[0][10]; + const double var_18 = -var_3*var_3*var_8*w[0][0] + var_1*var_1*var_7*w[0][10] + var_15*var_17; + const double var_19 = -var_1*var_1*var_7*w[0][15] + var_3*var_3*var_8*w[0][5]; + const double var_20 = var_3*var_3*var_8*w[0][7] + -var_1*var_1*var_7*w[0][17]; + const double var_21 = -var_3*var_7*var_7*w[0][14] + var_1*var_8*var_8*w[0][4]; + const double var_22 = var_1*var_1*var_8*w[0][5] + -var_3*var_3*var_7*w[0][15]; + const double var_23 = var_3*var_7*var_7*w[0][17] + -var_1*var_8*var_8*w[0][7]; + const double var_24 = -var_1*var_1*var_8*w[0][8] + var_3*var_3*var_7*w[0][18]; + const double var_25 = var_1*var_7*var_7*w[0][9] + -var_3*var_8*var_8*w[0][19]; + const double var_26 = w[0][18] + -w[0][13]; + const double var_27 = w[0][3] + -w[0][8]; + const double var_28 = var_27*var_3*var_3*var_8 + var_1*var_1*var_26*var_7; + const double var_29 = -var_3*var_7*var_7*w[0][10] + var_1*var_8*var_8*w[0][0]; + const double var_30 = -var_1*var_1*var_8*w[0][0] + var_3*var_3*var_7*w[0][10]; + const double var_31 = var_1*var_1*var_8*w[0][3] + -var_3*var_3*var_7*w[0][13]; + const double var_32 = -var_3*var_8*var_8*w[0][18] + var_1*var_7*var_7*w[0][8]; + const double var_33 = var_3*var_8*var_8*w[0][13] + -var_1*var_7*var_7*w[0][3]; + const double var_34 = -var_3*var_7*var_7*w[0][18] + var_1*var_8*var_8*w[0][8]; + const double var_35 = var_3*var_7*var_7*w[0][13] + -var_1*var_8*var_8*w[0][3]; + const double var_36 = var_8*w[0][18] + -var_7*w[0][8]; + const double var_37 = var_8*w[0][19] + -var_7*w[0][9]; + const double var_38 = var_1*var_3*var_37; + const double var_39 = w[0][6] + -w[0][4]; + const double var_40 = -w[0][16] + w[0][14]; + const double var_41 = var_40*var_8 + var_39*var_7; + const double var_42 = var_1*var_3*var_41; + const double var_43 = var_7*w[0][7] + -var_8*w[0][17]; + const double var_44 = var_1*var_3*var_43; + const double var_45 = var_7*w[0][3] + -var_8*w[0][13]; + const double var_46 = var_1*var_3*var_45; + const double var_47 = var_7*w[0][12] + -var_8*w[0][2]; + const double var_48 = var_15*var_47; + const double var_49 = var_3*w[0][11] + -var_1*w[0][1]; + const double var_50 = var_15*var_49; + const double var_51 = var_3*w[0][13] + -var_1*w[0][3]; + const double var_52 = var_15*var_51; + const double var_53 = w[0][8] + -w[0][3]; + const double var_54 = w[0][13] + -w[0][18]; + const double var_55 = var_3*var_53 + var_1*var_54; + const double var_56 = var_55*var_7*var_8; + const double var_57 = var_27*var_8 + var_26*var_7; + const double var_58 = var_16*var_57; + const double var_59 = var_56 + var_58; + const double var_60 = var_7*w[0][14] + -var_8*w[0][4]; + const double var_61 = -var_7*w[0][17] + var_8*w[0][7]; + const double var_62 = var_61 + var_60; + const double var_63 = var_7*w[0][10] + -var_8*w[0][0]; + const double var_64 = var_1*var_7*var_7*w[0][0] + -var_3*var_8*var_8*w[0][10] + var_16*var_63; + const double var_65 = -var_7*w[0][12] + var_8*w[0][2]; + const double var_66 = var_16*var_65; + const double var_67 = var_66 + var_64; + const double var_68 = var_3*w[0][0]; + const double var_69 = var_8*w[0][10]; + const double var_70 = var_68 + var_69; + const double var_71 = var_1*w[0][10]; + const double var_72 = var_7*w[0][0]; + const double var_73 = var_71 + var_72; + const double var_74 = -var_1*var_7*var_70 + var_3*var_73*var_8; + const double var_75 = var_1*var_8*var_8*w[0][9] + -var_3*var_7*var_7*w[0][19]; + const double var_76 = var_3*var_3*var_7*w[0][19] + -var_1*var_1*var_8*w[0][9]; + const double var_77 = var_75 + var_76; + const double var_78 = 0.3809523809523809312338471*var_77 + 0.0867724867724867787721621*var_74; + const double var_79 = var_16*var_49; + const double var_80 = var_3*var_7 + var_1*var_8; + const double var_81 = var_1*w[0][1] + -var_3*w[0][11]; + const double var_82 = var_80*var_81; + const double var_83 = var_82 + var_79; + const double var_84 = 0.6666666666666666296592325*var_47*var_80; + const double var_85 = var_3*w[0][15] + -var_1*w[0][5]; + const double var_86 = 0.0520634920634920617121821*var_15*var_85; + const double var_87 = var_1*w[0][16] + -var_3*w[0][6]; + const double var_88 = var_7*var_8*var_87; + const double var_89 = var_1*w[0][15] + -var_3*w[0][5]; + const double var_90 = var_7*var_8*var_89; + const double var_91 = var_3*var_8*var_8*w[0][15] + -var_1*var_7*var_7*w[0][5]; + const double var_92 = w[0][16] + -w[0][14]; + const double var_93 = w[0][4] + -w[0][6]; + const double var_94 = var_3*var_8*var_8*var_92 + var_1*var_7*var_7*var_93; + const double var_95 = var_94 + var_91; + const double var_96 = var_90 + var_95 + var_88; + const double var_97 = -var_3*var_3*var_8*w[0][4] + var_1*var_1*var_7*w[0][14]; + const double var_98 = -var_1*var_1*var_8*w[0][4] + var_3*var_3*var_7*w[0][14]; + const double var_99 = 0.0571428571428571410728559*var_98; + const double var_100 = 0.0285714285714285705364279*var_97 + var_99; + const double var_101 = var_7*w[0][5] + -var_8*w[0][15]; + const double var_102 = var_1*var_101*var_3; + const double var_103 = -var_3*var_3*var_8*w[0][9] + var_1*var_1*var_7*w[0][19]; + const double var_104 = var_3*w[0][9] + -var_1*w[0][19]; + const double var_105 = var_104*var_7*var_8; + const double var_106 = 2.0000000000000000000000000*var_105 + var_103; + const double var_107 = var_102 + 2.0000000000000000000000000*var_106; + const double var_108 = var_3*var_7*var_7*w[0][15] + -var_1*var_8*var_8*w[0][5]; + const double var_109 = 0.0507936507936507936067372*var_108; + const double var_110 = var_3*var_92 + var_1*var_93; + const double var_111 = 0.0323809523809523783222097*var_110*var_15; + const double var_112 = -var_3*var_3*var_7*w[0][17] + var_1*var_1*var_8*w[0][7]; + const double var_113 = 0.4888888888888889283634853*var_112; + const double var_114 = var_3*w[0][4] + -var_1*w[0][14]; + const double var_115 = var_1*w[0][17] + -var_3*w[0][7]; + const double var_116 = 61.0000000000000000000000000*var_115 + 31.0000000000000000000000000*var_114; + const double var_117 = -var_1*var_7*var_7*w[0][7] + var_3*var_8*var_8*w[0][17]; + const double var_118 = var_1*w[0][8] + -var_3*w[0][18]; + const double var_119 = var_118*var_15; + const double var_120 = -var_3*var_3*var_7*w[0][16] + var_1*var_1*var_8*w[0][6]; + const double var_121 = -var_1*var_8*var_8*w[0][6] + var_3*var_7*var_7*w[0][16]; + const double var_122 = 0.0761904761904761973489997*var_120 + 0.1904761904761904656169236*var_121; + const double var_123 = var_122 + 0.6190476190476190687661529*var_119; + const double var_124 = var_117 + var_123; + const double var_125 = var_1*w[0][9] + -var_3*w[0][19]; + const double var_126 = 4.0000000000000000000000000*var_125*var_15; + const double var_127 = 0.0228571428571428571230317*var_126; + const double var_128 = 0.2666666666666666629659233*var_124 + var_100 + 0.7015873015873015372534383*var_1*var_3*var_36 + var_86 + 0.1117460317460317459348218*var_30 + 0.8634920634920635329478955*var_24 + 0.1650793650793650757524489*var_33 + 0.0613756613756613819687935*var_67 + 0.4000000000000000222044605*var_31 + 0.1238095238095238276310184*var_20 + 0.3650793650793650590991035*var_44 + 0.0082539682539682548284565*var_9 + 0.2920634920634920805859736*var_16*var_62 + 0.2222222222222222098864108*var_21 + 0.1619047619047619124277304*var_28 + 1.4222222222222222764997923*var_34 + 0.2380952380952380820211545*var_46 + 0.0285714285714285705364279*var_42 + 0.6285714285714285587403083*var_32 + 0.4232804232804232569264968*var_83 + 0.1904761904761904656169236*var_25 + 0.9587301587301587657563573*var_35 + 0.0846560846560846513852994*var_50 + var_113 + 0.7936507936507936067371816*var_59 + 0.2857142857142856984253854*var_38 + 0.0253968253968253968033686*var_96 + 0.0249735449735449741015536*var_18 + 0.0812698412698412697707795*var_22 + 0.1053968253968253915298092*var_15*var_5 + 0.0336507936507936533665486*var_19 + var_78 + var_109 + 0.6539682539682539763603586*var_23 + 0.0539682539682539708092435*var_84 + 0.0063492063492063492008421*var_116*var_7*var_8 + 0.0004232804232804232981262*var_48 + 0.0698412698412698429439871*var_52 + 1.3333333333333332593184650*var_127 + 0.1481481481481481399242739*var_29 + 0.0476190476190476164042309*var_107 + 0.6666666666666666296592325*var_111; + A[101] = 16.0000000000000000000000000*var_128*var_13/(var_14*var_14*var_14); + A[566] = A[101]; + const double var_129 = var_7*w[0][16] + -var_8*w[0][6]; + const double var_130 = var_129*var_16; + const double var_131 = var_3*var_7*var_7*w[0][18] + -var_1*var_8*var_8*w[0][8]; + const double var_132 = -var_3*var_3*var_7*w[0][18] + var_1*var_1*var_8*w[0][8]; + const double var_133 = 0.0761904761904761973489997*var_131 + 0.1904761904761904656169236*var_132; + const double var_134 = 0.6190476190476190687661529*var_130 + var_133; + const double var_135 = var_19 + var_134; + const double var_136 = var_27*var_3 + var_1*var_26; + const double var_137 = 3.3555555555555556246360993*var_136 + 3.6000000000000000888178420*var_104 + 2.8888888888888888395456433*var_115 + 0.5777777777777778345225101*var_87; + const double var_138 = -var_1*w[0][0] + var_3*w[0][10]; + const double var_139 = var_3*var_3*var_8*w[0][0] + -var_1*var_1*var_7*w[0][10] + var_138*var_15; + const double var_140 = -var_1*var_1*var_8*w[0][5] + var_3*var_3*var_7*w[0][15]; + const double var_141 = var_1*var_7*var_7*w[0][5] + -var_3*var_8*var_8*w[0][15]; + const double var_142 = -var_1*var_7*var_7*w[0][9] + var_3*var_8*var_8*w[0][19]; + const double var_143 = var_1*var_1*var_7*w[0][15] + -var_3*var_3*var_8*w[0][5]; + const double var_144 = -var_3*var_7*var_7*w[0][16] + var_1*var_8*var_8*w[0][6]; + const double var_145 = var_1*w[0][7] + -var_3*w[0][17]; + const double var_146 = -var_1*var_1*var_7*w[0][16] + var_3*var_3*var_8*w[0][6]; + const double var_147 = var_3*var_7*var_7*w[0][14] + -var_1*var_8*var_8*w[0][4]; + const double var_148 = var_3*var_3*var_8*w[0][4] + -var_1*var_1*var_7*w[0][14]; + const double var_149 = -var_1*var_1*var_8*w[0][6] + var_3*var_3*var_7*w[0][16]; + const double var_150 = var_1*w[0][14] + -var_3*w[0][4]; + const double var_151 = var_150*var_7*var_8; + const double var_152 = var_53*var_8 + var_54*var_7; + const double var_153 = var_152*var_16; + const double var_154 = -var_7*w[0][19] + var_8*w[0][9]; + const double var_155 = var_154*var_16; + const double var_156 = 2.0000000000000000000000000*var_35; + const double var_157 = var_33 + var_56 + var_156; + const double var_158 = var_3*var_40 + var_1*var_39; + const double var_159 = var_15*var_65; + const double var_160 = 0.4063492063492063488538975*var_15*var_158 + 0.0571428571428571410728559*var_159; + const double var_161 = var_8*var_92 + var_7*var_93; + const double var_162 = 541.0000000000000000000000000*var_43 + 209.0000000000000000000000000*var_161 + 191.0000000000000000000000000*var_36; + const double var_163 = var_3*w[0][6] + -var_1*w[0][16]; + const double var_164 = var_1*var_1*var_8*w[0][4] + -var_3*var_3*var_7*w[0][14]; + const double var_165 = 2.0000000000000000000000000*var_164; + const double var_166 = 0.6444444444444444863862032*var_163*var_7*var_8 + 0.2000000000000000111022302*var_165; + const double var_167 = var_8*w[0][5] + -var_7*w[0][15]; + const double var_168 = 1.2761904761904763194735324*var_49; + const double var_169 = var_7*w[0][17] + -var_8*w[0][7]; + const double var_170 = 2.6000000000000000888178420*var_169; + const double var_171 = var_168 + 7.7428571428571428825193834*var_129 + 14.7142857142857135244184974*var_167 + var_170; + const double var_172 = 0.1396825396825396858879742*var_15*var_81; + const double var_173 = 1.2550264550264551566272075*var_74; + const double var_174 = -var_1*w[0][17] + var_3*w[0][7]; + const double var_175 = var_174*var_7*var_8; + const double var_176 = 0.2952380952380952439106920*var_175; + const double var_177 = 0.1714285714285714301574615*var_105; + const double var_178 = var_1*var_39*var_7*var_7 + var_3*var_40*var_8*var_8; + const double var_179 = 2.0000000000000000000000000*var_1*var_3*var_37; + const double var_180 = var_178 + var_179; + const double var_181 = var_66 + var_30; + const double var_182 = 2.0000000000000000000000000*var_15*var_51; + const double var_183 = var_182 + var_28; + const double var_184 = var_8*w[0][4] + -var_7*w[0][14]; + const double var_185 = var_16*var_184; + const double var_186 = var_3*w[0][18] + -var_1*w[0][8]; + const double var_187 = 4.0000000000000000000000000*var_15*var_186; + const double var_188 = var_185 + var_187; + const double var_189 = -var_1*var_8*var_8*w[0][9] + var_3*var_7*var_7*w[0][19]; + const double var_190 = 0.0761904761904761973489997*var_189; + const double var_191 = 0.1587301587301587213474363*var_188 + 0.0031746031746031746004211*var_1*var_162*var_3 + var_190 + 1.1047619047619048338049197*var_76 + 0.4190476190476191131750738*var_155 + 0.2825396825396825351006669*var_20 + 0.5650793650793650702013338*var_15*var_85 + 2.9873015873015873467011261*var_117 + 3.2846560846560848290209833*var_29 + var_173 + 2.6920634920634922693238877*var_23 + var_177 + 2.0296296296296296723937758*var_64 + 0.0984126984126984100109681*var_183 + 0.3428571428571428603149229*var_31 + 0.4804232804232804743271856*var_181 + 0.7746031746031746267888707*var_139 + 0.5079365079365079083117962*var_149 + 0.7047619047619048116004592*var_24 + 0.1555555555555555580227178*var_146 + 0.2444444444444444641817427*var_46 + 0.3079365079365079527207172*var_148 + 1.2888888888888889727724063*var_34 + var_176 + 0.7174603174603174648993331*var_140 + 0.0476190476190476164042309*var_157 + 0.9873015873015873467011261*var_143 + 0.2698412698412698262906417*var_102 + 0.1439153439153439129061240*var_80*var_81 + 0.2476190476190476552620368*var_142 + var_160 + 0.5375661375661375807055720*var_47*var_80 + 0.2571428571428571174806166*var_180 + var_172 + 1.8222222222222221876819503*var_144 + 2.0000000000000000000000000*var_112 + 1.9873015873015873467011261*var_108 + 2.2825396825396824240783644*var_7*var_8*var_89 + 1.2698412698412697707794905*var_145*var_15 + 0.7238095238095239025710725*var_147 + 0.1904761904761904656169236*var_126 + 0.5904761904761904878213841*var_103 + 0.2952380952380952439106920*var_141 + 0.2222222222222222098864108*var_16*var_171 + 0.0507936507936507936067372*var_153 + 2.4285714285714283811046243*var_166 + 1.2412698412698413008570242*var_32 + 0.4666666666666666740681535*var_151; + A[6] = var_13*var_191/(var_14*var_14*var_14); + A[471] = A[6]; + const double var_192 = -var_7*w[0][10] + var_8*w[0][0]; + const double var_193 = var_3*var_8*var_8*w[0][10] + -var_1*var_7*var_7*w[0][0] + var_16*var_192; + const double var_194 = -var_3*var_3*var_7*w[0][10] + var_1*var_1*var_8*w[0][0]; + const double var_195 = -var_1*var_8*var_8*w[0][0] + var_3*var_7*var_7*w[0][10]; + const double var_196 = -var_3*var_7*var_7*w[0][15] + var_1*var_8*var_8*w[0][5]; + const double var_197 = -var_1*var_1*var_8*w[0][7] + var_3*var_3*var_7*w[0][17]; + const double var_198 = -var_3*var_7*var_7*w[0][17] + var_1*var_8*var_8*w[0][7]; + const double var_199 = -var_3*var_3*var_8*w[0][7] + var_1*var_1*var_7*w[0][17]; + const double var_200 = -var_1*var_1*var_7*w[0][19] + var_3*var_3*var_8*w[0][9]; + const double var_201 = var_1*var_7*var_7*w[0][7] + -var_3*var_8*var_8*w[0][17]; + const double var_202 = -var_3*var_3*var_7*w[0][19] + var_1*var_1*var_8*w[0][9]; + const double var_203 = var_3*var_8*var_8*w[0][18] + -var_1*var_7*var_7*w[0][8]; + const double var_204 = var_8*w[0][13] + -var_7*w[0][3]; + const double var_205 = var_1*var_204*var_3; + const double var_206 = var_7*w[0][15] + -var_8*w[0][5]; + const double var_207 = var_16*var_206; + const double var_208 = var_16*var_61; + const double var_209 = var_1*w[0][5] + -var_3*w[0][15]; + const double var_210 = var_15*var_209; + const double var_211 = var_3*w[0][5] + -var_1*w[0][15]; + const double var_212 = var_1*w[0][19] + -var_3*w[0][9]; + const double var_213 = 8.3622222222222220011644822*var_114 + 4.4400000000000003907985047*var_212 + 30.8333333333333321490954404*var_211 + 26.9800000000000004263256415*var_87 + 3.9222222222222224985443972*var_115 + 1.5311111111111110894000831*var_55; + const double var_214 = var_8*w[0][15] + -var_7*w[0][5]; + const double var_215 = var_8*w[0][17] + -var_7*w[0][7]; + const double var_216 = var_7*w[0][9] + -var_8*w[0][19]; + const double var_217 = var_7*w[0][8] + -var_8*w[0][18]; + const double var_218 = 1.9342857142857143859515645*var_217 + 3.5600000000000000532907052*var_216 + 7.9857142857142857650387668*var_215 + 3.5476190476190474498707772*var_214 + 7.3152380952380955392300166*var_41; + const double var_219 = var_3*w[0][19] + -var_1*w[0][9]; + const double var_220 = 3.9634920634920636217657375*var_47 + 9.4000000000000003552713679*var_110; + const double var_221 = 3.6952380952380954326486062*var_118 + 5.9047619047619042120800259*var_5 + 7.4857142857142857650387668*var_219 + 0.7746031746031746267888707*var_49 + 0.4142857142857142571656937*var_4 + var_220; + const double var_222 = -var_7*w[0][16] + var_8*w[0][6]; + const double var_223 = var_7*w[0][19] + -var_8*w[0][9]; + const double var_224 = 3.0740740740740739589398345*var_81 + 2.6666666666666665186369300*var_57; + const double var_225 = 4.4285714285714279370154145*var_223 + 13.5105820105820093601778353*var_47 + 6.4047619047619042120800259*var_60 + 38.4841269841269806306627288*var_222 + var_224; + const double var_226 = var_1*var_7*var_70 + -var_3*var_73*var_8; + const double var_227 = 1.0798941798941799063982216*var_226; + const double var_228 = 0.4714285714285714190552312*var_210 + 0.4114285714285714212756773*var_189 + var_227 + 0.5158730158730158166235924*var_140 + 1.6069841269841269593143807*var_120 + 2.3587301587301587879608178*var_195 + 2.3222222222222224097265553*var_196 + 0.3877777777777777767909129*var_146 + 0.5925396825396825883913721*var_94 + 1.0876190476190477074425189*var_202 + 2.2777777777777776790912867*var_207 + 1.7246031746031746934022522*var_201 + 0.0255555555555555570512727*var_33 + 0.1666666666666666574148081*var_1*var_218*var_3 + 2.5196825396825395237954126*var_121 + 0.0714285714285714246063463*var_213*var_7*var_8 + 0.1349206349206349131453209*var_35 + 0.4593650793650793651146103*var_131 + 0.1198412698412698457195447*var_141 + 1.1898412698412699217698218*var_21 + 0.0026984126984126986271983*var_28 + 0.1989417989417989474087989*var_18 + 1.4841269841269839613318027*var_197 + 0.1531746031746031855291790*var_199 + 0.0020634920634920637071141*var_205 + 0.0753968253968253926400322*var_19 + 0.4942857142857142727088160*var_200 + 0.0713227513227513293392335*var_49*var_80 + 0.0400000000000000008326673*var_16*var_225 + 1.4444444444444444197728217*var_198 + 0.3196825396825396792266361*var_132 + 0.0666666666666666657414808*var_15*var_221 + 1.2788359788359788815625961*var_193 + 1.5603174603174603252142560*var_98 + 0.8809523809523809312338471*var_194 + 0.3411111111111110871796370*var_97 + 0.5687301587301587524336810*var_203 + 0.0006349206349206349200842*var_31 + 0.4333333333333333481363070*var_208 + 0.8046560846560847357622492*var_65*var_80 + 0.0942857142857142921377189*var_142; + const double var_229 = var_114*var_7*var_8; + const double var_230 = var_115*var_7*var_8; + const double var_231 = var_163*var_7*var_8; + const double var_232 = var_16*var_60; + const double var_233 = var_15*var_5; + const double var_234 = var_16*var_167; + const double var_235 = var_16*var_169; + const double var_236 = var_47*var_80; + const double var_237 = 15.7333333333333325043668083*var_45 + 2.2666666666666666074547720*var_101 + 4.0666666666666664298190881*var_43 + 18.0000000000000000000000000*var_37 + 12.7333333333333325043668083*var_36; + const double var_238 = 0.3333333333333333148296163*var_49 + var_57; + const double var_239 = 0.9523809523809523280846179*var_16*var_238; + const double var_240 = var_15*var_158; + const double var_241 = 0.0038095238095238095205053*var_240; + const double var_242 = 0.0025396825396825396803369*var_48 + var_241; + const double var_243 = 0.0190476190476190493372499*var_164 + 0.0139682539682539682418527*var_64; + const double var_244 = 0.7047619047619048116004592*var_112 + 0.8000000000000000444089210*var_75; + const double var_245 = 4.0000000000000000000000000*var_108 + var_121; + const double var_246 = 0.0736507936507936472603220*var_30; + const double var_247 = var_155 + var_103; + const double var_248 = 0.0952380952380952328084618*var_74; + const double var_249 = var_118 + var_85; + const double var_250 = 7.4761904761904753868861917*var_49 + 14.0000000000000000000000000*var_249 + 15.1428571428571423496123316*var_51; + const double var_251 = 0.0476190476190476164042309*var_32; + const double var_252 = var_156 + 0.0514285714285714276594597*var_94 + 0.0266666666666666683782605*var_15*var_250 + 0.1041269841269841234243643*var_16*var_65 + 0.1523809523809523946979994*var_233 + 0.0571428571428571410728559*var_1*var_237*var_3 + var_242 + 1.6000000000000000888178420*var_76 + 0.0609523809523809523280846*var_42 + 0.1980952380952381020051689*var_129*var_16 + 0.0990476190476190510025845*var_148 + 1.5047619047619049670316826*var_34 + 0.0304761904761904761640423*var_245 + var_244 + 0.1828571428571428569842539*var_22 + 0.3238095238095238248554608*var_235 + 0.0533333333333333367565210*var_19 + 0.5828571428571428514331387*var_25 + 0.1942857142857142838110462*var_126 + 0.0342857142857142874192711*var_236 + 0.1219047619047619046561692*var_234 + 0.0628571428571428614251460*var_229 + 0.0114285714285714285615159*var_149 + 1.2380952380952381375323057*var_24 + 0.5428571428571428159060019*var_33 + 0.0723809523809523791548770*var_9 + 0.4723809523809524013593375*var_20 + 0.2419047619047619002152771*var_201 + 1.4571428571428570730716956*var_56 + 0.5104761904761905277894130*var_28 + 0.5904761904761904878213841*var_82 + 0.1142857142857142821457117*var_21 + 0.0209523809523809514954173*var_231 + 0.0819047619047619107623959*var_7*var_8*var_89 + 0.0215873015873015890175868*var_139 + 0.2171428571428571374646310*var_105 + 1.4095238095238096232009184*var_31 + 0.5714285714285713968507707*var_247 + 0.1231746031746031727616142*var_29 + var_248 + 0.2800000000000000266453526*var_230 + 0.2476190476190476552620368*var_232 + 0.0400000000000000008326673*var_91 + var_239 + 2.0000000000000000000000000*var_243 + 0.0380952380952380986744998*var_23 + var_246 + var_251; + A[313] = 8.0000000000000000000000000*var_13*var_252/(var_14*var_14*var_14); + A[400] = A[313]; + const double var_253 = var_16*var_81; + const double var_254 = 0.0342857142857142874192711*var_58 + 0.0038095238095238095205053*var_253; + const double var_255 = 0.9555555555555556024316388*var_163*var_7*var_8; + const double var_256 = 0.0165079365079365096569131*var_24 + 0.0038095238095238095205053*var_105; + const double var_257 = var_15*var_85; + const double var_258 = 0.0742857142857142882519383*var_257; + const double var_259 = 0.0457142857142857142460635*var_25 + var_258; + const double var_260 = 0.0057142857142857142807579*var_178; + const double var_261 = 0.0952380952380952328084618*var_164 + var_260; + const double var_262 = 0.2666666666666666629659233*var_117 + var_38; + const double var_263 = 0.0234920634920634911757542*var_47*var_80; + const double var_264 = 0.0209523809523809514954173*var_15*var_47; + const double var_265 = 1.9333333333333333481363070*var_1*var_161*var_3; + const double var_266 = 0.0275132275132275137818905*var_74; + const double var_267 = var_1*var_214*var_3; + const double var_268 = 0.0069841269841269841209264*var_267; + const double var_269 = 0.0209523809523809514954173*var_240; + const double var_270 = var_56 + var_64; + const double var_271 = var_1*var_217*var_3; + const double var_272 = var_271 + var_149; + const double var_273 = var_155 + var_235; + const double var_274 = var_148 + var_28; + const double var_275 = var_244 + var_33; + const double var_276 = 0.1111111111111111049432054*var_264 + 0.0692063492063492019523707*var_140 + 0.0533333333333333367565210*var_175 + 0.0228571428571428571230317*var_198 + 0.0285714285714285705364279*var_255 + 0.0088888888888888888811790*var_187 + 0.0323809523809523783222097*var_66 + 0.0260317460317460308560911*var_108 + 0.0120634920634920643489618*var_272 + 0.1161904761904761912427730*var_129*var_16 + 0.0361904761904761895774385*var_126 + 0.0609523809523809523280846*var_150*var_7*var_8 + 0.1600000000000000033306691*var_273 + 0.1695238095238095210604001*var_16*var_167 + var_269 + 0.0063492063492063492008421*var_146 + var_254 + var_259 + 0.0463492063492063482987859*var_20 + 0.0006349206349206349200842*var_44 + 0.0266666666666666683782605*var_34 + 0.0035978835978835981695978*var_15*var_81 + 0.0148148148148148153802062*var_82 + 0.0311111111111111102167648*var_144 + 0.2057142857142857106378386*var_76 + 0.1523809523809523946979994*var_35 + 0.1212698412698412636645529*var_1*var_3*var_45 + 0.0209523809523809514954173*var_141 + 0.0914285714285714284921269*var_103 + 0.0622222222222222204335296*var_143 + var_266 + 0.0647619047619047566444195*var_147 + 0.0901587301587301603866820*var_145*var_15 + 0.3333333333333333148296163*var_263 + 2.0000000000000000000000000*var_256 + var_268 + 0.0704761904761904700578157*var_52 + 0.0666666666666666657414808*var_275 + 0.1663492063492063577356816*var_31 + 0.1132275132275132323300681*var_29 + 0.0590476190476190501699172*var_203 + 0.1142857142857142821457117*var_262 + 0.0306878306878306909843968*var_194 + 0.6666666666666666296592325*var_261 + 0.0095238095238095246686250*var_265 + 0.0469841269841269823515084*var_90 + 0.0450793650793650801933410*var_274 + 0.0582010582010581978273933*var_139 + 0.0857142857142857150787307*var_270; + const double var_277 = 0.1269841269841269770779490*var_110 + 0.2169312169312169191748296*var_65; + const double var_278 = 1.5396825396825395415589810*var_209 + 3.0317460317460316332471848*var_4 + 2.3492063492063492979866624*var_145 + 4.5714285714285711748061658*var_219 + 3.5555555555555553581825734*var_186 + 1.5767195767195767430735032*var_81 + var_277; + const double var_279 = var_25 + var_103; + const double var_280 = -var_1*var_1*var_8*w[0][3] + var_3*var_3*var_7*w[0][13]; + const double var_281 = -var_3*var_7*var_7*w[0][13] + var_1*var_8*var_8*w[0][3]; + const double var_282 = -var_3*var_8*var_8*w[0][13] + var_1*var_7*var_7*w[0][3]; + const double var_283 = var_1*var_1*var_54*var_7 + var_3*var_3*var_53*var_8; + const double var_284 = var_1*var_161*var_3; + const double var_285 = var_1*var_216*var_3; + const double var_286 = var_16*var_47; + const double var_287 = var_15*var_81; + const double var_288 = var_15*var_219; + const double var_289 = 25.1111111111111107163651468*var_174 + 24.0000000000000000000000000*var_212 + 30.2222222222222214327302936*var_136 + 2.3777777777777777679091287*var_163 + 3.8444444444444445529995846*var_211; + const double var_290 = var_130 + var_207; + const double var_291 = 71.8888888888888857309211744*var_217 + 49.7111111111111156901642971*var_215 + 8.2000000000000010658141036*var_214; + const double var_292 = var_110*var_15; + const double var_293 = 0.0076190476190476190410106*var_292 + 0.0050793650793650793606737*var_159; + const double var_294 = 1.6000000000000000888178420*var_202 + 0.0444444444444444461406185*var_178; + const double var_295 = 0.3483597883597883693163055*var_226; + const double var_296 = 0.8000000000000000444089210*var_253; + const double var_297 = var_143 + var_187; + const double var_298 = 67.0000000000000000000000000*var_209 + 83.0000000000000000000000000*var_4 + 118.0000000000000000000000000*var_145; + const double var_299 = 47.3333333333333285963817616*var_144 + 101.0000000000000000000000000*var_140 + var_120 + 1.8888888888888888395456433*var_47*var_80 + 118.1111111111111000582241104*var_194 + 149.7777777777777714618423488*var_195 + var_15*var_298; + const double var_300 = 0.2539682539682539541558981*var_287 + 0.0571428571428571410728559*var_289*var_7*var_8 + 0.4571428571428571285828468*var_142 + 0.9485714285714286209127977*var_285 + 0.0285714285714285705364279*var_1*var_291*var_3 + 0.1079365079365079416184869*var_147 + 0.5714285714285713968507707*var_288 + 0.0400000000000000008326673*var_284 + 0.0634920634920634885389745*var_151 + 0.1015873015873015872134744*var_139 + 0.9142857142857142571656937*var_235 + 0.6095238095238095787919974*var_154*var_16 + 0.9206349206349205838151306*var_201 + 0.0971428571428571419055231*var_97 + 1.4984126984126984183376408*var_203 + 1.2000000000000001776356839*var_280 + 0.0438095238095238120878960*var_146 + 1.8285714285714285143313873*var_189 + 1.9746031746031746934022522*var_197 + 1.3904761904761906432526075*var_152*var_16 + 0.7142857142857143015746146*var_205 + 0.5542857142857142704883699*var_199 + var_293 + 0.0825396825396825378762244*var_141 + 0.3047619047619047893959987*var_185 + 3.2253968253968254842334318*var_131 + 0.0888888888888888922812370*var_290 + 2.5396825396825395415589810*var_132 + 2.1015873015873016704802012*var_281 + 0.2222222222222222098864108*var_193 + 2.3555555555555556246360993*var_198 + var_99 + 0.0444444444444444461406185*var_286 + 0.9820105820105821115006961*var_49*var_80 + 0.6514285714285714679050443*var_200 + 0.1504761904761904856009380*var_297 + 0.4857142857142857095276156*var_283 + 0.3022222222222222254295332*var_196 + 0.3746031746031746045844102*var_282 + var_294 + var_295 + var_296 + 0.0038095238095238095205053*var_299; + A[100] = 4.0000000000000000000000000*var_13*var_300/(var_14*var_14*var_14); + const double var_301 = var_49*var_80; + const double var_302 = 0.0245502645502645513997386*var_15*var_65 + 0.0838095238095238059816694*var_15*var_158; + const double var_303 = 43.0000000000000000000000000*var_36 + 181.0000000000000000000000000*var_161 + 221.0000000000000000000000000*var_43 + 389.0000000000000000000000000*var_101 + 577.0000000000000000000000000*var_45; + const double var_304 = 3.6666666666666665186369300*var_65*var_80; + const double var_305 = 0.0190476190476190493372499*var_58 + 0.0380952380952380986744998*var_253; + const double var_306 = 0.2603174603174603363164863*var_164; + const double var_307 = 29.0000000000000000000000000*var_51 + 10.6666666666666660745477202*var_5 + 62.0000000000000000000000000*var_125 + 4.2222222222222223209087133*var_81; + const double var_308 = var_185 + var_33; + const double var_309 = 0.0613756613756613819687935*var_74; + const double var_310 = 0.1295238095238095132888390*var_91; + const double var_311 = 0.0082539682539682548284565*var_28; + const double var_312 = 0.0050793650793650793606737*var_119; + const double var_313 = 0.0457142857142857142460635*var_130; + const double var_314 = 4.0000000000000000000000000*var_16*var_223; + const double var_315 = 0.0457142857142857142460635*var_314 + 0.0965079365079365147916945*var_7*var_8*var_89 + 0.0634920634920634885389745*var_231; + const double var_316 = 0.2038095238095238015407773*var_150*var_7*var_8; + const double var_317 = var_315 + var_316; + const double var_318 = var_286 + var_56; + const double var_319 = 0.1066666666666666735130420*var_208 + 0.1574603174603174671197792*var_144 + var_313 + 0.3339682539682539696990204*var_22 + 0.0194708994708994720390649*var_18 + 0.8380952380952382263501477*var_76 + 0.1942857142857142838110462*var_230 + 0.1428571428571428492126927*var_156 + 0.1257142857142857228502919*var_257 + 0.9904761904761906210481470*var_75 + 0.3885714285714285676220925*var_25 + var_310 + 0.0006349206349206349200842*var_1*var_3*var_303 + 0.3225396825396825151166524*var_108 + 0.0038095238095238095205053*var_15*var_307 + 0.2196825396825396736755209*var_112 + 0.0793650793650793606737182*var_20 + 0.0304761904761904761640423*var_178 + 0.0920634920634920694837433*var_9 + 0.2857142857142856984253854*var_23 + var_312 + 0.0419047619047619029908347*var_64 + 0.3746031746031746045844102*var_31 + var_311 + 0.1032804232804232780207343*var_29 + 0.0914285714285714284921269*var_117 + 0.4380952380952381486345359*var_147 + 0.6019047619047619424037521*var_104*var_7*var_8 + var_306 + var_305 + var_302 + 0.6133333333333333969861201*var_38 + 0.0012698412698412698401684*var_304 + 0.0869841269841269831841757*var_19 + 0.1142857142857142821457117*var_234 + var_309 + 0.0355555555555555555247160*var_24 + 0.2069841269841269926210714*var_149 + 0.0808465608465608470689645*var_30 + 0.2247619047619047738528764*var_103 + 0.0516402116402116390103672*var_301 + 2.0000000000000000000000000*var_317 + 0.0114285714285714285615159*var_32 + 0.0380952380952380986744998*var_34 + 0.1453968253968253854235826*var_148 + 0.2590476190476190265776779*var_308 + 0.0266666666666666683782605*var_318; + A[129] = 4.0000000000000000000000000*var_13*var_319/(var_14*var_14*var_14); + A[274] = A[129]; + const double var_320 = 0.0245502645502645513997386*var_16*var_49 + 0.0838095238095238059816694*var_16*var_57; + const double var_321 = var_145*var_15; + const double var_322 = var_321 + var_119; + const double var_323 = var_139 + var_50 + var_322; + const double var_324 = var_205 + var_229; + const double var_325 = var_200 + var_142; + const double var_326 = var_199 + var_141; + const double var_327 = 0.0031746031746031746004211*var_326 + 0.0044444444444444444405895*var_324 + 0.0114285714285714285615159*var_325 + 0.0194708994708994720390649*var_74; + const double var_328 = 2.0000000000000000000000000*var_104*var_7*var_8; + const double var_329 = 89.0000000000000000000000000*var_36; + const double var_330 = 12.3333333333333321490954404*var_41 + 3.6666666666666665186369300*var_214 + var_329 + 71.0000000000000000000000000*var_43; + const double var_331 = 0.1523809523809523946979994*var_129*var_16; + const double var_332 = 3.0000000000000000000000000*var_211*var_7*var_8; + const double var_333 = 0.0224338624338624344212167*var_65*var_80; + const double var_334 = 0.0552380952380952389146884*var_16*var_169; + const double var_335 = 0.0006349206349206349200842*var_283; + const double var_336 = 0.0228571428571428571230317*var_202; + const double var_337 = 0.0431746031746031780351736*var_21; + const double var_338 = var_209 + var_4; + const double var_339 = 2.0000000000000000000000000*var_219 + var_338; + const double var_340 = 0.0114285714285714285615159*var_15*var_339; + const double var_341 = var_1*var_1*var_39*var_8 + var_3*var_3*var_40*var_7; + const double var_342 = 0.0317460317460317442694873*var_341; + const double var_343 = 83.0000000000000000000000000*var_55 + 229.0000000000000000000000000*var_115; + const double var_344 = var_280 + var_234; + const double var_345 = var_3*var_3*var_39*var_8 + var_1*var_1*var_40*var_7; + const double var_346 = var_345 + var_282; + const double var_347 = 0.1295238095238095132888390*var_75; + const double var_348 = 0.0082539682539682548284565*var_346 + var_336 + 0.0169312169312169323587280*var_30 + 0.1688888888888888939465716*var_24 + 0.0590476190476190501699172*var_88 + 0.0431746031746031780351736*var_23 + 0.0977777777777777828971395*var_121 + 0.0177777777777777777623580*var_140 + 0.1257142857142857228502919*var_16*var_60 + 0.0006349206349206349200842*var_343*var_7*var_8 + 0.0160846560846560869550981*var_193 + var_333 + var_340 + 2.0000000000000000000000000*var_334 + 0.0387301587301587327272223*var_94 + 0.2361904761904762006796688*var_154*var_16 + var_335 + 0.0057142857142857142807579*var_332 + 0.0615873015873015863808071*var_203 + 0.0033862433862433863850094*var_29 + 0.1320634920634920772553045*var_112 + 0.0704761904761904700578157*var_328 + 0.0088888888888888888811790*var_131 + 0.0025396825396825396803369*var_323 + 0.2666666666666666629659233*var_331 + 0.0537566137566137594583360*var_80*var_81 + var_347 + 0.0114285714285714285615159*var_285 + var_327 + 0.0107936507936507945087934*var_143 + 0.0019047619047619047602526*var_1*var_3*var_330 + var_320 + var_337 + 0.0203174603174603174426949*var_196 + 0.0050793650793650793606737*var_344 + 0.0222222222222222230703093*var_156 + 0.0194708994708994720390649*var_66 + 0.1022222222222222282050907*var_201 + var_342; + A[250] = 4.0000000000000000000000000*var_13*var_348/(var_14*var_14*var_14); + const double var_349 = var_292 + var_42; + const double var_350 = 23.0000000000000000000000000*var_45 + 16.0000000000000000000000000*var_101; + const double var_351 = 13.0000000000000000000000000*var_23 + var_1*var_3*var_350 + var_349; + const double var_352 = 0.4000000000000000222044605*var_212*var_7*var_8; + const double var_353 = 0.0215873015873015890175868*var_16*var_222 + 0.0044444444444444444405895*var_24; + const double var_354 = 1.5333333333333332149095440*var_169 + 1.2592592592592593003786305*var_47 + 1.8000000000000000444089210*var_60 + 2.5777777777777779455448126*var_206; + const double var_355 = 0.0960846560846560920898796*var_226; + const double var_356 = 0.1441269841269841311959254*var_141; + const double var_357 = 0.0063492063492063492008421*var_283; + const double var_358 = 0.0069841269841269841209264*var_175; + const double var_359 = 0.8000000000000000444089210*var_48; + const double var_360 = 43.0000000000000000000000000*var_214; + const double var_361 = 31.0000000000000000000000000*var_45 + var_360; + const double var_362 = 107.0000000000000000000000000*var_87 + 2.8666666666666666962726140*var_136; + const double var_363 = var_1*var_3*var_36; + const double var_364 = var_44 + var_363; + const double var_365 = var_143 + var_21; + const double var_366 = var_20 + var_139; + const double var_367 = var_15*var_186; + const double var_368 = var_233 + var_367; + const double var_369 = 0.0761904761904761973489997*var_126 + 0.0444444444444444461406185*var_368; + const double var_370 = 0.1142857142857142821457117*var_189; + const double var_371 = var_369 + var_370; + const double var_372 = 2.0000000000000000000000000*var_15*var_209 + var_285; + const double var_373 = 7.6666666666666660745477202*var_121 + var_372 + var_103; + const double var_374 = 0.0571428571428571410728559*var_16*var_354 + 0.0126984126984126984016843*var_1*var_3*var_361 + 0.3873015873015873133944353*var_31 + 0.1405291005291005312916042*var_194 + 0.1523809523809523946979994*var_373 + 0.0196825396825396833899724*var_203 + var_356 + 0.6412698412698413230614847*var_196 + var_355 + 1.3904761904761906432526075*var_292 + 0.1079365079365079416184869*var_148 + 1.0158730158730158166235924*var_146 + 0.4571428571428571285828468*var_182 + var_357 + 0.0907936507936507875005105*var_201 + 2.0698412698412700372330164*var_120 + 0.2952380952380952439106920*var_352 + 0.8063492063492063710583579*var_140 + 0.0095238095238095246686250*var_362*var_7*var_8 + 0.0465608465608465665885873*var_193 + 0.9460317460317460014351809*var_98 + 0.0469841269841269823515084*var_131 + 0.0960846560846560920898796*var_301 + 0.6179894179894179773171459*var_65*var_80 + 1.0539682539682539985648191*var_42 + var_359 + 0.1426455026455026586784669*var_195 + 8.0000000000000000000000000*var_353 + 0.1111111111111111049432054*var_229 + 0.1104761904761904778293768*var_142 + 2.0000000000000000000000000*var_371 + 0.0031746031746031746004211*var_156 + var_358 + var_320 + 0.0419047619047619029908347*var_364 + 0.1657142857142857028662775*var_332 + 0.0977777777777777828971395*var_198 + 0.0444444444444444461406185*var_366 + 0.2222222222222222098864108*var_287 + 0.2603174603174603363164863*var_365 + 0.1904761904761904656169236*var_155 + 0.1492063492063492036177053*var_94 + 0.0863492063492063560703471*var_112 + 0.0336507936507936533665486*var_33; + A[128] = 4.0000000000000000000000000*var_13*var_374/(var_14*var_14*var_14); + A[244] = A[128]; + const double var_375 = var_201 + var_32; + const double var_376 = 43.0000000000000000000000000*var_174; + const double var_377 = 273.6666666666666287710540928*var_163 + 446.3333333333333143855270464*var_89 + var_376; + const double var_378 = var_15*var_4; + const double var_379 = 0.0742857142857142882519383*var_378; + A[817] = 0.0000000000000000000000000; + const double var_380 = 0.0571428571428571410728559*var_79 + 0.4063492063492063488538975*var_16*var_57; + const double var_381 = var_211*var_7*var_8; + const double var_382 = var_231 + var_381; + const double var_383 = var_287 + var_139; + const double var_384 = var_197 + var_24; + const double var_385 = 0.0952380952380952328084618*var_285 + 0.0126984126984126984016843*var_28; + const double var_386 = var_1*var_215*var_3; + const double var_387 = var_363 + var_386; + const double var_388 = var_199 + var_387; + const double var_389 = var_209 + var_51; + const double var_390 = 9.2000000000000010658141036*var_389 + 13.3333333333333321490954404*var_47 + 25.0000000000000000000000000*var_110; + const double var_391 = 0.0126984126984126984016843*var_388 + 0.0253968253968253968033686*var_384 + 0.0101587301587301587213474*var_34 + 0.0952380952380952328084618*var_200 + 0.1904761904761904656169236*var_202 + 0.0406349206349206348853897*var_198 + 0.1333333333333333314829616*var_143 + 0.0306878306878306909843968*var_383 + var_385 + 0.3142857142857142793701541*var_146 + 0.0825396825396825378762244*var_97 + 0.0158730158730158721347436*var_15*var_390; + const double var_392 = 0.4000000000000000222044605*var_1*var_216*var_3; + const double var_393 = 104.0000000000000000000000000*var_212 + 92.3333333333333285963817616*var_87 + 74.3333333333333285963817616*var_114 + 29.6666666666666642981908808*var_174; + const double var_394 = 0.0666666666666666657414808*var_48 + 0.1428571428571428492126927*var_292; + const double var_395 = 0.6666666666666666296592325*var_394; + const double var_396 = var_189 + var_202; + const double var_397 = 0.3276190476190476430495835*var_396 + 0.0131216931216931228382228*var_226; + const double var_398 = 0.0095238095238095246686250*var_153 + 0.0052910052910052907115812*var_79; + const double var_399 = var_200 + var_288; + const double var_400 = var_155 + var_142; + const double var_401 = 0.0019047619047619047602526*var_119 + 0.0723809523809523791548770*var_143; + const double var_402 = 0.0645502645502645522324059*var_80*var_81; + const double var_403 = 0.0463492063492063482987859*var_198; + const double var_404 = 0.1968253968253968200219362*var_196; + const double var_405 = 0.0742857142857142882519383*var_232; + const double var_406 = var_50 + var_131; + const double var_407 = var_304 + var_207; + const double var_408 = 0.3333333333333333148296163*var_194; + const double var_409 = var_408 + var_381; + const double var_410 = var_136*var_7*var_8; + const double var_411 = 0.3333333333333333148296163*var_195; + const double var_412 = var_411 + var_410; + const double var_413 = 0.1098412698412698368377605*var_409 + var_395 + 0.2488888888888888817341183*var_121 + 0.0869841269841269831841757*var_141 + 0.0158730158730158721347436*var_197 + var_405 + 0.0730158730158730201464934*var_94 + 0.0273015873015873024309830*var_186*var_80 + 0.0266666666666666683782605*var_378 + 0.0742857142857142882519383*var_97 + 0.1295238095238095132888390*var_400 + 0.0264550264550264535579061*var_16*var_47 + 0.1733333333333333392545228*var_42 + 0.1676190476190476119633388*var_1*var_214*var_3 + 0.0584126984126984161171947*var_16*var_222 + 0.0103703703703703700722549*var_64 + var_401 + 0.0171428571428571437096355*var_199 + 0.0685714285714285748385421*var_51*var_80 + 0.0215873015873015890175868*var_407 + 0.0234920634920634911757542*var_139 + 0.0082539682539682548284565*var_412 + 0.5904761904761904878213841*var_392 + var_398 + 0.2666666666666666629659233*var_120 + 0.0031746031746031746004211*var_406 + var_403 + 0.0012698412698412698401684*var_44 + 0.0914285714285714284921269*var_399 + 0.2400000000000000188737914*var_140 + 0.0647619047619047566444195*var_210 + 0.0247619047619047627506461*var_321 + var_404 + 0.0019047619047619047602526*var_393*var_7*var_8 + 0.0933333333333333375891883*var_146 + 0.0425396825396825370435572*var_282 + var_397 + var_334 + 0.0507936507936507936067372*var_281 + 0.2000000000000000111022302*var_402 + 0.2146031746031746012537411*var_21 + 0.2476190476190476552620368*var_98 + 0.0101587301587301587213474*var_117 + 0.1066666666666666735130420*var_251; + A[194] = 32.0000000000000000000000000*var_13*var_413/(var_14*var_14*var_14); + A[108] = 0.0000000000000000000000000; + const double var_414 = 15.8000000000000007105427358*var_43 + 103.0000000000000000000000000*var_161 + 9.2000000000000010658141036*var_217; + A[514] = 0.0000000000000000000000000; + const double var_415 = var_169 + var_184; + const double var_416 = var_411 + var_21; + const double var_417 = 0.1917460317460317476001563*var_226; + const double var_418 = var_5 + var_186; + const double var_419 = var_125 + 0.1904761904761904656169236*var_418; + const double var_420 = 1.3333333333333332593184650*var_419; + const double var_421 = 13.5238095238095237249353886*var_110 + 5.9285714285714279370154145*var_51 + 4.5952380952380948997415544*var_209 + 7.3888888888888883954564335*var_47 + var_420; + A[865] = A[313]; + const double var_422 = -var_8*w[0][10] + var_72; + const double var_423 = var_63*var_80 + var_1*var_3*var_422; + const double var_424 = var_26*var_3*var_3*var_7 + var_1*var_1*var_27*var_8; + const double var_425 = var_27*var_7 + var_26*var_8; + const double var_426 = var_169 + var_60; + const double var_427 = 2.0000000000000000000000000*var_154 + var_426; + const double var_428 = 0.1333333333333333314829616*var_427*var_80; + const double var_429 = 0.4603174603174602919075653*var_28 + 0.1481481481481481399242739*var_287 + 0.3079365079365079527207172*var_1*var_3*var_425 + var_428 + 0.7682539682539683001394337*var_424; + const double var_430 = 0.1523809523809523946979994*var_118*var_15; + const double var_431 = 25.8888888888888857309211744*var_41 + 18.0000000000000000000000000*var_216 + 7.8888888888888883954564335*var_43; + const double var_432 = 1.1957671957671958118396560*var_15*var_47 + 2.1587301587301586103251338*var_292; + const double var_433 = 1.4476190476190478051421451*var_125*var_15; + const double var_434 = 0.1142857142857142821457117*var_202; + const double var_435 = 23.0000000000000000000000000*var_167 + 38.2000000000000028421709430*var_129 + 17.8000000000000007105427358*var_65; + const double var_436 = 0.2190476190476190743172680*var_143 + 0.6031746031746031411202580*var_98 + var_113 + 0.0285714285714285705364279*var_1*var_3*var_431 + var_429 + 0.2634920634920634996412048*var_20 + var_430 + 0.3047619047619047893959987*var_15*var_5 + 2.1587301587301586103251338*var_120 + 1.0412698412698413452659452*var_140 + var_434 + 0.0783068783068783108580746*var_194 + 1.7079365079365078639028752*var_15*var_51 + 0.4000000000000000222044605*var_103 + 0.0825396825396825378762244*var_423 + 1.4190476190476191131750738*var_146 + 0.1365079365079364948076801*var_148 + 0.2603174603174603363164863*var_210 + 0.8222222222222222987042528*var_267 + 0.0317460317460317442694873*var_435*var_80 + var_433 + var_432 + 0.0042328042328042330896820*var_18; + A[38] = 0.2000000000000000111022302*var_13*var_436/(var_14*var_14*var_14); + A[29] = 0.0000000000000000000000000; + const double var_437 = -var_3*w[0][0] + var_71; + const double var_438 = var_17*var_80 + var_437*var_7*var_8; + const double var_439 = var_212*var_7*var_8; + const double var_440 = var_51 + 2.0000000000000000000000000*var_125 + var_85; + const double var_441 = 11.0000000000000000000000000*var_3*var_7 + 106.0000000000000000000000000*var_1*var_8; + const double var_442 = 11.0000000000000000000000000*var_1*var_8 + 106.0000000000000000000000000*var_3*var_7; + const double var_443 = var_442*var_7*var_92 + var_441*var_8*var_93; + const double var_444 = 0.3015873015873015705601290*var_94 + 0.0190476190476190493372499*var_440*var_80 + 0.0031746031746031746004211*var_443; + const double var_445 = 0.3333333333333333148296163*var_174*var_7*var_8; + const double var_446 = 5.6799999999999997157829057*var_154 + 1.8800000000000001154631946*var_60 + 0.5155555555555555447000415*var_81 + 1.4133333333333333303727386*var_167 + 0.8888888888888888395456433*var_47; + const double var_447 = 0.0342857142857142874192711*var_142; + const double var_448 = 4.0000000000000000000000000*var_16*var_222; + const double var_449 = var_448 + var_301; + const double var_450 = 0.0228571428571428571230317*var_58; + const double var_451 = var_370 + 0.0952380952380952328084618*var_16*var_446 + 0.1917460317460317476001563*var_131 + 0.0660317460317460386276522*var_118*var_80 + 0.0800000000000000016653345*var_439 + var_444 + 0.0107936507936507945087934*var_56 + 0.3619047619047619512855363*var_235 + 0.0702645502645502656458021*var_64 + 0.1098412698412698368377605*var_33 + 0.0050793650793650793606737*var_449 + 0.0143915343915343926783912*var_29 + 0.1352380952380952405800230*var_445 + 0.1168253968253968322343894*var_5*var_80 + var_447 + 0.2349206349206349186964360*var_196 + 0.1282539682539682590611818*var_198 + 0.0558730158730158729674109*var_438 + var_450 + 0.0907936507936507875005105*var_211*var_7*var_8 + 0.2025396825396825473131202*var_203 + 0.0831746031746031788678408*var_201 + 0.1206349206349206365507243*var_35 + var_356; + A[72] = 2.0000000000000000000000000*var_13*var_451/(var_14*var_14*var_14); + A[537] = A[72]; + const double var_452 = var_3*w[0][3] + var_8*w[0][14]; + const double var_453 = -var_3*var_452 + var_15*w[0][8]; + const double var_454 = var_7*w[0][4] + var_1*w[0][13]; + const double var_455 = var_454*var_7 + -var_16*w[0][6]; + const double var_456 = var_453*var_8 + -var_15*var_7*w[0][18] + var_16*var_3*w[0][16] + var_1*var_455; + const double var_457 = var_386 + var_381; + const double var_458 = var_97 + var_282; + const double var_459 = var_280 + var_21; + const double var_460 = var_410 + var_42; + const double var_461 = var_378 + var_232; + const double var_462 = var_193 + var_139; + const double var_463 = var_153 + var_292; + const double var_464 = var_98 + var_281; + const double var_465 = var_439 + var_285; + const double var_466 = var_321 + var_207; + const double var_467 = var_16*var_222; + const double var_468 = var_467 + var_367; + const double var_469 = var_16*var_223 + var_125*var_15; + const double var_470 = var_159 + var_79; + const double var_471 = var_20 + var_91; + const double var_472 = var_286 + var_287; + const double var_473 = var_9 + var_32; + const double var_474 = var_19 + var_117; + const double var_475 = var_23 + var_22; + const double var_476 = var_208 + var_257; + const double var_477 = var_149 + var_34; + const double var_478 = var_47 + var_81; + const double var_479 = var_478*var_80; + const double var_480 = var_230 + var_102; + const double var_481 = var_108 + var_112; + const double var_482 = var_481 + var_480; + const double var_483 = var_194 + var_195; + const double var_484 = 0.4222222222222222209886411*var_483; + const double var_485 = 0.0095238095238095246686250*var_482 + 0.7619047619047618624676943*var_464 + 0.0571428571428571410728559*var_475 + 0.2730158730158729896153602*var_462 + 0.5047619047619048560093802*var_466 + 0.4571428571428571285828468*var_469 + 1.2000000000000001776356839*var_396 + 0.9238095238095238581621516*var_324 + 0.2952380952380952439106920*var_460 + 0.0222222222222222230703093*var_479 + 0.0857142857142857150787307*var_477 + 0.3809523809523809312338471*var_473 + 0.1619047619047619124277304*var_463 + 0.1714285714285714301574615*var_457 + 0.0603174603174603182753621*var_470 + 0.1809523809523809756427681*var_471 + 0.2857142857142856984253854*var_325 + 0.7333333333333332815229255*var_476 + 1.0761904761904763638824534*var_459 + 0.1492063492063492036177053*var_226 + 0.1206349206349206365507243*var_472 + 0.9142857142857142571656937*var_465 + 0.3523809523809524058002296*var_468 + 0.1523809523809523946979994*var_456 + 0.2761904761904762084512299*var_461 + 0.4666666666666666740681535*var_458 + 0.0476190476190476164042309*var_474 + var_484; + A[347] = 0.0000000000000000000000000; + const double var_486 = var_46 + 0.2000000000000000111022302*var_42; + const double var_487 = 4.0000000000000000000000000*var_145*var_15; + const double var_488 = 446.3333333333333143855270464*var_43 + 273.6666666666666287710540928*var_36 + var_360; + const double var_489 = 0.8571428571428570952761561*var_149 + 0.9047619047619047671915382*var_148; + const double var_490 = 0.0482539682539682573958473*var_23; + const double var_491 = 0.4740740740740740921665974*var_74; + const double var_492 = 0.0190476190476190493372499*var_98; + const double var_493 = var_200 + var_25; + const double var_494 = 67.0000000000000000000000000*var_51 + 118.0000000000000000000000000*var_186 + 83.0000000000000000000000000*var_85; + const double var_495 = 0.1428571428571428492126927*var_126; + const double var_496 = 0.1396825396825396858879742*var_16*var_47; + const double var_497 = 0.1428571428571428492126927*var_314; + const double var_498 = var_497 + var_496; + const double var_499 = 63.8000000000000042632564146*var_163 + 61.4000000000000056843418861*var_55 + 212.2000000000000170530256582*var_89 + 53.0000000000000000000000000*var_150 + 29.8000000000000007105427358*var_115; + const double var_500 = 4.0000000000000000000000000*var_16*var_206; + const double var_501 = 15.8000000000000007105427358*var_32 + 197.2000000000000170530256582*var_24 + 69.3333333333333285963817616*var_30 + 52.0000000000000000000000000*var_147 + 13.6000000000000014210854715*var_500 + 32.6000000000000014210854715*var_33 + 204.8000000000000113686837722*var_108 + 231.2000000000000170530256582*var_112 + 77.2000000000000028421709430*var_34 + 22.6666666666666642981908808*var_193 + 14.6000000000000014210854715*var_201 + 7.4000000000000003552713679*var_141 + 94.0000000000000000000000000*var_35 + var_94 + 11.6000000000000014210854715*var_448 + 32.0000000000000000000000000*var_287 + 62.8000000000000042632564146*var_144 + var_499*var_7*var_8; + const double var_502 = 0.1047619047619047782937685*var_28 + 0.0044444444444444444405895*var_84 + 0.1142857142857142821457117*var_76 + 0.3428571428571428603149229*var_75 + 0.4021164021164020940801720*var_29 + var_492 + 0.2514285714285714457005838*var_140 + 0.0800000000000000016653345*var_493 + var_495 + 0.2761904761904762084512299*var_486 + 0.0895238095238095193950656*var_9 + 0.0876190476190476241757921*var_16*var_184 + var_320 + 0.1942857142857142838110462*var_38 + 0.0038095238095238095205053*var_15*var_494 + 0.1161904761904761912427730*var_199 + 0.0400000000000000008326673*var_489 + 0.0019047619047619047602526*var_1*var_3*var_488 + var_490 + 0.1028571428571428553189193*var_16*var_61 + 0.2628571428571428447718006*var_105 + 0.2539682539682539541558981*var_139 + 0.1695238095238095210604001*var_143 + 0.3809523809523809312338471*var_31 + 0.3333333333333333148296163*var_498 + 0.1504761904761904856009380*var_487 + var_491 + var_293 + 0.1451851851851851671337812*var_80*var_81 + 0.0031746031746031746004211*var_501; + A[190] = 4.0000000000000000000000000*var_13*var_502/(var_14*var_14*var_14); + A[771] = A[190]; + const double var_503 = 0.0476190476190476164042309*var_141; + const double var_504 = var_503 + var_30; + const double var_505 = -var_7*w[0][0] + var_69; + const double var_506 = var_192*var_80 + var_1*var_3*var_505; + const double var_507 = var_184 + var_61 + 2.0000000000000000000000000*var_223; + const double var_508 = var_3*var_442*var_54 + var_1*var_441*var_53; + const double var_509 = 0.3015873015873015705601290*var_283 + 0.0190476190476190493372499*var_507*var_80 + 0.0031746031746031746004211*var_508; + const double var_510 = var_206*var_80; + const double var_511 = 0.0038095238095238095205053*var_200; + const double var_512 = 0.0419047619047619029908347*var_38; + const double var_513 = 113.0000000000000000000000000*var_161 + 121.0000000000000000000000000*var_101; + const double var_514 = 16.5555555555555535818257340*var_65; + const double var_515 = 61.0000000000000000000000000*var_219 + var_514 + 20.6666666666666642981908808*var_186; + const double var_516 = var_321 + var_222*var_80 + var_408; + const double var_517 = 0.0076190476190476190410106*var_15*var_515 + 0.0660317460317460386276522*var_510 + 0.0846560846560846513852994*var_287 + var_512 + 0.1968253968253968200219362*var_164 + 0.0336507936507936533665486*var_9 + var_511 + 0.0380952380952380986744998*var_76 + 0.0298412698412698421113198*var_386 + 0.1053968253968253915298092*var_149 + 0.1587301587301587213474363*var_197 + 0.3504761904761904967031683*var_240 + 0.1168253968253968322343894*var_516 + var_509 + 0.0050793650793650793606737*var_506 + 0.1365079365079364948076801*var_143 + 0.0440211640211640234388035*var_139 + 0.1288888888888888861750104*var_199 + 0.0006349206349206349200842*var_1*var_3*var_513 + 0.1250793650793650679808877*var_148 + 0.1485714285714285765038767*var_210 + 0.0596825396825396842226397*var_140 + 0.3161904761904761884672155*var_378 + 0.0558730158730158729674109*var_47*var_80; + A[44] = 2.0000000000000000000000000*var_13*var_517/(var_14*var_14*var_14); + A[886] = A[44]; + const double var_518 = var_28 + var_58 + var_189; + A[671] = 0.0000000000000000000000000; + const double var_519 = 0.3333333333333333148296163*var_1*var_214*var_3; + const double var_520 = 1.4133333333333333303727386*var_5 + 0.5155555555555555447000415*var_47 + 1.8800000000000001154631946*var_4 + 5.6799999999999997157829057*var_219 + 0.8888888888888888395456433*var_81; + const double var_521 = 0.1441269841269841311959254*var_199; + const double var_522 = 0.0342857142857142874192711*var_200; + const double var_523 = var_65*var_80; + const double var_524 = var_187 + var_523; + const double var_525 = 0.0228571428571428571230317*var_240; + const double var_526 = 0.1206349206349206365507243*var_164 + var_522 + 0.0952380952380952328084618*var_15*var_520 + var_525 + 0.1917460317460317476001563*var_120 + 0.1282539682539682590611818*var_140 + var_434 + 0.0800000000000000016653345*var_285 + 0.0702645502645502656458021*var_18 + 0.0907936507936507875005105*var_1*var_215*var_3 + 0.0143915343915343926783912*var_30 + 0.3619047619047619512855363*var_210 + 0.0660317460317460386276522*var_129*var_80 + var_509 + 0.0107936507936507945087934*var_284 + 0.0050793650793650793606737*var_524 + 0.1352380952380952405800230*var_519 + 0.0831746031746031788678408*var_143 + var_521 + 0.0558730158730158729674109*var_423 + 0.2025396825396825473131202*var_146 + 0.1098412698412698368377605*var_148 + 0.1168253968253968322343894*var_167*var_80 + 0.2349206349206349186964360*var_197; + A[42] = 2.0000000000000000000000000*var_13*var_526/(var_14*var_14*var_14); + A[361] = A[42]; + A[58] = 0.0000000000000000000000000; + const double var_527 = 0.0419047619047619029908347*var_15*var_49; + const double var_528 = var_527 + var_23; + A[819] = 0.0000000000000000000000000; + const double var_529 = 0.0247619047619047627506461*var_232; + A[350] = 0.0000000000000000000000000; + const double var_530 = 0.4000000000000000222044605*var_143 + var_151; + const double var_531 = 18.0666666666666664298190881*var_89 + 14.8000000000000007105427358*var_104 + 26.3333333333333321490954404*var_163; + const double var_532 = 0.0397883597883597894817598*var_74 + 0.2438095238095238093123385*var_77; + const double var_533 = 3.6666666666666665186369300*var_49*var_80; + const double var_534 = var_31 + var_533 + var_153; + const double var_535 = 0.0285714285714285705364279*var_35 + 0.1523809523809523946979994*var_257; + const double var_536 = 0.1028571428571428553189193*var_25; + const double var_537 = 0.0330158730158730193138261*var_112 + var_536; + const double var_538 = 0.0351322751322751328229010*var_16*var_65; + const double var_539 = 0.0050793650793650793606737*var_283; + const double var_540 = 0.0063492063492063492008421*var_46; + const double var_541 = var_20 + var_367; + const double var_542 = 0.0400000000000000008326673*var_49 + var_65; + const double var_543 = 0.0228571428571428571230317*var_314; + const double var_544 = var_495 + var_134; + const double var_545 = 0.0317460317460317442694873*var_208 + var_539 + 0.0584126984126984161171947*var_16*var_167 + 0.0095238095238095246686250*var_531*var_7*var_8 + 0.3809523809523809312338471*var_149 + 0.0685714285714285748385421*var_30 + 0.1841269841269841389674866*var_1*var_101*var_3 + 0.0846560846560846513852994*var_15*var_542 + 0.0596825396825396842226397*var_185 + 0.0533333333333333367565210*var_103 + var_306 + 0.0203174603174603174426949*var_271 + 0.1460317460317460402929868*var_240 + var_543 + 0.0444444444444444461406185*var_148 + 0.0088888888888888888811790*var_541 + 0.1904761904761904656169236*var_38 + 0.1333333333333333314829616*var_544 + 0.0120634920634920643489618*var_117 + 0.6666666666666666296592325*var_535 + 0.1650793650793650757524489*var_9 + var_538 + 0.0742857142857142882519383*var_178 + 0.0241269841269841286979236*var_44 + 0.1047619047619047782937685*var_151 + 0.0361904761904761895774385*var_230 + 0.1092063492063492097239319*var_19 + var_540 + 0.2933333333333333348136307*var_22 + 0.0287830687830687853567824*var_18 + 0.0507936507936507936067372*var_29 + 0.0044444444444444444405895*var_203 + 0.1790476190476190387901312*var_147 + var_532 + 0.0012698412698412698401684*var_534 + var_490 + 0.0110052910052910058597009*var_64 + 0.0057142857142857142807579*var_410 + 0.1185185185185185230416494*var_236 + 0.0253968253968253968033686*var_378 + 0.2501587301587301359617754*var_108 + 0.0165079365079365096569131*var_233 + 0.2158730158730158832369739*var_284 + 0.0247619047619047627506461*var_33 + 0.0055026455026455029298504*var_253 + var_537 + 0.0780952380952380925682732*var_91 + 0.3250793650793650790831180*var_144; + A[156] = 16.0000000000000000000000000*var_13*var_545/(var_14*var_14*var_14); + A[650] = A[156]; + A[443] = 0.0000000000000000000000000; + A[630] = 0.0000000000000000000000000; + const double var_546 = var_439 + var_367; + const double var_547 = 0.0247619047619047627506461*var_378; + const double var_548 = var_76 + var_56 + var_282; + A[264] = 0.0000000000000000000000000; + A[166] = 0.0000000000000000000000000; + const double var_549 = var_1*var_27*var_8*var_8 + var_26*var_3*var_7*var_7; + const double var_550 = var_26*var_3*var_8*var_8 + var_1*var_27*var_7*var_7; + const double var_551 = var_193 + var_66 + var_290; + const double var_552 = var_215 + 0.3333333333333333148296163*var_214; + const double var_553 = var_427 + var_219; + const double var_554 = 0.0220105820105820117194018*var_226; + const double var_555 = 0.2114285714285714379290226*var_1*var_161*var_3; + const double var_556 = 0.1111111111111111049432054*var_555; + const double var_557 = var_120 + var_144; + const double var_558 = var_530 + var_175; + const double var_559 = 0.3174603174603174426948726*var_132 + 0.4380952380952381486345359*var_392 + 0.1428571428571428492126927*var_294 + 0.3873015873015873133944353*var_549 + var_556 + 0.0355555555555555555247160*var_321 + 0.0704761904761904700578157*var_210 + var_379 + 0.0761904761904761973489997*var_16*var_553 + 0.0256084656084656081542761*var_194 + 0.0634920634920634885389745*var_558 + 0.0035978835978835981695978*var_139 + 0.0582010582010581978273933*var_287 + 0.0590476190476190501699172*var_1*var_3*var_552 + 0.1460317460317460402929868*var_198 + 0.0273015873015873024309830*var_148 + 0.0603174603174603182753621*var_550 + 0.0533333333333333367565210*var_200 + 0.1439153439153439129061240*var_49*var_80 + 0.1809523809523809756427681*var_271 + 0.1555555555555555580227178*var_205 + 0.0806349206349206287791631*var_199 + 0.0006349206349206349200842*var_557 + 0.0152380952380952380820212*var_381 + 0.0023280423280423283294294*var_48 + 0.1396825396825396858879742*var_197 + 0.0442328042328042347897110*var_195 + var_269 + 0.0698412698412698429439871*var_147 + 0.0253968253968253968033686*var_165 + var_554 + 0.1365079365079364948076801*var_283 + 0.0311111111111111102167648*var_196 + 0.2920634920634920805859736*var_280 + 0.0241269841269841286979236*var_146 + 0.0901587301587301603866820*var_15*var_186 + 0.0222222222222222230703093*var_551 + 0.0124867724867724870507768*var_65*var_80 + 0.3269841269841269881801793*var_136*var_7*var_8 + 0.0825396825396825378762244*var_201 + 0.0450793650793650801933410*var_140 + 0.1447619047619047583097540*var_15*var_219 + 0.0057142857142857142807579*var_88 + 0.3333333333333333148296163*var_503; + A[343] = 32.0000000000000000000000000*var_13*var_559/(var_14*var_14*var_14); + const double var_560 = 3.0000000000000000000000000*var_1*var_215*var_3; + const double var_561 = 0.0044444444444444444405895*var_144 + 0.0215873015873015890175868*var_15*var_186; + const double var_562 = 2.0000000000000000000000000*var_16*var_184; + const double var_563 = 1.5333333333333332149095440*var_209 + 2.5777777777777779455448126*var_145 + 1.8000000000000000444089210*var_4 + 1.2592592592592593003786305*var_81; + const double var_564 = 0.0063492063492063492008421*var_94; + const double var_565 = 31.0000000000000000000000000*var_150 + var_376; + const double var_566 = 107.0000000000000000000000000*var_217 + 2.8666666666666666962726140*var_41; + const double var_567 = var_280 + var_201; + const double var_568 = var_231 + var_90; + const double var_569 = var_193 + var_91; + const double var_570 = var_467 + var_234; + const double var_571 = 0.0444444444444444461406185*var_570 + 0.0761904761904761973489997*var_314; + const double var_572 = var_434 + var_571; + const double var_573 = var_439 + 2.0000000000000000000000000*var_16*var_169; + const double var_574 = 7.6666666666666660745477202*var_132 + var_573 + var_25; + const double var_575 = 0.0571428571428571410728559*var_15*var_563 + 8.0000000000000000000000000*var_561 + var_296 + 0.0469841269841269823515084*var_120 + 2.0000000000000000000000000*var_572 + 0.1104761904761904778293768*var_200 + 0.6179894179894179773171459*var_49*var_80 + 0.0336507936507936533665486*var_148 + 0.6412698412698413230614847*var_197 + 1.3904761904761906432526075*var_153 + 0.0960846560846560920898796*var_523 + 0.1111111111111111049432054*var_205 + 0.1426455026455026586784669*var_194 + var_564 + 0.1657142857142857028662775*var_560 + 0.2952380952380952439106920*var_392 + 1.0158730158730158166235924*var_203 + var_521 + 0.8063492063492063710583579*var_198 + var_302 + 1.0539682539682539985648191*var_410 + 0.2222222222222222098864108*var_286 + 0.1079365079365079416184869*var_33 + 0.0863492063492063560703471*var_108 + 0.3873015873015873133944353*var_147 + var_355 + 0.0031746031746031746004211*var_165 + 0.1405291005291005312916042*var_195 + 0.1904761904761904656169236*var_288 + 0.9460317460317460014351809*var_281 + 0.0126984126984126984016843*var_565*var_7*var_8 + 0.0977777777777777828971395*var_140 + 0.0419047619047619029908347*var_568 + 0.1492063492063492036177053*var_283 + 0.0465608465608465665885873*var_139 + 0.4571428571428571285828468*var_562 + 0.2603174603174603363164863*var_567 + 0.0095238095238095246686250*var_1*var_3*var_566 + var_268 + 2.0698412698412700372330164*var_131 + 0.0907936507936507875005105*var_143 + 0.0196825396825396833899724*var_146 + 0.0444444444444444461406185*var_569 + 0.1523809523809523946979994*var_574; + A[131] = 4.0000000000000000000000000*var_13*var_575/(var_14*var_14*var_14); + A[334] = A[131]; + const double var_576 = var_138 + var_192; + const double var_577 = var_47 + var_576; + const double var_578 = var_110 + var_85; + const double var_579 = 1.0694444444444444197728217*var_577 + 1.5337301587301586103251338*var_4 + 6.1646825396825395415589810*var_81 + 10.9861111111111107163651468*var_152 + 9.4523809523809525501292228*var_186 + 1.4761904761904760530200065*var_219 + 4.3571428571428567622092487*var_145 + 4.2996031746031739828595164*var_415 + 0.0575396825396825364884457*var_578; + A[31] = 0.2000000000000000111022302*var_13*var_15*var_579/(var_14*var_14*var_14); + const double var_580 = 0.8000000000000000444089210*var_219; + const double var_581 = 6.2000000000000001776356839*var_65 + 1.1733333333333333392545228*var_118 + 4.4666666666666667850904560*var_4 + 3.6666666666666665186369300*var_85 + 11.3333333333333321490954404*var_158 + var_580 + 1.8133333333333334635995016*var_49 + 0.1066666666666666735130420*var_5; + const double var_582 = 2.8000000000000002664535259*var_212 + 4.4476190476190478051421451*var_211 + 12.2380952380952372493538860*var_87 + 1.6857142857142857206298459*var_136; + const double var_583 = 0.0520634920634920617121821*var_16*var_61; + const double var_584 = 0.2391534391534391734701614*var_16*var_49; + const double var_585 = 0.2895238095238095166195080*var_154*var_16; + const double var_586 = var_583 + 0.2838095238095237893283240*var_32 + 0.0296296296296296307604123*var_66 + 0.0152380952380952380820212*var_500 + 0.9079365079365079305162567*var_121 + 0.0920634920634920694837433*var_94 + 0.0666666666666666657414808*var_582*var_7*var_8 + 0.0526984126984126957649046*var_141 + 0.0304761904761904761640423*var_467 + 0.0800000000000000016653345*var_142 + 0.0438095238095238120878960*var_117 + 0.1238095238095238276310184*var_229 + 0.3492063492063491869643599*var_196 + 0.2666666666666666629659233*var_189 + 0.0711111111111111110494321*var_438 + 0.0952380952380952328084618*var_581*var_80 + var_585 + 0.3415873015873016060872658*var_16*var_60 + var_584 + 0.0628571428571428614251460*var_175 + 0.0190476190476190493372499*var_198 + 0.0008465608465608465962524*var_193 + 0.1714285714285714301574615*var_34 + 0.4317460317460317664739478*var_58 + 0.1396825396825396858879742*var_281 + 0.0273015873015873024309830*var_282 + 0.2158730158730158832369739*var_416; + A[234] = 0.0000000000000000000000000; + const double var_587 = var_131 + var_23; + A[25] = 0.0000000000000000000000000; + A[135] = 0.0000000000000000000000000; + const double var_588 = 3.1460317460317459570262599*var_55 + 2.9873015873015873467011261*var_115 + 4.8571428571428567622092487*var_104 + 1.4000000000000001332267630*var_211 + 1.8698412698412698595973325*var_150; + const double var_589 = 9.0000000000000000000000000*var_36 + 8.0793650793650790831179620*var_101 + 25.0476190476190474498707772*var_37 + 16.9682539682539683667528152*var_45; + const double var_590 = 16.5555555555555535818257340*var_49; + const double var_591 = 5.7777777777777776790912867*var_47 + 61.0000000000000000000000000*var_223 + 20.6666666666666642981908808*var_206 + 15.3333333333333321490954404*var_222 + 46.0000000000000000000000000*var_57 + var_590; + const double var_592 = 0.0351322751322751328229010*var_15*var_49; + const double var_593 = var_483 + 0.3333333333333333148296163*var_462; + const double var_594 = 0.6666666666666666296592325*var_226 + var_593; + const double var_595 = 0.2539682539682539541558981*var_594; + const double var_596 = var_148 + var_32; + const double var_597 = 0.2253968253968254009667049*var_596 + 2.0000000000000000000000000*var_592 + 0.9460317460317460014351809*var_35 + 0.3860317460317460591667782*var_147 + 0.2787301587301587169065442*var_28 + 0.0203174603174603174426949*var_321 + 0.2006349206349206382160588*var_22 + 0.1358730158730158676938515*var_196 + 0.1790476190476190387901312*var_257 + 1.4323809523809523103210495*var_75 + 0.0869841269841269831841757*var_146 + 0.4609523809523809467769695*var_25 + 0.5409523809523809623200918*var_125*var_15 + 0.0520634920634920617121821*var_120 + 0.6120634920634920872473117*var_23 + 0.0349206349206349214719936*var_284 + 0.1917460317460317476001563*var_121 + 0.0400000000000000008326673*var_1*var_3*var_589 + 0.2755555555555555535818257*var_112 + 0.2038095238095238015407773*var_88 + 0.6387301587301587035838679*var_24 + 0.3168253968253968433366197*var_33 + 0.8546031746031745868208418*var_34 + 0.0120634920634920643489618*var_178 + 0.2812698412698412808730097*var_20 + 0.5066666666666667095952903*var_103 + 0.1485714285714285765038767*var_185 + 0.3619047619047619512855363*var_52 + var_595 + 0.0491005291005291027994772*var_48 + 0.0076190476190476190410106*var_16*var_591 + 0.3161904761904761884672155*var_208 + 0.1964021164021164111979090*var_80*var_81 + 0.9574603174603174560175489*var_31 + 0.1346031746031746134661944*var_118*var_15 + 0.1441269841269841311959254*var_91 + var_306 + 0.1225396825396825456477856*var_143 + 0.0057142857142857142807579*var_386 + 1.5085714285714286742035029*var_76 + 0.0146031746031746040292987*var_117 + 0.0253968253968253968033686*var_304 + 0.2000000000000000111022302*var_588*var_7*var_8 + var_525; + A[229] = 0.0000000000000000000000000; + const double var_598 = var_184 + var_51; + const double var_599 = var_155 + var_151; + const double var_600 = var_235 + var_210; + const double var_601 = var_120 + var_131; + const double var_602 = var_155 + var_288; + const double var_603 = var_66 + var_50; + const double var_604 = var_44 + var_90; + const double var_605 = var_231 + var_363; + const double var_606 = var_203 + var_146; + const double var_607 = var_130 + var_119; + const double var_608 = var_606 + var_607 + var_479; + const double var_609 = var_140 + var_198; + const double var_610 = 0.2222222222222222098864108*var_462 + var_325; + const double var_611 = var_610 + var_609; + const double var_612 = var_460 + var_480; + const double var_613 = var_94 + var_283; + const double var_614 = var_613 + var_226; + const double var_615 = var_197 + var_196; + const double var_616 = var_466 + var_615; + const double var_617 = 1.6000000000000000888178420*var_611 + var_484 + 0.5333333333333333259318465*var_326 + 5.2000000000000001776356839*var_396 + 0.3333333333333333148296163*var_616 + 1.3333333333333332593184650*var_464 + 0.7111111111111111382498962*var_603 + 0.0666666666666666657414808*var_614 + 0.2000000000000000111022302*var_604 + 4.8000000000000007105427358*var_602 + 0.2666666666666666629659233*var_612 + 3.6000000000000000888178420*var_465 + var_601 + 3.8666666666666666962726140*var_324 + var_605 + 0.7333333333333332815229255*var_608 + 1.0666666666666666518636930*var_458 + 2.0666666666666664298190881*var_600; + A[550] = 0.0000000000000000000000000; + const double var_618 = 0.3333333333333333148296163*var_1*var_215*var_3; + const double var_619 = 6.4000000000000003552713679*var_36 + 23.0000000000000000000000000*var_41; + const double var_620 = 0.0431746031746031780351736*var_280; + const double var_621 = 577.0000000000000000000000000*var_150 + 181.0000000000000000000000000*var_55 + 389.0000000000000000000000000*var_115 + 43.0000000000000000000000000*var_163 + 221.0000000000000000000000000*var_89; + const double var_622 = var_169 + var_209; + const double var_623 = 1.4333333333333333481363070*var_41 + 14.7666666666666657192763523*var_45 + 88.9666666666666685614472954*var_36 + 2.2333333333333333925452280*var_101 + 17.0000000000000000000000000*var_37 + 34.2333333333333342807236477*var_43; + const double var_624 = var_222 + var_167; + const double var_625 = 0.2666666666666666629659233*var_223*var_80; + const double var_626 = 0.0507936507936507936067372*var_624*var_80 + var_625; + const double var_627 = 1.9682539682539681447082103*var_118 + 0.1380952380952381042256150*var_85 + 0.3333333333333333148296163*var_220 + 2.3571428571428572062984586*var_51 + 2.4952380952380952550129223*var_125 + 1.2317460317460318108828687*var_5 + 0.9947089947089946537772676*var_49; + const double var_628 = 4.5952380952380948997415544*var_169 + 7.3888888888888883954564335*var_81 + 13.5238095238095237249353886*var_152 + 5.9285714285714279370154145*var_184; + const double var_629 = var_15*var_627 + 2.7341269841269841833764076*var_28 + 1.3809523809523809312338471*var_236 + 1.1944444444444444197728217*var_97 + 4.4920634920634920916882038*var_31 + 1.5984126984126985071554827*var_120 + 0.4174603174603174760015634*var_22 + 0.1515873015873015761112441*var_19 + 1.1312169312169313428739770*var_30 + 13.3253968253968242407836442*var_24 + 1.3650793650793651146102548*var_98 + 1.4277777777777778123180497*var_146 + 1.2182539682539681447082103*var_20 + 5.2936507936507934957148791*var_112 + 0.0238095238095238082021154*var_103 + var_628*var_80 + 0.2582010582010582089296236*var_18 + 2.0476190476190474498707772*var_76; + const double var_630 = var_626 + 0.1746031746031745934821799*var_506 + 0.2000000000000000111022302*var_629 + 0.0238095238095238082021154*var_1*var_3*var_623; + A[34] = var_13*var_630/(var_14*var_14*var_14); + A[121] = A[34]; + const double var_631 = 0.0038095238095238095205053*var_142; + const double var_632 = 0.0038095238095238095205053*var_19; + const double var_633 = 0.0380952380952380986744998*var_142 + var_632; + const double var_634 = 0.0965079365079365147916945*var_1*var_3*var_43 + 0.0634920634920634885389745*var_363 + 0.0457142857142857142460635*var_126; + A[643] = 0.0000000000000000000000000; + const double var_635 = var_178 + var_28; + const double var_636 = 0.0069841269841269841209264*var_102 + 0.0380952380952380986744998*var_105; + A[449] = 0.0000000000000000000000000; + const double var_637 = 2.3777777777777777679091287*var_36 + 30.2222222222222214327302936*var_41 + 3.8444444444444445529995846*var_215 + 24.0000000000000000000000000*var_216 + 25.1111111111111107163651468*var_214; + const double var_638 = 49.7111111111111156901642971*var_211 + 71.8888888888888857309211744*var_87 + 8.2000000000000010658141036*var_174; + const double var_639 = 0.0050793650793650793606737*var_79 + 0.0076190476190476190410106*var_153; + const double var_640 = 1.6000000000000000888178420*var_189 + 0.0444444444444444461406185*var_28; + const double var_641 = 0.0571428571428571410728559*var_281; + const double var_642 = var_448 + var_201; + const double var_643 = 67.0000000000000000000000000*var_169 + 83.0000000000000000000000000*var_60 + 118.0000000000000000000000000*var_206; + const double var_644 = 1.8888888888888888395456433*var_80*var_81 + 47.3333333333333285963817616*var_24 + var_131 + 101.0000000000000000000000000*var_198 + 149.7777777777777714618423488*var_194 + var_16*var_643 + 118.1111111111111000582241104*var_195; + const double var_645 = 0.4857142857142857095276156*var_94 + 0.0444444444444444461406185*var_287 + 0.5714285714285713968507707*var_155 + 0.2222222222222222098864108*var_139 + 0.0825396825396825378762244*var_199 + 0.0285714285714285705364279*var_638*var_7*var_8 + 0.0400000000000000008326673*var_56 + 1.2000000000000001776356839*var_21 + 0.5542857142857142704883699*var_141 + 0.9206349206349205838151306*var_143 + 1.9746031746031746934022522*var_196 + 0.0971428571428571419055231*var_282 + 1.3904761904761906432526075*var_110*var_15 + 0.3022222222222222254295332*var_197 + var_641 + 0.0571428571428571410728559*var_1*var_3*var_637 + 2.3555555555555556246360993*var_140 + var_295 + 3.2253968253968254842334318*var_120 + 0.9142857142857142571656937*var_210 + 0.2539682539682539541558981*var_286 + 2.1015873015873016704802012*var_98 + 0.1015873015873015872134744*var_193 + 0.0888888888888888922812370*var_322 + var_639 + 0.4571428571428571285828468*var_200 + 0.0634920634920634885389745*var_46 + var_640 + 0.1504761904761904856009380*var_642 + 0.9820105820105821115006961*var_65*var_80 + 0.6514285714285714679050443*var_142 + 0.3746031746031746045844102*var_97 + 0.0438095238095238120878960*var_203 + 0.1079365079365079416184869*var_31 + 0.6095238095238095787919974*var_15*var_219 + 0.0038095238095238095205053*var_644 + 2.5396825396825395415589810*var_121 + 1.8285714285714285143313873*var_202 + 0.3047619047619047893959987*var_52 + 0.9485714285714286209127977*var_439 + 0.7142857142857143015746146*var_229 + 1.4984126984126984183376408*var_146 + var_359; + A[157] = 4.0000000000000000000000000*var_13*var_645/(var_14*var_14*var_14); + A[680] = A[157]; + const double var_646 = 1.1888888888888888839545643*var_174 + 1.4555555555555557134539413*var_55 + 32.9444444444444428654605872*var_87 + 16.1222222222222235643585009*var_211 + 8.2111111111111121374506183*var_114 + 9.4000000000000003552713679*var_212; + const double var_647 = 1.2788359788359788815625961*var_47 + 2.2777777777777776790912867*var_222 + 1.5393650793650792696354301*var_206 + 0.1771428571428571296930699*var_154 + 0.2561904761904761906876615*var_61 + 0.0400000000000000008326673*var_224; + const double var_648 = 13.5238095238095237249353886*var_158 + 5.9285714285714279370154145*var_85 + 4.5952380952380948997415544*var_4 + 7.3888888888888883954564335*var_65 + var_420; + const double var_649 = 0.1746031746031745934821799*var_301 + 4.5111111111111110716365147*var_121 + 0.6753968253968254398245108*var_33 + 0.1850793650793650657604417*var_34 + 0.5404232804232804721067396*var_193 + 0.3363492063492063421925593*var_201 + 2.7444444444444444641817427*var_21 + var_16*var_647 + 0.2714285714285714079530010*var_142 + 0.0714285714285714246063463*var_646*var_7*var_8 + 2.0984126984126985071554827*var_196 + 2.1579365079365078194939542*var_94 + 0.7793650793650793717759484*var_35 + 0.9468253968253967922663605*var_141 + 0.2761904761904762084512299*var_438 + 0.9428571428571428381104624*var_189 + 0.8166137566137566805579695*var_195 + 0.4333333333333333481363070*var_232 + 0.4212698412698412941956860*var_198 + 0.2000000000000000111022302*var_648*var_80 + 0.0811111111111111060534284*var_32; + const double var_650 = 0.0342857142857142874192711*var_240 + 0.0038095238095238095205053*var_48; + const double var_651 = 0.9555555555555556024316388*var_1*var_3*var_36; + const double var_652 = 0.0038095238095238095205053*var_38 + 0.0165079365079365096569131*var_144; + const double var_653 = 0.0742857142857142882519383*var_208; + const double var_654 = 0.0457142857142857142460635*var_103 + var_653; + const double var_655 = 0.0057142857142857142807579*var_28; + const double var_656 = 0.0952380952380952328084618*var_35 + var_655; + const double var_657 = 0.2666666666666666629659233*var_19 + var_105; + const double var_658 = 0.0234920634920634911757542*var_80*var_81; + const double var_659 = 0.0209523809523809514954173*var_16*var_81; + const double var_660 = 1.9333333333333333481363070*var_55*var_7*var_8; + const double var_661 = 0.0209523809523809514954173*var_58; + const double var_662 = var_284 + var_18; + const double var_663 = var_210 + var_288; + const double var_664 = var_88 + var_34; + const double var_665 = var_178 + var_33; + const double var_666 = 0.8000000000000000444089210*var_76 + 0.7047619047619048116004592*var_108; + const double var_667 = var_148 + var_666; + const double var_668 = var_654 + 0.0323809523809523783222097*var_50 + 0.1600000000000000033306691*var_663 + 0.0260317460317460308560911*var_112 + var_661 + 0.0582010582010581978273933*var_193 + 0.0228571428571428571230317*var_140 + 0.0285714285714285705364279*var_651 + 0.0469841269841269823515084*var_44 + 0.0463492063492063482987859*var_91 + 0.0901587301587301603866820*var_16*var_206 + 0.6666666666666666296592325*var_656 + 0.0533333333333333367565210*var_267 + var_266 + var_358 + 0.0088888888888888888811790*var_448 + 0.0647619047619047566444195*var_31 + 0.1161904761904761912427730*var_118*var_15 + 0.0361904761904761895774385*var_314 + 0.0306878306878306909843968*var_195 + 0.0857142857142857150787307*var_662 + 0.0063492063492063492008421*var_203 + 0.0035978835978835981695978*var_16*var_47 + 0.0006349206349206349200842*var_90 + 0.1111111111111111049432054*var_659 + 0.0609523809523809523280846*var_1*var_3*var_45 + 2.0000000000000000000000000*var_652 + 0.0450793650793650801933410*var_665 + 0.0622222222222222204335296*var_201 + 0.0914285714285714284921269*var_25 + 0.2057142857142857106378386*var_75 + 0.0590476190476190501699172*var_146 + 0.0148148148148148153802062*var_236 + 0.1212698412698412636645529*var_150*var_7*var_8 + 0.0704761904761904700578157*var_185 + 0.1663492063492063577356816*var_147 + 0.1132275132275132323300681*var_30 + 0.0311111111111111102167648*var_24 + 0.0209523809523809514954173*var_199 + 0.0266666666666666683782605*var_149 + var_650 + 0.1523809523809523946979994*var_164 + 0.1142857142857142821457117*var_657 + 0.0666666666666666657414808*var_667 + 0.0095238095238095246686250*var_660 + 0.1695238095238095210604001*var_15*var_5 + 0.0120634920634920643489618*var_664 + 0.0692063492063492019523707*var_198 + 0.3333333333333333148296163*var_658; + A[192] = 32.0000000000000000000000000*var_13*var_668/(var_14*var_14*var_14); + A[366] = A[192]; + A[204] = 0.0000000000000000000000000; + A[47] = 0.0000000000000000000000000; + const double var_669 = var_231 + var_178; + A[358] = 0.0000000000000000000000000; + A[876] = 0.0000000000000000000000000; + const double var_670 = 0.0114285714285714285615159*var_16*var_427; + const double var_671 = 0.0317460317460317442694873*var_549; + const double var_672 = 0.6666666666666666296592325*var_670 + var_671 + 0.0044444444444444444405895*var_550 + 0.0177777777777777777623580*var_301; + const double var_673 = 0.0304761904761904761640423*var_396 + 0.0482539682539682573958473*var_226; + const double var_674 = var_19 + var_267; + const double var_675 = 1.7333333333333333925452280*var_49 + 13.0000000000000000000000000*var_5 + 9.2000000000000010658141036*var_118 + 9.4000000000000003552713679*var_209 + 0.8666666666666666962726140*var_47; + const double var_676 = var_280 + var_195; + const double var_677 = var_64 + var_292; + const double var_678 = var_523 + 12.2000000000000010658141036*var_197 + 0.8000000000000000444089210*var_234 + 7.4000000000000003552713679*var_676 + 12.8000000000000007105427358*var_196 + 5.5333333333333332149095440*var_18 + 0.4000000000000000222044605*var_66 + 11.8000000000000007105427358*var_132 + var_15*var_675 + 6.4000000000000003552713679*var_121 + 3.4000000000000003552713679*var_198 + 0.2000000000000000111022302*var_677 + var_130 + 2.0666666666666664298190881*var_194; + const double var_679 = 0.0914285714285714284921269*var_288; + const double var_680 = var_229 + var_20; + const double var_681 = var_271 + var_445; + const double var_682 = var_205 + var_410; + const double var_683 = var_284 + var_148 + var_165; + const double var_684 = var_683 + var_201; + const double var_685 = 0.0114285714285714285615159*var_103; + const double var_686 = var_679 + 0.0552380952380952389146884*var_681 + 0.0063492063492063492008421*var_678 + var_673 + var_631 + 0.0196825396825396833899724*var_283 + 0.0819047619047619107623959*var_381 + 0.0285714285714285705364279*var_560 + 0.0082539682539682548284565*var_680 + 0.0260317460317460308560911*var_146 + 0.0266666666666666683782605*var_439 + 0.0419047619047619029908347*var_1*var_216*var_3 + 0.0088888888888888888811790*var_21 + 0.0400000000000000008326673*var_88 + 0.0273015873015873024309830*var_682 + 0.0006349206349206349200842*var_95 + 0.0031746031746031746004211*var_684 + 0.0317460317460317442694873*var_378 + 0.0228571428571428571230317*var_120 + var_672 + var_685 + 0.0146031746031746040292987*var_674; + A[191] = 16.0000000000000000000000000*var_13*var_686/(var_14*var_14*var_14); + A[336] = A[191]; + const double var_687 = 0.0380952380952380986744998*var_285 + 0.0061375661375661378499347*var_16*var_81 + 0.0209523809523809514954173*var_153; + A[509] = A[44]; + A[663] = 0.0000000000000000000000000; + const double var_688 = 0.0175661375661375664114505*var_49*var_80 + 0.0057142857142857142807579*var_126; + const double var_689 = 0.0787301587301587335598896*var_601 + 0.0179894179894179891132655*var_74; + const double var_690 = 0.0400000000000000008326673*var_153 + 0.0114285714285714285615159*var_253; + const double var_691 = var_178 + var_240 + var_202; + const double var_692 = 0.0368253968253968236301610*var_15*var_81; + const double var_693 = 0.0342857142857142874192711*var_314; + const double var_694 = var_467 + var_285; + const double var_695 = 113.0000000000000000000000000*var_204 + var_329; + const double var_696 = var_208 + var_207; + const double var_697 = var_201 + var_91; + const double var_698 = var_286 + var_48; + const double var_699 = var_321 + var_140; + const double var_700 = 0.8000000000000000444089210*var_148 + var_164; + const double var_701 = var_700 + var_90; + const double var_702 = 0.0114285714285714285615159*var_25; + const double var_703 = 0.0228571428571428571230317*var_103; + const double var_704 = 0.1841269841269841389674866*var_699 + 0.0133333333333333341891302*var_24 + 0.0285714285714285705364279*var_137*var_7*var_8 + 0.0279365079365079364837054*var_147 + 0.1301587301587301681582431*var_281 + 0.0006349206349206349200842*var_1*var_3*var_695 + 0.1269841269841269770779490*var_139 + 0.1428571428571428492126927*var_112 + 0.0031746031746031746004211*var_102 + 0.1873015873015873022922051*var_143 + 0.0076190476190476190410106*var_691 + var_109 + 0.0025396825396825396803369*var_284 + 0.0444444444444444461406185*var_23 + 0.0088888888888888888811790*var_121 + 0.0228571428571428571230317*var_185 + var_689 + 0.0920634920634920694837433*var_44 + 0.0507936507936507936067372*var_20 + 0.0476190476190476164042309*var_257 + 0.0203174603174603174426949*var_151 + 0.0812698412698412697707795*var_146 + 0.1066666666666666735130420*var_75 + 0.1149206349206349231373281*var_280 + 0.1142857142857142821457117*var_696 + 0.0486772486772486800976623*var_195 + var_690 + 0.0431746031746031780351736*var_283 + 0.0342857142857142874192711*var_282 + 0.0380952380952380986744998*var_697 + 0.0666666666666666657414808*var_193 + var_692 + var_688 + 0.1089947089947090053119183*var_194 + 0.3333333333333333148296163*var_702 + 0.0209523809523809514954173*var_698 + 0.0685714285714285748385421*var_694 + 0.0939682539682539647030168*var_15*var_186 + 0.0171428571428571437096355*var_32 + var_547 + 0.0112169312169312172106084*var_65*var_80 + var_693 + 0.0126984126984126984016843*var_701 + 2.6666666666666665186369300*var_703; + A[279] = 32.0000000000000000000000000*var_13*var_704/(var_14*var_14*var_14); + A[228] = 0.0000000000000000000000000; + const double var_705 = 101.0000000000000000000000000*var_217; + const double var_706 = 239.0000000000000000000000000*var_101 + 311.0000000000000000000000000*var_41 + 181.0000000000000000000000000*var_215 + var_705; + const double var_707 = 0.0038095238095238095205053*var_58; + const double var_708 = 0.0025396825396825396803369*var_253 + var_707; + const double var_709 = var_60 + var_167; + const double var_710 = 0.2698412698412698262906417*var_47 + 5.0476190476190474498707772*var_169 + 9.7142857142857135244184974*var_154 + 4.6666666666666660745477202*var_709; + const double var_711 = 0.0393650793650793667799448*var_49*var_80; + const double var_712 = 27.3333333333333321490954404*var_209 + 48.0000000000000000000000000*var_219 + 20.6666666666666642981908808*var_4 + 5.8888888888888883954564335*var_49; + const double var_713 = var_321 + var_280; + const double var_714 = 27.0000000000000000000000000*var_114 + 23.0000000000000000000000000*var_212; + const double var_715 = 0.0476190476190476164042309*var_199; + const double var_716 = 20.6000000000000014210854715*var_197 + 46.0000000000000000000000000*var_98; + const double var_717 = var_90 + var_716; + const double var_718 = 0.0685714285714285748385421*var_548 + 0.0552380952380952389146884*var_205 + 0.7314285714285714279370154*var_189 + 0.0723809523809523791548770*var_231 + 0.0914285714285714284921269*var_230 + 0.0800000000000000016653345*var_16*var_710 + 0.3066666666666666984930600*var_143 + 0.9142857142857142571656937*var_120 + 0.3219047619047619157583995*var_146 + 0.1180952380952381003398344*var_196 + 0.0736507936507936472603220*var_139 + 0.1993650793650793562328261*var_64 + var_708 + 0.2476190476190476552620368*var_121 + 0.1980952380952381020051689*var_23 + var_715 + 2.0000000000000000000000000*var_395 + var_331 + 0.2057142857142857106378386*var_142 + 0.0114285714285714285615159*var_15*var_712 + 0.1384126984126984039047414*var_65*var_80 + 0.1371428571428571496770843*var_141 + 0.0266666666666666683782605*var_131 + 0.0952380952380952328084618*var_203 + 0.0076190476190476190410106*var_29 + 0.2838095238095237893283240*var_97 + 0.2653968253968254087382661*var_194 + 0.4000000000000000222044605*var_262 + 0.9371428571428571663304297*var_21 + 0.0133333333333333341891302*var_28 + 0.0228571428571428571230317*var_7*var_714*var_8 + 0.0019047619047619047602526*var_1*var_3*var_706 + 0.3314285714285714057325549*var_200 + 0.3200000000000000066613381*var_94 + var_711 + 0.1790476190476190387901312*var_132 + 0.0419047619047619029908347*var_713 + 0.1485714285714285765038767*var_22 + 0.0990476190476190510025845*var_119 + var_417 + 0.0190476190476190493372499*var_717; + A[222] = 8.0000000000000000000000000*var_13*var_718/(var_14*var_14*var_14); + A[687] = A[222]; + const double var_719 = 3.9634920634920636217657375*var_81 + 9.4000000000000003552713679*var_152; + const double var_720 = 1.9682539682539681447082103*var_129 + 2.4952380952380952550129223*var_223 + 0.1380952380952381042256150*var_61 + 1.2317460317460318108828687*var_167 + 2.3571428571428572062984586*var_184 + 0.9947089947089946537772676*var_65 + 0.3333333333333333148296163*var_719; + const double var_721 = var_84 + var_139; + const double var_722 = var_321 + var_20; + const double var_723 = 0.4000000000000000222044605*var_159; + A[416] = 0.0000000000000000000000000; + const double var_724 = var_481 + var_279; + const double var_725 = 0.0158730158730158721347436*var_151 + 0.0025396825396825396803369*var_286 + 0.0006349206349206349200842*var_178 + 0.0292063492063492080585974*var_23 + 0.0457142857142857142460635*var_233 + 0.0165079365079365096569131*var_147 + 0.0095238095238095246686250*var_165; + const double var_726 = var_20 + var_283; + const double var_727 = 0.0190476190476190493372499*var_205 + var_702 + 0.0025396825396825396803369*var_64; + const double var_728 = 0.0380952380952380986744998*var_48 + 0.0190476190476190493372499*var_240; + const double var_729 = var_16*var_507; + const double var_730 = 0.0306878306878306909843968*var_65*var_80; + const double var_731 = 2.4666666666666667850904560*var_211*var_7*var_8; + const double var_732 = 0.0486772486772486800976623*var_226; + const double var_733 = var_3*var_54*var_7*var_7 + var_1*var_53*var_8*var_8; + const double var_734 = 0.0317460317460317442694873*var_733; + const double var_735 = 0.2114285714285714379290226*var_55*var_7*var_8; + const double var_736 = 0.1111111111111111049432054*var_735; + const double var_737 = 0.0038095238095238095205053*var_148 + 0.1828571428571428569842539*var_15*var_219; + const double var_738 = 0.0057142857142857142807579*var_284 + 0.0533333333333333367565210*var_378; + const double var_739 = var_737 + var_738; + const double var_740 = var_143 + var_120; + const double var_741 = var_280 + var_105; + const double var_742 = var_1*var_53*var_7*var_7 + var_3*var_54*var_8*var_8; + const double var_743 = 17.0000000000000000000000000*var_7*var_8*var_87; + const double var_744 = var_743 + var_742; + const double var_745 = 0.1396825396825396858879742*var_121 + var_736 + 0.0203174603174603174426949*var_384 + 0.0355555555555555555247160*var_387 + 0.0031746031746031746004211*var_91 + 0.1612698412698412575583262*var_196 + 0.1142857142857142821457117*var_119 + 0.0342857142857142874192711*var_741 + 0.0266666666666666683782605*var_139 + 0.1066666666666666735130420*var_202 + 0.0184126984126984118150805*var_230 + var_727 + 0.0082539682539682548284565*var_744 + 0.0025396825396825396803369*var_570 + 0.0107936507936507945087934*var_117 + 0.0461375661375661369478784*var_195 + 0.0457142857142857142460635*var_75 + 0.2400000000000000188737914*var_146 + 2.0000000000000000000000000*var_739 + 0.2285714285714285642914234*var_740 + 0.0666666666666666657414808*var_731 + 0.0114285714285714285615159*var_729 + 0.1295238095238095132888390*var_372 + var_725 + 0.0753439153439153519453697*var_194 + var_527 + var_734 + 0.1104761904761904778293768*var_267 + var_732 + 0.0224338624338624344212167*var_80*var_81 + 0.0152380952380952380820212*var_726 + var_728 + 0.8000000000000000444089210*var_730 + 0.3390476190476190421208003*var_140 + var_703; + A[97] = 4.0000000000000000000000000*var_13*var_745/(var_14*var_14*var_14); + A[213] = A[97]; + A[345] = 0.0000000000000000000000000; + const double var_746 = var_1*var_39*var_8*var_8 + var_3*var_40*var_7*var_7; + const double var_747 = -var_1*w[0][10] + var_68; + const double var_748 = var_138*var_80 + var_7*var_747*var_8; + const double var_749 = var_145*var_80; + const double var_750 = var_301 + var_118*var_80 + var_748 + var_749; + const double var_751 = 2.3199999999999998401278845*var_152 + 7.8666666666666662521834041*var_129 + 5.1111111111111107163651468*var_65 + 3.5600000000000000532907052*var_61 + 3.4133333333333335524173435*var_167 + 7.7599999999999997868371793*var_223; + const double var_752 = var_25 + var_105; + const double var_753 = 0.1333333333333333314829616*var_339*var_80; + const double var_754 = 0.1022222222222222282050907*var_32; + const double var_755 = var_3*var_39 + var_1*var_40; + const double var_756 = 37.0000000000000000000000000*var_755 + 11.0000000000000000000000000*var_136; + const double var_757 = 0.1333333333333333314829616*var_752 + var_754 + 0.1682539682539682668327430*var_90 + 1.1492063492063491203509784*var_746 + var_753 + 0.5111111111111111826588171*var_91 + 0.6793650793650793939804089*var_108 + 0.4000000000000000222044605*var_185 + 0.0952380952380952328084618*var_16*var_751 + 0.2666666666666666629659233*var_75 + 0.0626455026455026431353446*var_64 + 0.1688888888888888939465716*var_23 + 0.1134391534391534506198695*var_29 + 0.1530158730158730218118279*var_117 + 0.4126984126984126755033344*var_281 + 1.0317460317460316332471848*var_178 + 0.0507936507936507936067372*var_750 + 0.3777777777777777679091287*var_282 + 0.0673015873015873067330972*var_34 + 0.0118518518518518512633309*var_79 + 0.0158730158730158721347436*var_230 + 0.0031746031746031746004211*var_7*var_756*var_8; + A[74] = 2.0000000000000000000000000*var_13*var_757/(var_14*var_14*var_14); + A[887] = A[74]; + A[258] = 0.0000000000000000000000000; + const double var_758 = var_48 + var_523; + const double var_759 = var_85 + var_4; + const double var_760 = 0.3333333333333333148296163*var_211*var_7*var_8; + const double var_761 = 0.0666666666666666657414808*var_141 + 0.4000000000000000222044605*var_142 + 0.3333333333333333148296163*var_282; + const double var_762 = 0.0234920634920634911757542*var_226 + 0.0457142857142857142460635*var_396; + const double var_763 = var_199 + var_165; + const double var_764 = var_487 + var_187; + const double var_765 = var_205 + var_235; + const double var_766 = var_240 + var_284; + const double var_767 = var_766 + var_207; + const double var_768 = 0.0400000000000000008326673*var_47 + var_81; + const double var_769 = 0.0952380952380952328084618*var_439 + 0.0126984126984126984016843*var_178; + const double var_770 = 0.0380952380952380986744998*var_103; + const double var_771 = var_770 + var_769; + const double var_772 = 0.2247619047619047738528764*var_194; + const double var_773 = 0.0869841269841269831841757*var_197 + 0.2000000000000000111022302*var_771 + 0.0825396825396825378762244*var_203 + 0.0076190476190476190410106*var_758 + 0.0514285714285714276594597*var_383 + 0.0590476190476190501699172*var_143 + 0.0711111111111111110494321*var_386 + 0.0423280423280423256926497*var_16*var_768 + 0.0082539682539682548284565*var_767 + 0.0380952380952380986744998*var_599 + 0.0152380952380952380820212*var_146 + 0.1339682539682539585967902*var_280 + 0.0019047619047619047602526*var_144 + 0.1117460317460317459348218*var_198 + 0.0571428571428571410728559*var_175 + 0.0533333333333333367565210*var_285 + 0.1746031746031745934821799*var_281 + 0.2101587301587301559457899*var_132 + 0.0793650793650793606737182*var_49*var_80 + 0.0234920634920634911757542*var_148 + 0.0044444444444444444405895*var_130 + 0.1269841269841269770779490*var_271 + 0.0831746031746031788678408*var_283 + 0.0209523809523809514954173*var_196 + 0.0615873015873015863808071*var_140 + 0.0666666666666666657414808*var_761 + 0.0158730158730158721347436*var_763 + 0.0069841269841269841209264*var_120 + 0.2349206349206349186964360*var_131 + 0.0126984126984126984016843*var_185 + 0.0143915343915343926783912*var_193 + 0.0025396825396825396803369*var_267 + 0.0495238095238095255012922*var_760 + 0.0241269841269841286979236*var_15*var_759 + 0.0730158730158730201464934*var_152*var_16 + 0.0546031746031746048619659*var_201 + 0.1523809523809523946979994*var_410 + var_762 + 0.0006349206349206349200842*var_88 + 0.0406349206349206348853897*var_147 + 0.0507936507936507936067372*var_765 + 0.0378835978835978873235923*var_195 + 0.0247619047619047627506461*var_764 + 0.3333333333333333148296163*var_772; + A[281] = 32.0000000000000000000000000*var_13*var_773/(var_14*var_14*var_14); + A[746] = A[281]; + const double var_774 = 2.6000000000000000888178420*var_209; + const double var_775 = 0.0380952380952380986744998*var_281; + const double var_776 = var_775 + var_707 + 0.0495238095238095255012922*var_34 + 0.0069841269841269841209264*var_199; + const double var_777 = 0.0380952380952380986744998*var_439 + 0.0061375661375661378499347*var_15*var_47 + 0.0209523809523809514954173*var_292; + const double var_778 = 0.0057142857142857142807579*var_314 + 0.0175661375661375664114505*var_65*var_80; + const double var_779 = var_285 + var_189; + const double var_780 = 0.0038095238095238095205053*var_117; + const double var_781 = 0.0380952380952380986744998*var_200 + var_780; + const double var_782 = 0.3714285714285714412596917*var_233 + var_24; + const double var_783 = 0.0207407407407407401445099*var_226; + const double var_784 = 0.0463492063492063482987859*var_140; + const double var_785 = 0.0533333333333333367565210*var_288; + const double var_786 = var_210 + var_141; + const double var_787 = var_229 + var_142; + const double var_788 = var_230 + var_232; + const double var_789 = var_146 + var_119; + const double var_790 = 0.4000000000000000222044605*var_79; + const double var_791 = var_790 + var_267; + const double var_792 = 0.3333333333333333148296163*var_208 + 0.5714285714285713968507707*var_21; + const double var_793 = 61.0000000000000000000000000*var_41 + 71.0000000000000000000000000*var_36 + 103.0000000000000000000000000*var_204; + const double var_794 = 101.0000000000000000000000000*var_87; + const double var_795 = 106.0000000000000000000000000*var_211 + var_794; + const double var_796 = 104.0000000000000000000000000*var_280 + 43.0000000000000000000000000*var_193 + var_7*var_795*var_8 + 75.6666666666666571927635232*var_195 + var_1*var_3*var_793 + 22.3333333333333321490954404*var_194 + 12.3333333333333321490954404*var_15*var_49 + 31.0000000000000000000000000*var_286 + 151.0000000000000000000000000*var_196 + 8.0000000000000000000000000*var_143 + 10.3333333333333321490954404*var_18 + 89.0000000000000000000000000*var_120 + 31.3333333333333321490954404*var_80*var_81 + 137.0000000000000000000000000*var_121; + const double var_797 = 0.0412698412698412689381122*var_791 + 0.1066666666666666735130420*var_779 + 0.0780952380952380925682732*var_16*var_206 + var_784 + 0.0704761904761904700578157*var_467 + 0.0285714285714285705364279*var_786 + 0.0311111111111111102167648*var_97 + 0.0698412698412698429439871*var_98 + var_778 + 0.0044444444444444444405895*var_44 + 0.0025396825396825396803369*var_197 + 0.0006349206349206349200842*var_796 + 0.1600000000000000033306691*var_792 + 0.0444444444444444461406185*var_782 + 0.0304761904761904761640423*var_788 + 0.0019047619047619047602526*var_56 + var_776 + 0.0342857142857142874192711*var_23 + 0.0228571428571428571230317*var_94 + var_781 + var_777 + 0.1447619047619047583097540*var_202 + var_783 + var_547 + var_335 + var_785 + 0.0400000000000000008326673*var_282 + 0.0685714285714285748385421*var_787 + 0.0177777777777777777623580*var_789 + var_251; + A[284] = 32.0000000000000000000000000*var_13*var_797/(var_14*var_14*var_14); + A[877] = 0.0000000000000000000000000; + const double var_798 = 0.2361904761904762006796688*var_15*var_85 + 0.5485714285714285987083372*var_125*var_15 + 1.3333333333333332593184650*var_394; + A[241] = A[38]; + const double var_799 = var_410 + var_24; + const double var_800 = 0.0780952380952380925682732*var_461 + 0.1123809523809523869264382*var_459; + const double var_801 = 0.1828571428571428569842539*var_154*var_16 + 0.0038095238095238095205053*var_33; + const double var_802 = 0.0645502645502645522324059*var_47*var_80; + const double var_803 = 0.0471957671957672006413098*var_226; + const double var_804 = 0.0520634920634920617121821*var_24; + const double var_805 = 0.3714285714285714412596917*var_58; + const double var_806 = 19.5714285714285693984493264*var_212 + 4.6666666666666660745477202*var_211; + const double var_807 = 0.0761904761904761973489997*var_202; + const double var_808 = 0.4400000000000000022204460*var_36 + 0.8171428571428571707713218*var_215 + 3.5714285714285711748061658*var_204 + 0.0285714285714285705364279*var_360; + const double var_809 = var_196 + var_411; + const double var_810 = var_144 + var_42; + const double var_811 = var_199 + var_18; + const double var_812 = 0.4857142857142857095276156*var_97 + 0.4000000000000000222044605*var_322 + var_50 + 3.5428571428571427048836995*var_280 + 1.1714285714285714856686127*var_19 + 0.0057142857142857142807579*var_64 + 4.3428571428571425272480155*var_149 + 0.7142857142857143015746146*var_98 + 1.2571428571428571174806166*var_809 + 1.0171428571428571263624008*var_197 + 0.1142857142857142821457117*var_88 + 0.6571428571428571396850771*var_66 + 0.2285714285714285642914234*var_810 + 4.5714285714285711748061658*var_9 + 0.8323809523809523325255100*var_80*var_81 + 0.2000000000000000111022302*var_811 + var_1*var_3*var_808 + 0.0571428571428571410728559*var_140 + 1.7714285714285713524418497*var_79 + 0.0285714285714285705364279*var_28 + var_772; + const double var_813 = var_535 + var_802 + 0.6952380952380953216263038*var_15*var_158 + var_803 + 0.2038095238095238015407773*var_32 + 0.2285714285714285642914234*var_34 + 0.2057142857142857106378386*var_16*var_60 + 0.0076190476190476190410106*var_500 + 2.0000000000000000000000000*var_781 + 0.3047619047619047893959987*var_288 + 0.4571428571428571285828468*var_378 + 0.1111111111111111049432054*var_812 + 0.0380952380952380986744998*var_178 + 0.0266666666666666683782605*var_7*var_8*var_806 + 0.3809523809523809312338471*var_21 + 0.0247619047619047627506461*var_56 + 0.1028571428571428553189193*var_175 + 0.0952380952380952328084618*var_198 + 0.0419047619047619029908347*var_129*var_16 + var_801 + 0.0228571428571428571230317*var_208 + var_723 + 8.0000000000000000000000000*var_807 + 0.0114285714285714285615159*var_142 + 0.0152380952380952380820212*var_141 + var_804 + 0.5333333333333333259318465*var_779 + var_805 + 0.4190476190476191131750738*var_229; + A[125] = 8.0000000000000000000000000*var_13*var_813/(var_14*var_14*var_14); + A[154] = A[125]; + const double var_814 = 5.1111111111111107163651468*var_49 + 2.3199999999999998401278845*var_110 + 3.4133333333333335524173435*var_5 + 7.8666666666666662521834041*var_118 + 3.5600000000000000532907052*var_85 + 7.7599999999999997868371793*var_125; + const double var_815 = 8.0000000000000000000000000*var_19 + var_367; + const double var_816 = 0.3714285714285714412596917*var_240; + const double var_817 = 0.0814814814814814880605809*var_74; + const double var_818 = 0.1714285714285714301574615*var_103; + const double var_819 = var_76 + var_283; + const double var_820 = 188.8000000000000113686837722*var_167 + 22.0666666666666664298190881*var_49 + 128.0000000000000000000000000*var_129 + 67.8666666666666600349344662*var_65; + const double var_821 = 20.6000000000000014210854715*var_196 + 46.0000000000000000000000000*var_281; + const double var_822 = 494.0000000000000000000000000*var_163 + 148.0000000000000000000000000*var_89 + 566.0000000000000000000000000*var_150 + 67.0000000000000000000000000*var_136; + const double var_823 = 163.0000000000000000000000000*var_282 + 76.0000000000000000000000000*var_24 + 474.3333333333333143855270464*var_47*var_80 + 551.0000000000000000000000000*var_178 + 878.0000000000000000000000000*var_23 + var_50 + 251.0000000000000000000000000*var_141 + 76.3333333333333285963817616*var_80*var_81 + 8.0000000000000000000000000*var_175 + 353.0000000000000000000000000*var_32 + 158.0000000000000000000000000*var_112 + var_7*var_8*var_822 + 286.0000000000000000000000000*var_34 + 1117.0000000000000000000000000*var_147 + 886.0000000000000000000000000*var_117; + const double var_824 = 154.3333333333333143855270464*var_29 + var_16*var_820 + 48.6666666666666642981908808*var_30 + 23.0000000000000000000000000*var_18 + 209.0000000000000000000000000*var_144 + 62.0000000000000000000000000*var_15*var_65 + 128.6666666666666571927635232*var_64 + 0.2000000000000000111022302*var_823 + var_821; + const double var_825 = var_817 + var_818 + 0.0495238095238095255012922*var_153 + 0.1561904761904761851365464*var_1*var_216*var_3 + 0.3676190476190476230655690*var_9 + 0.0419047619047619029908347*var_233 + var_634 + 1.0857142857142856318120039*var_149 + 0.3714285714285714412596917*var_265 + 0.0152380952380952380820212*var_819 + 0.0038095238095238095205053*var_20 + 0.3542857142857142593861397*var_105 + 0.1504761904761904856009380*var_185 + 0.1485714285714285765038767*var_205 + 0.1638095238095238215247917*var_280 + 0.0076190476190476190410106*var_267 + 0.2057142857142857106378386*var_15*var_85 + 0.0457142857142857142460635*var_155 + 0.2361904761904762006796688*var_22 + 0.2628571428571428447718006*var_142 + var_816 + 0.1676190476190476119633388*var_148 + 0.0031746031746031746004211*var_824 + 0.0914285714285714284921269*var_75 + 0.8857142857142856762209249*var_164 + 0.0304761904761904761640423*var_815 + 0.0228571428571428571230317*var_378 + 0.1961904761904761929081076*var_235; + A[187] = 8.0000000000000000000000000*var_13*var_825/(var_14*var_14*var_14); + const double var_826 = var_321 + var_367; + const double var_827 = 292.3333333333333143855270464*var_163 + 24.3333333333333321490954404*var_136 + 354.0000000000000000000000000*var_212 + 183.6666666666666571927635232*var_89 + 244.3333333333333143855270464*var_114; + const double var_828 = var_378 + var_257; + const double var_829 = 0.5142857142857142349612332*var_396; + const double var_830 = 0.1676190476190476119633388*var_1*var_217*var_3 + var_829; + const double var_831 = var_159 + var_236; + const double var_832 = 0.1523809523809523946979994*var_283 + 0.1714285714285714301574615*var_285; + const double var_833 = var_50 + var_18; + const double var_834 = 0.0215873015873015890175868*var_833; + const double var_835 = 0.0520634920634920617121821*var_74; + const double var_836 = 17.0000000000000000000000000*var_1*var_204*var_3; + const double var_837 = var_280 + var_98; + const double var_838 = 14.6666666666666660745477202*var_49 + 61.0000000000000000000000000*var_60 + 30.6666666666666642981908808*var_65; + const double var_839 = 0.0590476190476190501699172*var_32 + 0.0038095238095238095205053*var_16*var_838 + 0.4000000000000000222044605*var_832 + 0.1504761904761904856009380*var_91 + 1.9885714285714286564399345*var_200 + var_834 + 0.6266666666666667051543982*var_175 + 0.5371428571428571441259692*var_198 + var_246 + 1.1885714285714286120310135*var_197 + 1.0666666666666666518636930*var_828 + 0.0647619047619047566444195*var_836 + 1.3333333333333332593184650*var_450 + 0.0863492063492063560703471*var_64 + 0.1847619047619047660813152*var_282 + 1.0057142857142857828023352*var_19 + 0.0190476190476190493372499*var_235 + 2.0380952380952384039858316*var_22 + 1.9047619047619046561692357*var_149 + 0.5790476190476190332390161*var_199 + 0.0800000000000000016653345*var_131 + 0.0088888888888888888811790*var_301 + 1.8285714285714285143313873*var_618 + 0.2476190476190476552620368*var_766 + 1.0323809523809523991388915*var_1*var_101*var_3 + 1.3523809523809524613113808*var_21 + 1.7142857142857141905523122*var_144 + 1.4095238095238096232009184*var_97 + 0.1384126984126984039047414*var_29 + 0.0057142857142857142807579*var_7*var_8*var_827 + 0.6730158730158730673309719*var_831 + 1.2000000000000001776356839*var_108 + 0.2895238095238095166195080*var_130 + 0.0895238095238095193950656*var_117 + 1.1619047619047619956944573*var_837 + 1.6571428571428570286627746*var_9 + 0.2514285714285714457005838*var_155 + var_835 + 0.0438095238095238120878960*var_178 + 0.2590476190476190265776779*var_234 + 0.7314285714285714279370154*var_132 + 0.3238095238095238248554608*var_281 + var_447 + 4.0000000000000000000000000*var_830 + 0.6400000000000000133226763*var_826; + A[127] = var_13*var_839/(var_14*var_14*var_14); + A[592] = A[127]; + A[255] = 0.0000000000000000000000000; + A[515] = 0.0000000000000000000000000; + const double var_840 = var_143 + var_201; + const double var_841 = var_840 + var_326; + A[673] = 0.0000000000000000000000000; + A[612] = 0.0000000000000000000000000; + A[804] = A[281]; + const double var_842 = var_3*var_3*var_8*var_93 + var_1*var_1*var_7*var_92; + const double var_843 = var_1*var_1*var_8*var_93 + var_3*var_3*var_7*var_92; + const double var_844 = 0.0317460317460317442694873*var_843; + const double var_845 = 0.0266666666666666683782605*var_84 + 0.0076190476190476190410106*var_15*var_440 + 0.0139682539682539682418527*var_30 + 0.0273015873015873024309830*var_1*var_161*var_3 + 0.0044444444444444444405895*var_842 + var_844; + const double var_846 = 0.0292063492063492080585974*var_22 + 0.0457142857142857142460635*var_234 + 0.0158730158730158721347436*var_46 + 0.0025396825396825396803369*var_287 + 0.0165079365079365096569131*var_31 + 0.0006349206349206349200842*var_28 + 0.0095238095238095246686250*var_156; + const double var_847 = var_235 + var_308; + const double var_848 = var_253 + var_301; + const double var_849 = 0.3333333333333333148296163*var_848 + var_131; + const double var_850 = 0.0457142857142857142460635*var_77 + 0.0152380952380952380820212*var_74; + const double var_851 = 0.0006349206349206349200842*var_199; + const double var_852 = 0.0266666666666666683782605*var_117 + 0.0044444444444444444405895*var_139; + const double var_853 = 0.0228571428571428571230317*var_91; + const double var_854 = 17.0000000000000000000000000*var_1*var_217*var_3; + const double var_855 = var_112 + var_367; + const double var_856 = var_106 + var_198; + const double var_857 = var_203 + 0.3333333333333333148296163*var_59; + const double var_858 = var_175 + var_857; + const double var_859 = 0.0380952380952380986744998*var_25; + const double var_860 = var_846 + 0.0260317460317460308560911*var_1*var_101*var_3 + 0.0469841269841269823515084*var_163*var_7*var_8 + 0.0063492063492063492008421*var_855 + 0.0317460317460317442694873*var_29 + 0.0190476190476190493372499*var_151 + 0.0038095238095238095205053*var_856 + 0.0031746031746031746004211*var_19 + var_845 + 0.0050793650793650793606737*var_321 + 0.0076190476190476190410106*var_849 + 0.0114285714285714285615159*var_858 + 0.0673015873015873067330972*var_108 + 0.0006349206349206349200842*var_854 + 0.0419047619047619029908347*var_147 + 0.2857142857142856984253854*var_852 + 0.0165079365079365096569131*var_67 + var_850 + 0.0152380952380952380820212*var_847 + 0.0069841269841269841209264*var_44 + 0.0228571428571428571230317*var_178 + var_853 + var_313 + 0.0698412698412698429439871*var_144 + 0.0444444444444444461406185*var_90 + var_512 + 0.0101587301587301587213474*var_132 + var_851 + var_859; + A[159] = 16.0000000000000000000000000*var_13*var_860/(var_14*var_14*var_14); + const double var_861 = var_203 + var_90; + const double var_862 = 4.6666666666666660745477202*var_215 + 19.5714285714285693984493264*var_216; + const double var_863 = 0.4888888888888889283634853*var_108; + A[174] = 0.0000000000000000000000000; + const double var_864 = var_506 + var_523 + var_129*var_80 + var_510; + const double var_865 = var_103 + var_38; + const double var_866 = 0.1022222222222222282050907*var_9; + const double var_867 = 37.0000000000000000000000000*var_425 + 11.0000000000000000000000000*var_41; + const double var_868 = 0.1333333333333333314829616*var_865 + 0.4000000000000000222044605*var_52 + 0.3777777777777777679091287*var_97 + 0.0507936507936507936067372*var_864 + 0.5111111111111111826588171*var_20 + 0.0952380952380952328084618*var_15*var_814 + 0.6793650793650793939804089*var_112 + 0.0158730158730158721347436*var_102 + var_866 + 0.2666666666666666629659233*var_76 + 0.1530158730158730218118279*var_19 + var_428 + 0.1688888888888888939465716*var_22 + 0.4126984126984126755033344*var_98 + 0.0673015873015873067330972*var_149 + 0.1134391534391534506198695*var_30 + 0.1682539682539682668327430*var_44 + 1.0317460317460316332471848*var_28 + 1.1492063492063491203509784*var_424 + 0.0626455026455026431353446*var_18 + 0.0118518518518518512633309*var_159 + 0.0031746031746031746004211*var_1*var_3*var_867; + A[43] = 2.0000000000000000000000000*var_13*var_868/(var_14*var_14*var_14); + A[856] = A[43]; + const double var_869 = var_466 + var_840; + A[460] = 0.0000000000000000000000000; + const double var_870 = var_439 + var_202; + A[482] = 0.0000000000000000000000000; + A[572] = 0.0000000000000000000000000; + A[513] = 0.0000000000000000000000000; + const double var_871 = var_286 + var_193; + const double var_872 = var_208 + var_232; + const double var_873 = var_200 + 2.0000000000000000000000000*var_212*var_7*var_8; + const double var_874 = var_153 + var_410; + const double var_875 = 0.0526984126984126957649046*var_226; + const double var_876 = 0.1142857142857142821457117*var_98; + const double var_877 = 0.0704761904761904700578157*var_321; + const double var_878 = var_149 + var_257; + const double var_879 = var_94 + var_88; + const double var_880 = var_117 + var_42; + const double var_881 = var_467 + var_207; + const double var_882 = var_199 + var_881; + const double var_883 = 2.4666666666666667850904560*var_1*var_215*var_3; + const double var_884 = var_203 + var_883; + const double var_885 = 0.0247619047619047627506461*var_19 + 0.0171428571428571437096355*var_836 + 0.0241269841269841286979236*var_139 + 0.2380952380952380820211545*var_874 + var_877 + 0.1085714285714285687323155*var_97 + 0.0196825396825396833899724*var_47*var_80 + 0.0692063492063492019523707*var_195 + 0.2952380952380952439106920*var_131 + var_830 + 0.0400000000000000008326673*var_882 + 0.1466666666666666674068153*var_378 + 0.0076190476190476190410106*var_121 + 0.1809523809523809756427681*var_197 + 0.0761904761904761973489997*var_381 + 0.0609523809523809523280846*var_9 + 0.0768253968253968244628282*var_194 + 0.0495238095238095255012922*var_140 + 0.5428571428571428159060019*var_761 + 0.0038095238095238095205053*var_879 + 0.9142857142857142571656937*var_392 + 0.0546031746031746048619659*var_15*var_81 + 0.1333333333333333314829616*var_198 + 0.0165079365079365096569131*var_871 + var_875 + 0.0120634920634920643489618*var_159 + 0.3047619047619047893959987*var_132 + 0.4190476190476191131750738*var_281 + 0.1580952380952380942336077*var_229 + 0.1371428571428571496770843*var_283 + 0.1123809523809523869264382*var_196 + 0.0793650793650793606737182*var_848 + var_876 + 0.0742857142857142882519383*var_267 + var_111 + 0.4285714285714285476380780*var_280 + 0.1485714285714285765038767*var_873 + 0.0552380952380952389146884*var_878 + 0.0095238095238095246686250*var_872 + 0.1009523809523809462218580*var_15*var_186 + 0.1390476190476190587741456*var_174*var_7*var_8 + 0.1619047619047619124277304*var_21 + var_679 + 0.0057142857142857142807579*var_880 + 0.0571428571428571410728559*var_884; + A[403] = 64.0000000000000000000000000*var_13*var_885/(var_14*var_14*var_14); + A[868] = A[403]; + const double var_886 = 1.6857142857142857206298459*var_125; + const double var_887 = 1.6857142857142857206298459*var_223; + const double var_888 = var_206 + var_145; + const double var_889 = var_222 + var_186; + const double var_890 = var_110 + var_152; + const double var_891 = 1.5976190476190477163243031*var_622 + var_887 + 0.5103174603174602808053351*var_576 + 4.1388888888888883954564335*var_478 + 3.2833333333333332149095440*var_598 + var_886 + 5.9166666666666660745477202*var_890 + 1.1000000000000000888178420*var_888 + 4.7285714285714286475581503*var_889; + A[32] = 0.0333333333333333328707404*var_13*var_80*var_891/(var_14*var_14*var_14); + A[61] = A[32]; + A[661] = 0.0000000000000000000000000; + A[540] = 0.0000000000000000000000000; + const double var_892 = 181.0000000000000000000000000*var_211 + 311.0000000000000000000000000*var_136 + 239.0000000000000000000000000*var_115 + var_794; + const double var_893 = 0.1428571428571428492126927*var_153 + 0.0666666666666666657414808*var_253; + const double var_894 = 0.6666666666666666296592325*var_893; + const double var_895 = 0.2698412698412698262906417*var_81 + 9.7142857142857135244184974*var_219 + 5.0476190476190474498707772*var_209 + 4.6666666666666660745477202*var_6; + const double var_896 = 0.0393650793650793667799448*var_65*var_80; + const double var_897 = var_97 + var_284 + var_75; + const double var_898 = 20.6666666666666642981908808*var_60 + 5.8888888888888883954564335*var_65 + 27.3333333333333321490954404*var_169 + 48.0000000000000000000000000*var_154; + const double var_899 = 27.0000000000000000000000000*var_204 + 23.0000000000000000000000000*var_216; + const double var_900 = var_207 + var_21; + const double var_901 = var_44 + var_821; + const double var_902 = 0.1180952380952381003398344*var_197 + var_417 + 0.0800000000000000016653345*var_15*var_895 + 0.0076190476190476190410106*var_30 + 0.4000000000000000222044605*var_657 + 0.0990476190476190510025845*var_130 + 0.0228571428571428571230317*var_1*var_3*var_899 + var_242 + 0.0266666666666666683782605*var_120 + 0.0736507936507936472603220*var_193 + 0.0685714285714285748385421*var_897 + 0.0114285714285714285615159*var_16*var_898 + var_896 + var_503 + 0.0723809523809523791548770*var_363 + 0.1371428571428571496770843*var_199 + var_430 + 0.1790476190476190387901312*var_121 + 0.1485714285714285765038767*var_23 + 0.2057142857142857106378386*var_200 + 0.1384126984126984039047414*var_49*var_80 + 0.1993650793650793562328261*var_18 + 0.1980952380952381020051689*var_22 + 0.3200000000000000066613381*var_283 + 0.2838095238095237893283240*var_282 + 0.0133333333333333341891302*var_178 + 0.0914285714285714284921269*var_102 + 0.0190476190476190493372499*var_901 + 2.0000000000000000000000000*var_894 + 0.9142857142857142571656937*var_131 + 0.3314285714285714057325549*var_142 + 0.0019047619047619047602526*var_7*var_8*var_892 + 0.3066666666666666984930600*var_201 + 0.0952380952380952328084618*var_146 + 0.9371428571428571663304297*var_280 + 0.0419047619047619029908347*var_900 + 0.7314285714285714279370154*var_202 + 0.0552380952380952389146884*var_229 + 0.2476190476190476552620368*var_132 + 0.2653968253968254087382661*var_195 + 0.3219047619047619157583995*var_203; + A[734] = 0.0000000000000000000000000; + A[282] = 32.0000000000000000000000000*var_13*var_276/(var_14*var_14*var_14); + A[792] = 0.0000000000000000000000000; + const double var_903 = 33.4761904761904744987077720*var_41 + 9.8666666666666671403618238*var_45 + 6.0380952380952388480750415*var_214 + 3.8285714285714282922867824*var_37 + 1.4095238095238096232009184*var_43; + const double var_904 = 0.5714285714285713968507707*var_396 + 0.1022222222222222282050907*var_226; + const double var_905 = 0.8000000000000000444089210*var_33 + var_35; + const double var_906 = 0.1295238095238095132888390*var_20; + const double var_907 = 331.0000000000000000000000000*var_211 + 1889.0000000000000000000000000*var_87; + const double var_908 = 1.5238095238095237249353886*var_52 + var_904 + 0.4647619047619047649710922*var_19 + 0.4723809523809524013593375*var_367 + 2.1142857142857143237790751*var_881 + 0.1225396825396825456477856*var_139 + 2.0171428571428573484070057*var_201 + 1.0419047619047618891130469*var_16*var_62 + 0.2361904761904762006796688*var_28 + 0.8685714285714285498585241*var_857 + 5.4380952380952383151679896*var_21 + 6.6571428571428565845735648*var_121 + var_772 + 0.9447619047619048027186750*var_91 + 0.1828571428571428569842539*var_24 + 8.1619047619047631059174819*var_98 + 0.0419047619047619029908347*var_487 + 0.4114285714285714212756773*var_112 + 4.0000000000000000000000000*var_495 + 0.3142857142857142793701541*var_108 + 0.7428571428571428825193834*var_140 + var_176 + 7.7142857142857135244184974*var_120 + 0.4374603174603174382539805*var_848 + 2.2095238095238096676098394*var_31 + 0.0533333333333333367565210*var_271 + 0.2000000000000000111022302*var_1*var_3*var_903 + 2.1028571428571427581744047*var_25 + 1.0190476190476192019929158*var_146 + 2.3790476190476188556033321*var_229 + 1.6063492063492064154672789*var_15*var_47 + 1.4666666666666665630458510*var_97 + 0.0019047619047619047602526*var_7*var_8*var_907 + 1.3371428571428571885348902*var_873 + 0.4273015873015872934104209*var_15*var_81 + 3.0698412698412700372330164*var_65*var_80 + var_906 + 0.5790476190476190332390161*var_131 + 1.6882539682539683401074626*var_195 + 1.4476190476190478051421451*var_905 + 0.7619047619047618624676943*var_257 + 1.5860317460317461257801597*var_871 + 2.3123809523809524257842440*var_198 + 3.0590476190476190154754477*var_94 + 3.9333333333333331260917021*var_292; + A[217] = 2.0000000000000000000000000*var_13*var_908/(var_14*var_14*var_14); + const double var_909 = var_44 + var_146; + A[419] = 0.0000000000000000000000000; + A[781] = 0.0000000000000000000000000; + const double var_910 = 29.6666666666666642981908808*var_214 + 92.3333333333333285963817616*var_217 + 74.3333333333333285963817616*var_204 + 104.0000000000000000000000000*var_216; + const double var_911 = 0.0095238095238095246686250*var_292 + 0.0052910052910052907115812*var_159; + const double var_912 = 0.0723809523809523791548770*var_201 + 0.0019047619047619047602526*var_130; + const double var_913 = 0.0552380952380952389146884*var_15*var_209; + const double var_914 = 0.1968253968253968200219362*var_197; + const double var_915 = var_66 + var_120; + const double var_916 = var_321 + var_533; + const double var_917 = var_408 + var_42; + const double var_918 = var_411 + var_386; + const double var_919 = 0.5904761904761904878213841*var_352 + 0.0019047619047619047602526*var_1*var_3*var_910 + 0.0012698412698412698401684*var_90 + 0.2476190476190476552620368*var_281 + 0.2488888888888888817341183*var_132 + 0.0234920634920634911757542*var_193 + 0.0507936507936507936067372*var_98 + var_784 + var_379 + 0.2000000000000000111022302*var_802 + 0.0031746031746031746004211*var_915 + 0.1676190476190476119633388*var_174*var_7*var_8 + 0.0082539682539682548284565*var_917 + 0.0742857142857142882519383*var_282 + 0.0730158730158730201464934*var_283 + var_914 + 0.0158730158730158721347436*var_196 + 0.0584126984126984161171947*var_15*var_186 + 0.0869841269841269831841757*var_199 + 0.1066666666666666735130420*var_10 + 0.0647619047619047566444195*var_235 + 0.0101587301587301587213474*var_19 + 0.0266666666666666683782605*var_232 + 0.0264550264550264535579061*var_15*var_81 + 0.2146031746031746012537411*var_280 + 0.0247619047619047627506461*var_207 + 0.2666666666666666629659233*var_131 + 0.0171428571428571437096355*var_141 + var_397 + var_894 + 0.0914285714285714284921269*var_400 + 0.0933333333333333375891883*var_203 + 0.0425396825396825370435572*var_97 + 0.0685714285714285748385421*var_184*var_80 + 0.2400000000000000188737914*var_198 + var_913 + 0.0215873015873015890175868*var_916 + var_912 + 0.0103703703703703700722549*var_18 + 0.0273015873015873024309830*var_222*var_80 + var_911 + 0.1098412698412698368377605*var_918 + 0.1295238095238095132888390*var_399 + 0.1733333333333333392545228*var_410; + A[283] = 32.0000000000000000000000000*var_13*var_919/(var_14*var_14*var_14); + A[399] = A[283]; + const double var_920 = 16.0000000000000000000000000*var_9 + var_234; + const double var_921 = 2.8888888888888888395456433*var_101 + 3.3555555555555556246360993*var_41 + 0.5777777777777778345225101*var_217 + 3.6000000000000000888178420*var_37; + const double var_922 = 0.0400000000000000008326673*var_292 + 0.0114285714285714285615159*var_48; + const double var_923 = 0.0368253968253968236301610*var_16*var_47; + const double var_924 = 0.0507936507936507936067372*var_112; + const double var_925 = 0.0342857142857142874192711*var_126; + const double var_926 = 89.0000000000000000000000000*var_163; + const double var_927 = 113.0000000000000000000000000*var_114 + var_926; + const double var_928 = var_321 + var_257; + const double var_929 = var_253 + var_287; + const double var_930 = var_44 + var_905; + const double var_931 = var_207 + var_198; + const double var_932 = var_143 + var_20; + const double var_933 = 0.0228571428571428571230317*var_25; + const double var_934 = 2.6666666666666665186369300*var_933 + var_924 + 0.0076190476190476190410106*var_518 + 0.1089947089947090053119183*var_195 + 0.0666666666666666657414808*var_139 + 0.1841269841269841389674866*var_931 + var_922 + 0.0476190476190476164042309*var_208 + 0.0203174603174603174426949*var_46 + 0.0112169312169312172106084*var_49*var_80 + 0.1142857142857142821457117*var_928 + 0.0444444444444444461406185*var_22 + 0.0279365079365079364837054*var_31 + 0.0486772486772486800976623*var_194 + 0.1428571428571428492126927*var_108 + 0.0685714285714285748385421*var_546 + 0.0939682539682539647030168*var_16*var_222 + 0.1066666666666666735130420*var_76 + 0.0133333333333333341891302*var_144 + 0.1149206349206349231373281*var_21 + 0.0285714285714285705364279*var_1*var_3*var_921 + 0.0025396825396825396803369*var_56 + 0.1269841269841269770779490*var_193 + 0.1301587301587301681582431*var_98 + var_925 + var_529 + var_778 + 0.0171428571428571437096355*var_9 + 0.0209523809523809514954173*var_929 + 0.0380952380952380986744998*var_932 + 0.3333333333333333148296163*var_685 + var_689 + 0.1873015873015873022922051*var_201 + 0.0920634920634920694837433*var_90 + 0.0088888888888888888811790*var_132 + 0.0342857142857142874192711*var_97 + 0.0812698412698412697707795*var_203 + 0.0126984126984126984016843*var_930 + 0.0228571428571428571230317*var_52 + var_923 + 0.0031746031746031746004211*var_230 + 0.0431746031746031780351736*var_94 + 0.0507936507936507936067372*var_91 + 0.0006349206349206349200842*var_7*var_8*var_927; + A[186] = 32.0000000000000000000000000*var_13*var_934/(var_14*var_14*var_14); + const double var_935 = 1.4333333333333333481363070*var_136 + 34.2333333333333342807236477*var_89 + 88.9666666666666685614472954*var_163 + 17.0000000000000000000000000*var_104 + 14.7666666666666657192763523*var_150 + 2.2333333333333333925452280*var_115; + const double var_936 = 1.2182539682539681447082103*var_91 + 1.5984126984126985071554827*var_131 + 1.3809523809523809312338471*var_82 + 0.4174603174603174760015634*var_23 + 0.2582010582010582089296236*var_64 + 2.7341269841269841833764076*var_178 + 1.3650793650793651146102548*var_281 + 1.4277777777777778123180497*var_203 + var_16*var_720 + var_421*var_80 + 5.2936507936507934957148791*var_108 + 1.1944444444444444197728217*var_282 + 4.4920634920634920916882038*var_147 + 1.1312169312169313428739770*var_29 + 0.1515873015873015761112441*var_117 + 13.3253968253968242407836442*var_144 + 2.0476190476190474498707772*var_75 + 0.0238095238095238082021154*var_25; + const double var_937 = 0.0238095238095238082021154*var_7*var_8*var_935 + 0.1746031746031745934821799*var_748 + 0.2000000000000000111022302*var_936; + A[64] = var_13*var_937/(var_14*var_14*var_14); + const double var_938 = 0.2169312169312169191748296*var_49 + 0.1269841269841269770779490*var_152; + const double var_939 = 1.5396825396825395415589810*var_169 + 1.5767195767195767430735032*var_47 + var_938 + 2.3492063492063492979866624*var_206 + 3.5555555555555553581825734*var_222 + 4.5714285714285711748061658*var_154 + 3.0317460317460316332471848*var_60; + const double var_940 = 71.0000000000000000000000000*var_89 + 3.6666666666666665186369300*var_174 + 12.3333333333333321490954404*var_136 + var_926; + const double var_941 = var_24 + var_144; + const double var_942 = var_271 + var_88; + const double var_943 = var_121 + var_132; + const double var_944 = var_48 + var_253; + const double var_945 = var_267 + var_175; + const double var_946 = var_301 + var_523; + const double var_947 = 4.0857142857142854097673990*var_464 + 0.1676190476190476119633388*var_468 + 3.8057142857142856051666513*var_465 + 3.9333333333333331260917021*var_463 + 1.1714285714285714856686127*var_460 + 0.6171428571428571041579403*var_942 + 2.9142857142857141461433912*var_458 + 0.7619047619047618624676943*var_461 + 3.6380952380952384928036736*var_601 + 0.1428571428571428492126927*var_946 + 2.4666666666666667850904560*var_606 + 0.4171428571428571485668613*var_226 + 3.0285714285714284699224663*var_459 + 7.4285714285714279370154145*var_396 + 0.9142857142857142571656937*var_943 + 0.4723809523809524013593375*var_466 + 2.2857142857142855874030829*var_602 + 1.2876190476190476630335979*var_840 + 0.7085714285714285187722794*var_326 + 0.4273015873015872934104209*var_462 + 0.8914285714285714590232601*var_457 + 2.7314285714285713169147130*var_324 + 1.0742857142857142882519383*var_945 + 0.2971428571428571530077534*var_613 + 2.3619047619047619512855363*var_609 + 1.6063492063492064154672789*var_944 + 3.6228571428571427759379731*var_325 + 1.6000000000000000888178420*var_615 + 1.5238095238095237249353886*var_600 + 0.1225396825396825456477856*var_472 + 2.0000000000000000000000000*var_484; + A[124] = 2.0000000000000000000000000*var_13*var_947/(var_14*var_14*var_14); + A[589] = A[124]; + const double var_948 = var_476 + var_471; + const double var_949 = 0.0419047619047619029908347*var_105; + const double var_950 = 113.0000000000000000000000000*var_55 + 121.0000000000000000000000000*var_115; + const double var_951 = 61.0000000000000000000000000*var_154 + var_590 + 20.6666666666666642981908808*var_222; + const double var_952 = var_207 + var_186*var_80 + var_411; + const double var_953 = 0.0076190476190476190410106*var_16*var_951 + 0.1587301587301587213474363*var_196 + var_949 + 0.0660317460317460386276522*var_749 + 0.0380952380952380986744998*var_75 + 0.1365079365079364948076801*var_201 + 0.3504761904761904967031683*var_58 + 0.1053968253968253915298092*var_34 + 0.0846560846560846513852994*var_286 + 0.0440211640211640234388035*var_193 + var_444 + 0.0336507936507936533665486*var_32 + 0.0050793650793650793606737*var_748 + 0.1168253968253968322343894*var_952 + 0.1288888888888888861750104*var_141 + 0.1968253968253968200219362*var_35 + 0.0596825396825396842226397*var_198 + 0.0558730158730158729674109*var_80*var_81 + 0.1250793650793650679808877*var_33 + 0.1485714285714285765038767*var_235 + 0.3161904761904761884672155*var_232 + 0.0298412698412698421113198*var_381 + var_631 + 0.0006349206349206349200842*var_7*var_8*var_950; + A[73] = 2.0000000000000000000000000*var_13*var_953/(var_14*var_14*var_14); + const double var_954 = 0.2603174603174603363164863*var_35; + const double var_955 = 62.0000000000000000000000000*var_223 + 29.0000000000000000000000000*var_184 + 4.2222222222222223209087133*var_47 + 10.6666666666666660745477202*var_167; + const double var_956 = var_148 + var_52; + const double var_957 = 0.0082539682539682548284565*var_178; + const double var_958 = 0.0050793650793650793606737*var_130; + const double var_959 = 0.0457142857142857142460635*var_119; + const double var_960 = 0.2038095238095238015407773*var_1*var_3*var_45; + const double var_961 = var_634 + var_960; + const double var_962 = var_284 + var_287; + const double var_963 = 0.1066666666666666735130420*var_257 + 0.0516402116402116390103672*var_523 + 0.0808465608465608470689645*var_29 + 2.0000000000000000000000000*var_961 + 0.0869841269841269831841757*var_117 + var_906 + 0.1257142857142857228502919*var_208 + 0.0920634920634920694837433*var_32 + 0.0793650793650793606737182*var_91 + 0.3885714285714285676220925*var_103 + 0.0114285714285714285615159*var_9 + var_728 + 0.9904761904761906210481470*var_76 + 0.3339682539682539696990204*var_23 + 0.0194708994708994720390649*var_64 + 0.0038095238095238095205053*var_16*var_955 + 0.2247619047619047738528764*var_25 + 0.8380952380952382263501477*var_75 + 0.2857142857142856984253854*var_22 + var_958 + 0.0419047619047619029908347*var_18 + 0.0914285714285714284921269*var_19 + 0.0380952380952380986744998*var_149 + var_959 + 0.1453968253968253854235826*var_33 + 0.6019047619047619424037521*var_1*var_3*var_37 + var_309 + 0.1574603174603174671197792*var_24 + var_957 + 0.1032804232804232780207343*var_30 + 0.2590476190476190265776779*var_956 + 0.1142857142857142821457117*var_233 + 0.2196825396825396736755209*var_108 + 0.1942857142857142838110462*var_102 + 0.3225396825396825151166524*var_112 + 0.0266666666666666683782605*var_962 + 0.0304761904761904761640423*var_28 + 0.0355555555555555555247160*var_144 + var_320 + 0.4380952380952381486345359*var_31 + 0.3746031746031746045844102*var_147 + 0.1428571428571428492126927*var_165 + 0.0006349206349206349200842*var_621*var_7*var_8 + 0.0012698412698412698401684*var_533 + var_954 + 0.2069841269841269926210714*var_34 + 0.6133333333333333969861201*var_105; + const double var_964 = 183.6666666666666571927635232*var_43 + 244.3333333333333143855270464*var_204 + 24.3333333333333321490954404*var_41 + 292.3333333333333143855270464*var_36 + 354.0000000000000000000000000*var_216; + const double var_965 = 0.1676190476190476119633388*var_7*var_8*var_87 + var_829; + const double var_966 = 0.1523809523809523946979994*var_94 + 0.1714285714285714301574615*var_439; + const double var_967 = 0.0736507936507936472603220*var_29; + const double var_968 = 0.0215873015873015890175868*var_67; + const double var_969 = 17.0000000000000000000000000*var_114*var_7*var_8; + const double var_970 = var_281 + var_21; + const double var_971 = 14.6666666666666660745477202*var_65 + 30.6666666666666642981908808*var_49 + 61.0000000000000000000000000*var_4; + const double var_972 = 0.0438095238095238120878960*var_28 + 0.1847619047619047660813152*var_97 + 0.2895238095238095166195080*var_119 + 0.0038095238095238095205053*var_15*var_971 + 0.2514285714285714457005838*var_288 + 0.0863492063492063560703471*var_18 + 1.0323809523809523991388915*var_115*var_7*var_8 + 0.5790476190476190332390161*var_141 + 1.6571428571428570286627746*var_32 + 1.0666666666666666518636930*var_872 + 0.6730158730158730673309719*var_83 + 1.0057142857142857828023352*var_117 + 0.3238095238095238248554608*var_98 + 1.3523809523809524613113808*var_280 + 1.1619047619047619956944573*var_970 + 0.2476190476190476552620368*var_59 + 2.0380952380952384039858316*var_23 + 0.7314285714285714279370154*var_121 + 0.5371428571428571441259692*var_140 + 0.0800000000000000016653345*var_120 + var_967 + 0.0190476190476190493372499*var_210 + 1.9885714285714286564399345*var_142 + 0.0647619047619047566444195*var_969 + 4.0000000000000000000000000*var_965 + 1.9047619047619046561692357*var_34 + 0.0057142857142857142807579*var_1*var_3*var_964 + 0.6266666666666667051543982*var_267 + 1.8285714285714285143313873*var_760 + 0.0088888888888888888811790*var_523 + var_835 + 0.0590476190476190501699172*var_9 + 0.1504761904761904856009380*var_20 + 1.2000000000000001776356839*var_112 + 0.2590476190476190265776779*var_233 + 1.3333333333333332593184650*var_525 + 0.0895238095238095193950656*var_19 + 1.1885714285714286120310135*var_196 + 1.4095238095238096232009184*var_282 + 0.4000000000000000222044605*var_966 + 0.6400000000000000133226763*var_881 + var_522 + 0.1384126984126984039047414*var_30 + 1.7142857142857141905523122*var_24 + var_968; + const double var_973 = 229.6666666666666571927635232*var_211 + 302.0000000000000000000000000*var_212 + 390.3333333333333143855270464*var_87; + const double var_974 = var_280 + var_52; + const double var_975 = 0.3333333333333333148296163*var_386 + 44.6666666666666642981908808*var_24 + 59.0000000000000000000000000*var_282 + 508.0000000000000000000000000*var_189 + 77.6666666666666571927635232*var_97 + 32.3333333333333285963817616*var_199 + 241.0000000000000000000000000*var_146 + 191.7777777777777714618423488*var_65*var_80 + 9.5555555555555553581825734*var_80*var_81 + 206.0000000000000000000000000*var_142 + 7.3333333333333330372738601*var_34 + var_410 + 16.0000000000000000000000000*var_233 + 539.3333333333332575421081856*var_121 + 179.3333333333333143855270464*var_15*var_209 + 0.4444444444444444197728217*var_50 + var_7*var_8*var_973 + 97.0000000000000000000000000*var_175 + 131.0000000000000000000000000*var_143 + 27.3333333333333321490954404*var_974 + 149.0000000000000000000000000*var_94; + A[633] = 0.0000000000000000000000000; + A[110] = 0.0000000000000000000000000; + A[303] = A[100]; + A[584] = 0.0000000000000000000000000; + const double var_976 = var_613 + var_463 + var_458 + var_461; + const double var_977 = var_25 + 2.0000000000000000000000000*var_38; + const double var_978 = var_106 + var_977 + var_469; + const double var_979 = var_468 + var_606; + const double var_980 = var_472 + var_944; + const double var_981 = var_459 + var_464; + const double var_982 = var_460 + var_324; + const double var_983 = 3.7809523809523812865052150*var_457 + 1.7543650793650793495714879*var_943 + 1.8904761904761906432526075*var_869 + 0.0230158730158730173709358*var_982 + 0.2138888888888889061590248*var_980 + 1.7428571428571428825193834*var_942 + 0.8944444444444444863862032*var_601 + 0.4277777777777778123180497*var_946 + 2.4658730158730159942592763*var_226 + 0.0345238095238095260564037*var_981 + 0.6134920634920635329478955*var_480 + 0.3067460317460317664739478*var_948 + 0.8857142857142856762209249*var_77 + 0.8714285714285714412596917*var_979 + 0.0115079365079365086854679*var_976 + 3.6988095238095239913889145*var_593 + 1.2769841269841268882601071*var_609 + 3.4742063492063488538974525*var_615 + 0.2952380952380952439106920*var_978; + A[0] = var_13*var_983/(var_14*var_14*var_14); + A[465] = A[0]; + const double var_984 = 4.7285714285714286475581503*var_167 + var_887 + 1.5976190476190477163243031*var_60 + 1.1000000000000000888178420*var_129 + 5.9166666666666660745477202*var_57 + 3.2833333333333332149095440*var_61; + const double var_985 = 0.1523809523809523946979994*var_208 + 0.0285714285714285705364279*var_164; + const double var_986 = 0.0520634920634920617121821*var_144; + const double var_987 = 0.4400000000000000022204460*var_163 + 0.8171428571428571707713218*var_211 + 3.5714285714285711748061658*var_114 + 0.0285714285714285705364279*var_376; + const double var_988 = var_197 + var_408; + const double var_989 = var_64 + var_141; + const double var_990 = 0.2247619047619047738528764*var_195; + const double var_991 = 0.2285714285714285642914234*var_799 + 0.4000000000000000222044605*var_290 + 0.0571428571428571410728559*var_198 + 0.2000000000000000111022302*var_989 + 0.0057142857142857142807579*var_18 + 0.4857142857142857095276156*var_282 + 1.7714285714285713524418497*var_159 + 0.1142857142857142821457117*var_271 + 1.0171428571428571263624008*var_196 + 0.6571428571428571396850771*var_50 + var_66 + 4.5714285714285711748061658*var_32 + 4.3428571428571425272480155*var_34 + var_7*var_8*var_987 + 0.7142857142857143015746146*var_281 + 3.5428571428571427048836995*var_21 + 0.0285714285714285705364279*var_178 + 1.1714285714285714856686127*var_117 + 1.2571428571428571174806166*var_988 + 0.8323809523809523325255100*var_47*var_80 + var_990; + const double var_992 = 0.4571428571428571285828468*var_232 + var_986 + 0.3809523809523809312338471*var_280 + 0.1028571428571428553189193*var_267 + 0.0419047619047619029908347*var_118*var_15 + 0.0952380952380952328084618*var_140 + 8.0000000000000000000000000*var_190 + 2.0000000000000000000000000*var_633 + 0.0114285714285714285615159*var_200 + 0.2057142857142857106378386*var_15*var_4 + 0.0380952380952380986744998*var_28 + var_402 + var_737 + 0.0247619047619047627506461*var_284 + var_803 + 0.0228571428571428571230317*var_257 + 0.6952380952380953216263038*var_16*var_57 + 0.0076190476190476190410106*var_487 + var_816 + 0.4190476190476191131750738*var_205 + 0.2285714285714285642914234*var_149 + 0.0152380952380952380820212*var_199 + 0.0266666666666666683782605*var_1*var_3*var_862 + var_790 + 0.2038095238095238015407773*var_9 + 0.3047619047619047893959987*var_155 + 0.5333333333333333259318465*var_870 + var_985 + 0.1111111111111111049432054*var_991; + A[94] = 8.0000000000000000000000000*var_13*var_992/(var_14*var_14*var_14); + const double var_993 = var_55 + var_174; + const double var_994 = 30.1111111111111107163651468*var_114 + 65.6666666666666571927635232*var_211 + 149.0000000000000000000000000*var_87 + 35.3333333333333285963817616*var_212 + 5.2222222222222223209087133*var_993; + const double var_995 = 2.0000000000000000000000000*var_467 + var_207; + const double var_996 = var_438 + var_301; + const double var_997 = var_34 + var_198; + const double var_998 = 88.3333333333333285963817616*var_65 + 63.8000000000000042632564146*var_759 + 161.2000000000000170530256582*var_158; + const double var_999 = 0.0984126984126984100109681*var_375 + 0.5629629629629629983256223*var_195 + var_380 + 0.1968253968253968200219362*var_235 + 1.5523809523809524169024598*var_94 + 0.7111111111111111382498962*var_35 + 0.7333333333333332815229255*var_141 + 0.7746031746031746267888707*var_16*var_47 + 1.1809523809523809756427681*var_189 + 2.6095238095238095787919974*var_196 + 0.4232804232804232569264968*var_996 + 0.1714285714285714301574615*var_142 + 0.6349206349206348853897452*var_995 + 0.2476190476190476552620368*var_997 + 0.0285714285714285705364279*var_7*var_8*var_994 + 2.4126984126984125644810319*var_21 + 0.5619047619047619068766153*var_33 + 0.7619047619047618624676943*var_155 + 5.8095238095238093123384715*var_121 + 0.5650793650793650702013338*var_16*var_60 + 0.0317460317460317442694873*var_80*var_998 + 0.1396825396825396858879742*var_193; + A[65] = var_13*var_999/(var_14*var_14*var_14); + A[530] = A[65]; + A[209] = 0.0000000000000000000000000; + A[323] = 0.0000000000000000000000000; + const double var_1000 = var_101 + var_41; + const double var_1001 = 149.0000000000000000000000000*var_36 + 35.3333333333333285963817616*var_37 + 65.6666666666666571927635232*var_43 + 5.2222222222222223209087133*var_1000; + const double var_1002 = 1.2761904761904763194735324*var_65; + const double var_1003 = 14.7142857142857135244184974*var_118 + 9.1333333333333328596381762*var_49 + 0.2285714285714285642914234*var_110 + 7.7428571428571428825193834*var_5 + var_1002; + const double var_1004 = var_236 + var_506; + const double var_1005 = var_120 + var_22; + const double var_1006 = var_19 + var_146; + const double var_1007 = 161.2000000000000170530256582*var_152 + 63.8000000000000042632564146*var_415 + 88.3333333333333285963817616*var_81; + const double var_1008 = 0.2476190476190476552620368*var_1005 + 0.1587301587301587213474363*var_210 + 1.4634920634920633997211326*var_20 + 0.0317460317460317442694873*var_1007*var_80 + 0.4804232804232804743271856*var_18 + 1.1809523809523809756427681*var_76 + 4.4253968253968256618691157*var_31 + 3.3396825396825398080125069*var_112 + 0.5777777777777778345225101*var_52 + 1.2920634920634921360971248*var_97 + 7.8222222222222228538157651*var_24 + 0.0285714285714285705364279*var_1*var_1001*var_3 + 0.0984126984126984100109681*var_1006 + 1.4412698412698412564481032*var_98 + 0.9037037037037037867648337*var_30 + var_818 + 0.4232804232804232569264968*var_1004 + 3.5650793650793652922459387*var_28 + 0.8603174603174603696231770*var_46 + 0.2222222222222222098864108*var_1003*var_15 + 0.7333333333333332815229255*var_495; + A[41] = var_1008*var_13/(var_14*var_14*var_14); + A[796] = A[41]; + const double var_1009 = 0.0069841269841269841209264*var_20; + const double var_1010 = var_570 + var_286 + var_64; + A[230] = 0.0000000000000000000000000; + A[752] = 0.0000000000000000000000000; + const double var_1011 = 0.0338624338624338647174561*var_80*var_81 + 0.0730158730158730201464934*var_56 + 0.0888888888888888922812370*var_733 + 0.0082539682539682548284565*var_22 + 0.0158730158730158721347436*var_742 + 0.0190476190476190493372499*var_729; + const double var_1012 = 0.0006349206349206349200842*var_141; + const double var_1013 = var_467 + 2.0000000000000000000000000*var_19; + const double var_1014 = 0.0042328042328042330896820*var_226; + const double var_1015 = 0.0203174603174603174426949*var_117; + const double var_1016 = 0.0050793650793650793606737*var_94; + const double var_1017 = 0.0139682539682539682418527*var_23; + const double var_1018 = 0.0228571428571428571230317*var_189; + const double var_1019 = 0.0133333333333333341891302*var_126; + const double var_1020 = var_52 + var_363; + const double var_1021 = var_267 + var_486; + const double var_1022 = var_88 + var_386; + const double var_1023 = 8.6666666666666660745477202*var_118 + 8.0000000000000000000000000*var_223 + 3.4444444444444441977282167*var_49; + const double var_1024 = 0.0095238095238095246686250*var_1022 + 0.1111111111111111049432054*var_100 + 0.0019047619047619047602526*var_1023*var_15 + var_1015 + 0.0002116402116402116490631*var_29 + var_804 + 0.0146031746031746040292987*var_121 + var_1018 + var_1019 + 0.0082539682539682548284565*var_286 + 0.0052910052910052907115812*var_236 + 0.0393650793650793667799448*var_31 + var_1012 + 0.0285714285714285705364279*var_1020 + 0.0368253968253968236301610*var_21 + 0.0234920634920634911757542*var_28 + 0.0006349206349206349200842*var_920 + var_1014 + 0.0078306878306878303919181*var_18 + 0.0069841269841269841209264*var_149 + 0.0035978835978835981695978*var_30 + 0.3333333333333333148296163*var_259 + 0.0190476190476190493372499*var_381 + 0.0184126984126984118150805*var_20 + 0.0158730158730158721347436*var_1021 + 0.0044444444444444444405895*var_64 + 0.0088888888888888888811790*var_112 + var_1016 + var_1011 + 0.0177777777777777777623580*var_233 + var_1017 + var_777 + 0.0120634920634920643489618*var_1013 + 0.0196825396825396833899724*var_196 + 0.0317460317460317442694873*var_229 + 0.0063492063492063492008421*var_175; + A[344] = 32.0000000000000000000000000*var_1024*var_13/(var_14*var_14*var_14); + A[896] = A[344]; + const double var_1025 = 21.5333333333333314385527046*var_89 + 34.3999999999999985789145285*var_104 + 6.4000000000000003552713679*var_115 + 30.6666666666666642981908808*var_163; + A[67] = var_13*var_649/(var_14*var_14*var_14); + const double var_1026 = var_91 + var_282; + const double var_1027 = var_1026 + var_234; + A[346] = 0.0000000000000000000000000; + const double var_1028 = 0.8000000000000000444089210*var_154; + const double var_1029 = 6.2000000000000001776356839*var_49 + 0.1066666666666666735130420*var_167 + 1.1733333333333333392545228*var_129 + 11.3333333333333321490954404*var_57 + var_1028 + 4.4666666666666667850904560*var_60 + 3.6666666666666665186369300*var_61 + 1.8133333333333334635995016*var_65; + const double var_1030 = 12.2380952380952372493538860*var_217 + 2.8000000000000002664535259*var_216 + 4.4476190476190478051421451*var_215 + 1.6857142857142857206298459*var_41; + const double var_1031 = 0.2391534391534391734701614*var_15*var_65; + const double var_1032 = 0.2895238095238095166195080*var_15*var_219; + const double var_1033 = var_280 + var_408; + const double var_1034 = 0.0273015873015873024309830*var_97 + 0.0190476190476190493372499*var_140 + 0.0952380952380952328084618*var_1029*var_80 + 0.0920634920634920694837433*var_283 + 0.0800000000000000016653345*var_200 + var_86 + 0.1714285714285714301574615*var_149 + 0.1396825396825396858879742*var_98 + 0.3415873015873016060872658*var_15*var_4 + 0.0296296296296296307604123*var_50 + var_1032 + 0.0666666666666666657414808*var_1*var_1030*var_3 + 0.0526984126984126957649046*var_199 + 0.0008465608465608465962524*var_139 + 0.2838095238095237893283240*var_9 + var_1031 + 0.3492063492063491869643599*var_197 + 0.1238095238095238276310184*var_205 + 0.4317460317460317664739478*var_240 + 0.9079365079365079305162567*var_132 + 0.2666666666666666629659233*var_202 + 0.0304761904761904761640423*var_367 + 0.0438095238095238120878960*var_19 + 0.0711111111111111110494321*var_423 + 0.0152380952380952380820212*var_487 + 0.2158730158730158832369739*var_1033 + 0.0628571428571428614251460*var_267; + A[35] = var_1034*var_13/(var_14*var_14*var_14); + A[616] = A[35]; + A[441] = 0.0000000000000000000000000; + A[879] = 0.0000000000000000000000000; + A[456] = 0.0000000000000000000000000; + const double var_1035 = 6.4000000000000003552713679*var_101 + 34.3999999999999985789145285*var_37 + 21.5333333333333314385527046*var_43 + 30.6666666666666642981908808*var_36; + const double var_1036 = 15.8000000000000007105427358*var_89 + 103.0000000000000000000000000*var_55 + 9.2000000000000010658141036*var_87; + const double var_1037 = var_25 + var_164 + var_729; + const double var_1038 = 0.1028571428571428553189193*var_103; + const double var_1039 = 0.0330158730158730193138261*var_108 + var_1038; + const double var_1040 = 0.0569312169312169366608423*var_74; + const double var_1041 = 0.6666666666666666296592325*var_80*var_81; + const double var_1042 = var_230 + var_1041; + const double var_1043 = var_117 + var_147; + const double var_1044 = var_146 + var_18; + const double var_1045 = 0.0791534391534391562617046*var_29 + 0.0031746031746031746004211*var_1036*var_7*var_8 + var_1040 + 0.0857142857142857150787307*var_50 + 0.0825396825396825378762244*var_1043 + 0.0400000000000000008326673*var_126 + 0.0603174603174603182753621*var_742 + 0.0893121693121693149830520*var_30 + var_564 + 0.4825396825396825462028971*var_24 + var_650 + 0.1904761904761904656169236*var_28 + 0.1161904761904761912427730*var_15*var_5 + 0.0761904761904761973489997*var_1037 + 0.0647619047619047566444195*var_22 + 0.2984126984126984072354105*var_23 + 0.0355555555555555555247160*var_121 + 0.0158730158730158721347436*var_91 + 0.4571428571428571285828468*var_31 + 2.0000000000000000000000000*var_1039 + 0.1695238095238095210604001*var_118*var_15 + var_632 + 0.2158730158730158832369739*var_1042 + 0.3809523809523809312338471*var_75 + 0.0888888888888888922812370*var_151 + 0.0222222222222222230703093*var_1010 + 0.1123809523809523869264382*var_20 + 0.3047619047619047893959987*var_105 + 0.0095238095238095246686250*var_1*var_1035*var_3 + 0.3174603174603174426948726*var_112 + 0.2666666666666666629659233*var_46 + 0.0933333333333333375891883*var_148 + 0.0171428571428571437096355*var_42 + 0.5333333333333333259318465*var_76 + var_333 + 0.3873015873015873133944353*var_733 + 0.0495238095238095255012922*var_120 + 0.0323809523809523783222097*var_1044 + 0.1600000000000000033306691*var_52; + A[103] = 32.0000000000000000000000000*var_1045*var_13/(var_14*var_14*var_14); + A[568] = A[103]; + const double var_1046 = var_210 + var_956; + const double var_1047 = 0.2361904761904762006796688*var_16*var_61 + 0.5485714285714285987083372*var_16*var_223 + 1.3333333333333332593184650*var_893; + const double var_1048 = 0.3333333333333333148296163*var_758 + var_120; + const double var_1049 = 0.0774603174603174654544446*var_74 + 0.2742857142857142993541686*var_77; + const double var_1050 = var_175 + 2.0000000000000000000000000*var_31; + const double var_1051 = 0.0228571428571428571230317*var_200; + const double var_1052 = var_467 + var_105; + const double var_1053 = 0.1714285714285714301574615*var_271 + 0.0342857142857142874192711*var_909 + 0.0095238095238095246686250*var_178 + 0.0888888888888888922812370*var_286 + var_243 + 0.1504761904761904856009380*var_136*var_7*var_8 + 0.2133333333333333470260840*var_147 + 0.0228571428571428571230317*var_207 + 0.0685714285714285748385421*var_826 + 0.0457142857142857142460635*var_143 + var_775 + 0.0253968253968253968033686*var_383 + 0.0780952380952380925682732*var_1050 + 0.0266666666666666683782605*var_1046 + 0.1123809523809523869264382*var_33 + 0.1485714285714285765038767*var_977 + 0.2704761904761904811600459*var_108 + 0.0190476190476190493372499*var_283 + 0.0361904761904761895774385*var_91 + 0.0742857142857142882519383*var_32 + 0.0419047619047619029908347*var_1048 + var_133 + 0.1282539682539682590611818*var_49*var_80 + var_1049 + 0.0761904761904761973489997*var_22 + 0.1523809523809523946979994*var_144 + 0.1257142857142857228502919*var_1052 + var_316 + 0.1428571428571428492126927*var_231 + var_1047 + 0.1771428571428571296930699*var_117 + 0.0914285714285714284921269*var_29 + 0.0152380952380952380820212*var_197 + 0.1561904761904761851365464*var_562 + 0.0520634920634920617121821*var_30 + var_1051 + 0.0495238095238095255012922*var_199 + 0.2342857142857142915826074*var_90 + 0.0076190476190476190410106*var_351; + A[314] = 8.0000000000000000000000000*var_1053*var_13/(var_14*var_14*var_14); + A[779] = A[314]; + const double var_1054 = var_47 + 0.0400000000000000008326673*var_81; + const double var_1055 = var_240 + var_58; + const double var_1056 = 22.0666666666666664298190881*var_65 + 128.0000000000000000000000000*var_118 + 188.8000000000000113686837722*var_5 + 67.8666666666666600349344662*var_49; + const double var_1057 = 67.0000000000000000000000000*var_41 + 494.0000000000000000000000000*var_36 + 148.0000000000000000000000000*var_43 + 566.0000000000000000000000000*var_45; + const double var_1058 = 286.0000000000000000000000000*var_149 + 8.0000000000000000000000000*var_267 + 1117.0000000000000000000000000*var_31 + 76.3333333333333285963817616*var_47*var_80 + 878.0000000000000000000000000*var_22 + 163.0000000000000000000000000*var_97 + 886.0000000000000000000000000*var_19 + 158.0000000000000000000000000*var_108 + var_66 + 353.0000000000000000000000000*var_9 + 251.0000000000000000000000000*var_199 + 76.0000000000000000000000000*var_144 + 474.3333333333333143855270464*var_80*var_81 + var_1*var_1057*var_3 + 551.0000000000000000000000000*var_28; + const double var_1059 = 23.0000000000000000000000000*var_64 + 209.0000000000000000000000000*var_24 + var_716 + 48.6666666666666642981908808*var_29 + var_1056*var_15 + 128.6666666666666571927635232*var_18 + 0.2000000000000000111022302*var_1058 + 154.3333333333333143855270464*var_30 + 62.0000000000000000000000000*var_16*var_49; + const double var_1060 = 1.5976190476190477163243031*var_4 + 3.2833333333333332149095440*var_85 + 5.9166666666666660745477202*var_158 + 1.1000000000000000888178420*var_118 + 4.7285714285714286475581503*var_5 + var_886; + const double var_1061 = var_88 + var_881 + var_381; + const double var_1062 = var_872 + var_230 + var_229; + const double var_1063 = var_871 + var_438 + var_523; + const double var_1064 = 2.0694444444444441977282167*var_1063 + 0.2551587301587301404026675*var_848 + 2.3642857142857143237790751*var_201 + 0.5500000000000000444089210*var_203 + 0.7988095238095238581621516*var_33 + 7.5583333333333335701809119*var_121 + 4.1388888888888883954564335*var_195 + 6.2416666666666662521834041*var_196 + 0.8428571428571428603149229*var_16*var_219 + 0.3011904761904762306556904*var_131 + 1.6416666666666666074547720*var_141 + 0.5000000000000000000000000*var_1060*var_80 + 2.9583333333333330372738601*var_94 + 0.2488095238095238415088062*var_59 + 1.7702380952380953882396852*var_198 + 4.6000000000000005329070518*var_1061 + 3.5523809523809526389470648*var_21 + 0.5940476190476190465616924*var_1062 + 0.5238095238095238359576911*var_156; + A[2] = 0.0666666666666666657414808*var_1064*var_13/(var_14*var_14*var_14); + A[467] = A[2]; + A[814] = 0.0000000000000000000000000; + const double var_1065 = 0.0133333333333333341891302*var_314; + const double var_1066 = 0.0190476190476190493372499*var_15*var_339 + 0.0338624338624338647174561*var_65*var_80 + 0.0888888888888888922812370*var_341 + 0.0158730158730158721347436*var_345; + const double var_1067 = var_175 + var_200; + const double var_1068 = 0.0065608465608465614191114*var_226; + const double var_1069 = 0.0190476190476190493372499*var_281; + const double var_1070 = var_286 + var_381; + const double var_1071 = var_203 + var_618; + const double var_1072 = var_205 + var_197; + const double var_1073 = var_131 + var_229; + const double var_1074 = var_271 + var_411; + const double var_1075 = 0.0019047619047619047602526*var_1027 + var_894 + 0.0110052910052910058597009*var_194 + 0.2000000000000000111022302*var_625 + 0.0063492063492063492008421*var_1072 + 0.0097354497354497360195325*var_49*var_80 + 0.0317460317460317442694873*var_267 + 0.0012698412698412698401684*var_280 + 0.0533333333333333367565210*var_202 + 0.0209523809523809514954173*var_1071 + 0.0171428571428571437096355*var_136*var_7*var_8 + 0.0730158730158730201464934*var_42 + 0.0082539682539682548284565*var_50 + 0.0114285714285714285615159*var_23 + 0.0584126984126984161171947*var_121 + 0.0203174603174603174426949*var_143 + var_1068 + 0.0031746031746031746004211*var_64 + 0.0800000000000000016653345*var_792 + var_1069 + 0.0247619047619047627506461*var_467 + 0.0120634920634920643489618*var_118*var_15 + 0.0006349206349206349200842*var_722 + var_543 + 0.0507936507936507936067372*var_88 + 0.0647619047619047566444195*var_185 + var_852 + 0.0520634920634920617121821*var_140 + 0.4000000000000000222044605*var_385 + 0.0152380952380952380820212*var_1067 + 0.0234920634920634911757542*var_1070 + 0.0050793650793650793606737*var_132 + 0.0076190476190476190410106*var_94 + 0.0380952380952380986744998*var_1073 + 0.0215873015873015890175868*var_196 + var_1066 + 0.0101587301587301587213474*var_1074; + A[163] = 32.0000000000000000000000000*var_1075*var_13/(var_14*var_14*var_14); + A[860] = A[163]; + const double var_1076 = 9.4000000000000003552713679*var_216 + 16.1222222222222235643585009*var_215 + 8.2111111111111121374506183*var_204 + 1.4555555555555557134539413*var_161 + 32.9444444444444428654605872*var_217 + 1.1888888888888888839545643*var_214; + const double var_1077 = 3.0740740740740739589398345*var_47 + 2.6666666666666665186369300*var_158; + const double var_1078 = 1.2788359788359788815625961*var_81 + 0.2561904761904761906876615*var_85 + 1.5393650793650792696354301*var_145 + 2.2777777777777776790912867*var_186 + 0.1771428571428571296930699*var_219 + 0.0400000000000000008326673*var_1077; + const double var_1079 = 5.9285714285714279370154145*var_61 + 13.5238095238095237249353886*var_57 + 4.5952380952380948997415544*var_60 + 7.3888888888888883954564335*var_49; + const double var_1080 = 0.8166137566137566805579695*var_194 + 0.4333333333333333481363070*var_378 + 0.2000000000000000111022302*var_1079*var_80 + 0.7793650793650793717759484*var_164 + 0.9468253968253967922663605*var_199 + 0.5404232804232804721067396*var_139 + 0.3363492063492063421925593*var_143 + 0.0714285714285714246063463*var_1*var_1076*var_3 + 0.1850793650793650657604417*var_149 + 2.1579365079365078194939542*var_283 + 0.4212698412698412941956860*var_140 + var_626 + 0.2714285714285714079530010*var_200 + 2.0984126984126985071554827*var_197 + 0.1746031746031745934821799*var_523 + 2.7444444444444444641817427*var_280 + var_1078*var_15 + 0.9428571428571428381104624*var_202 + 4.5111111111111110716365147*var_132 + 0.0811111111111111060534284*var_9 + 0.6753968253968254398245108*var_148 + 0.2761904761904762084512299*var_423; + const double var_1081 = 3.9222222222222224985443972*var_101 + 8.3622222222222220011644822*var_204 + 26.9800000000000004263256415*var_217 + 30.8333333333333321490954404*var_215 + 4.4400000000000003907985047*var_216 + 1.5311111111111110894000831*var_161; + const double var_1082 = 7.9857142857142857650387668*var_211 + 1.9342857142857143859515645*var_87 + 3.5600000000000000532907052*var_212 + 7.3152380952380955392300166*var_136 + 3.5476190476190474498707772*var_174; + const double var_1083 = 5.9047619047619042120800259*var_167 + 0.4142857142857142571656937*var_60 + var_719 + 3.6952380952380954326486062*var_129 + 0.7746031746031746267888707*var_65 + 7.4857142857142857650387668*var_154; + const double var_1084 = 6.4047619047619042120800259*var_4 + 38.4841269841269806306627288*var_186 + 4.4285714285714279370154145*var_125 + 13.5105820105820093601778353*var_81 + var_1077; + const double var_1085 = 0.3196825396825396792266361*var_121 + 0.1666666666666666574148081*var_1082*var_7*var_8 + 0.0400000000000000008326673*var_1084*var_15 + 0.1198412698412698457195447*var_199 + 1.2788359788359788815625961*var_139 + 0.4714285714285714190552312*var_235 + 0.0942857142857142921377189*var_200 + 0.8046560846560847357622492*var_49*var_80 + 0.0255555555555555570512727*var_148 + 0.5158730158730158166235924*var_198 + 2.3222222222222224097265553*var_197 + 1.6069841269841269593143807*var_131 + 0.1531746031746031855291790*var_141 + 0.4942857142857142727088160*var_142 + 0.0713227513227513293392335*var_65*var_80 + 1.0876190476190477074425189*var_189 + 0.0026984126984126986271983*var_178 + var_227 + 0.1349206349206349131453209*var_164 + 0.4114285714285714212756773*var_202 + 2.2777777777777776790912867*var_321 + 0.0714285714285714246063463*var_1*var_1081*var_3 + 1.1898412698412699217698218*var_280 + 0.5687301587301587524336810*var_146 + 2.5196825396825395237954126*var_132 + 1.5603174603174603252142560*var_281 + 0.0020634920634920637071141*var_229 + 0.5925396825396825883913721*var_283 + 0.3411111111111110871796370*var_282 + 1.4841269841269839613318027*var_196 + 0.4333333333333333481363070*var_257 + 0.0753968253968253926400322*var_117 + 0.8809523809523809312338471*var_195 + 0.1989417989417989474087989*var_64 + 1.7246031746031746934022522*var_143 + 0.3877777777777777767909129*var_203 + 2.3587301587301587879608178*var_194 + 0.4593650793650793651146103*var_120 + 0.0666666666666666657414808*var_1083*var_16 + 1.4444444444444444197728217*var_140 + 0.0006349206349206349200842*var_147; + A[10] = var_1085*var_13/(var_14*var_14*var_14); + A[475] = A[10]; + A[621] = A[156]; + A[19] = 0.0000000000000000000000000; + const double var_1086 = var_233 + var_234; + const double var_1087 = var_65 + var_49; + const double var_1088 = var_105 + var_38; + const double var_1089 = var_64 + var_18; + const double var_1090 = 0.0152380952380952380820212*var_77; + const double var_1091 = 0.6666666666666666296592325*var_800 + 0.0266666666666666683782605*var_325 + 0.0004232804232804232981262*var_944 + 0.1053968253968253915298092*var_607 + 0.1219047619047619046561692*var_602 + 0.0298412698412698421113198*var_458 + 0.0031746031746031746004211*var_471 + 0.1650793650793650757524489*var_1086 + 0.2539682539682539541558981*var_226 + 0.1904761904761904656169236*var_475 + 0.0698412698412698429439871*var_600 + 0.0419047619047619029908347*var_1088 + 0.1726984126984127121406942*var_943 + 0.0984126984126984100109681*var_480 + 0.0184126984126984118150805*var_613 + 0.0846560846560846513852994*var_1089 + 0.3682539682539682779349732*var_615 + 0.0215873015873015890175868*var_463 + 0.0069841269841269841209264*var_473 + 0.0146031746031746040292987*var_460 + 0.1542857142857142760394851*var_942 + 0.3714285714285714412596917*var_457 + 0.0565079365079365070201334*var_324 + 0.0368253968253968236301610*var_1087*var_80 + 0.1693121693121693027705987*var_483 + 0.0444444444444444461406185*var_464 + 0.0249735449735449741015536*var_603 + 0.0076190476190476190410106*var_601 + 0.0920634920634920694837433*var_474 + var_1090; + A[189] = 16.0000000000000000000000000*var_1091*var_13/(var_14*var_14*var_14); + A[741] = A[189]; + const double var_1092 = var_144 + var_196; + const double var_1093 = 0.0025396825396825396803369*var_18 + 0.0190476190476190493372499*var_229 + var_685; + const double var_1094 = var_15*var_440; + const double var_1095 = 0.0306878306878306909843968*var_49*var_80; + const double var_1096 = 0.0419047619047619029908347*var_16*var_65; + const double var_1097 = 0.0057142857142857142807579*var_56 + 0.0533333333333333367565210*var_232; + const double var_1098 = var_1097 + var_801; + const double var_1099 = var_131 + var_201; + const double var_1100 = var_21 + var_38; + const double var_1101 = var_854 + var_842; + const double var_1102 = 0.0114285714285714285615159*var_1094 + 0.2285714285714285642914234*var_1099 + var_732 + 0.0266666666666666683782605*var_193 + var_846 + 0.0203174603174603174426949*var_1092 + 0.0461375661375661369478784*var_194 + 0.0082539682539682548284565*var_1101 + 0.1142857142857142821457117*var_130 + 0.8000000000000000444089210*var_1095 + 0.1612698412698412575583262*var_197 + 0.0025396825396825396803369*var_368 + 0.0031746031746031746004211*var_20 + 0.1066666666666666735130420*var_189 + var_556 + 0.0666666666666666657414808*var_883 + var_1093 + 0.1396825396825396858879742*var_132 + 2.0000000000000000000000000*var_1098 + var_1096 + 0.2400000000000000188737914*var_203 + 0.0355555555555555555247160*var_382 + 0.0184126984126984118150805*var_102 + 0.0342857142857142874192711*var_1100 + 0.1104761904761904778293768*var_175 + var_305 + 0.3390476190476190421208003*var_198 + 0.0224338624338624344212167*var_47*var_80 + 0.0753439153439153519453697*var_195 + 0.0457142857142857142460635*var_76 + 0.0152380952380952380820212*var_95 + var_844 + 0.1295238095238095132888390*var_573 + 0.0107936507936507945087934*var_19 + var_933; + A[160] = 4.0000000000000000000000000*var_1102*var_13/(var_14*var_14*var_14); + const double var_1103 = var_146 + var_33; + const double var_1104 = var_328 + var_28; + A[265] = 0.0000000000000000000000000; + const double var_1105 = var_117 + var_175; + const double var_1106 = var_32 + var_618 + var_282; + const double var_1107 = 0.0217989417989418003684943*var_226; + const double var_1108 = 0.1142857142857142821457117*var_285; + const double var_1109 = 0.0704761904761904700578157*var_207; + const double var_1110 = 0.0228571428571428571230317*var_155; + const double var_1111 = var_519 + var_352; + const double var_1112 = var_1041 + var_193; + const double var_1113 = 41.0000000000000000000000000*var_222 + 14.3333333333333321490954404*var_47 + 8.6666666666666660745477202*var_49; + const double var_1114 = var_1107 + 0.0082539682539682548284565*var_139 + 0.3333333333333333148296163*var_401 + 0.2095238095238095565875369*var_1111 + 0.0019047619047619047602526*var_1113*var_16 + 0.0044444444444444444405895*var_50 + var_620 + var_1110 + 0.1752380952380952483515841*var_189 + 0.0304761904761904761640423*var_208 + 0.0076190476190476190410106*var_1105 + var_1108 + 0.0914285714285714284921269*var_142 + 0.0300529100529100534622273*var_194 + 0.0012698412698412698401684*var_28 + 0.1257142857142857228502919*var_21 + var_776 + 0.1384126984126984039047414*var_121 + 0.1244444444444444408670591*var_809 + var_1109 + 0.0438095238095238120878960*var_1106 + 0.0031746031746031746004211*var_1*var_3*var_619 + 0.1371428571428571496770843*var_202 + 0.0120634920634920643489618*var_321 + var_1097 + 0.0888888888888888922812370*var_88 + var_1051 + 0.0761904761904761973489997*var_229 + 0.0768253968253968244628282*var_211*var_7*var_8 + 0.0444444444444444461406185*var_205 + 0.0495238095238095255012922*var_94 + 0.0939682539682539647030168*var_140 + var_1066 + 0.0196825396825396833899724*var_1112 + var_503 + 0.0215873015873015890175868*var_384; + A[162] = 32.0000000000000000000000000*var_1114*var_13/(var_14*var_14*var_14); + A[365] = A[162]; + A[231] = 0.0000000000000000000000000; + const double var_1115 = var_29 + var_30; + const double var_1116 = 0.2501587301587301359617754*var_601 + 0.4819047619047618913334929*var_605 + 0.6622222222222222676180081*var_324 + 0.4069841269841270037233016*var_460 + 0.6825396825396825573051274*var_945 + 0.2209523809523809556587537*var_463 + 1.4603174603174602363964141*var_1115 + 0.1568253968253968122503750*var_473 + 0.4000000000000000222044605*var_600 + 0.7390476190476190643252608*var_602 + 1.0984126984126985071554827*var_481 + 1.3809523809523809312338471*var_604 + 0.3250793650793650790831180*var_607 + 1.9504761904761904744987078*var_396 + 0.2825396825396825351006669*var_326 + 0.8482539682539682601714048*var_459 + 1.3447619047619048249231355*var_465 + 0.7301587301587301181982070*var_464 + 0.0626455026455026431353446*var_603 + 0.0744973544973545065417397*var_478*var_80 + 0.6057142857142857605978747*var_325 + 0.4867724867724867454654714*var_1089 + 0.1860317460317460203089723*var_613 + 0.0507936507936507936067372*var_609 + 0.9735449735449734909309427*var_74 + 0.7492063492063492091688204*var_1086 + 0.3231746031746031699860566*var_458 + 0.6317460317460317220650268*var_474 + 0.0118518518518518512633309*var_470 + 0.3390476190476190421208003*var_461 + 0.2958730158730158987800962*var_941; + A[12] = 2.0000000000000000000000000*var_1116*var_13/(var_14*var_14*var_14); + A[477] = A[12]; + const double var_1117 = 0.0222222222222222230703093*var_94 + 0.9777777777777778567269706*var_23; + A[293] = 0.0000000000000000000000000; + const double var_1118 = 9.8666666666666671403618238*var_150 + 33.4761904761904744987077720*var_136 + 6.0380952380952388480750415*var_174 + 1.4095238095238096232009184*var_89 + 3.8285714285714282922867824*var_104; + const double var_1119 = var_161 + var_214; + const double var_1120 = 149.0000000000000000000000000*var_217 + 30.1111111111111107163651468*var_204 + 65.6666666666666571927635232*var_215 + 35.3333333333333285963817616*var_216 + 5.2222222222222223209087133*var_1119; + const double var_1121 = var_321 + 2.0000000000000000000000000*var_367; + const double var_1122 = var_149 + var_140; + const double var_1123 = var_423 + var_523; + const double var_1124 = var_143 + var_9; + const double var_1125 = 88.3333333333333285963817616*var_49 + 63.8000000000000042632564146*var_62 + 161.2000000000000170530256582*var_57; + const double var_1126 = 0.2476190476190476552620368*var_1122 + 0.5619047619047619068766153*var_148 + var_160 + 0.1714285714285714301574615*var_200 + 0.0317460317460317442694873*var_1125*var_80 + 5.8095238095238093123384715*var_132 + 2.4126984126984125644810319*var_280 + 1.1809523809523809756427681*var_202 + 0.6349206349206348853897452*var_1121 + 0.0984126984126984100109681*var_1124 + 0.0285714285714285705364279*var_1*var_1120*var_3 + 0.1396825396825396858879742*var_139 + 0.7333333333333332815229255*var_199 + 0.7746031746031746267888707*var_15*var_81 + 0.7111111111111111382498962*var_164 + 0.5629629629629629983256223*var_194 + 2.6095238095238095787919974*var_197 + 1.5523809523809524169024598*var_283 + 0.7619047619047618624676943*var_288 + 0.5650793650793650702013338*var_15*var_4 + 0.1968253968253968200219362*var_210 + 0.4232804232804232569264968*var_1123; + A[33] = var_1126*var_13/(var_14*var_14*var_14); + A[91] = A[33]; + A[321] = 0.0000000000000000000000000; + A[516] = 0.0000000000000000000000000; + const double var_1127 = 9.0000000000000000000000000*var_163 + 8.0793650793650790831179620*var_115 + 25.0476190476190474498707772*var_104 + 16.9682539682539683667528152*var_150; + A[512] = 0.0000000000000000000000000; + A[634] = 0.0000000000000000000000000; + A[178] = 0.0000000000000000000000000; + A[503] = A[38]; + const double var_1128 = 0.2000000000000000111022302*var_410 + var_151; + const double var_1129 = var_175 + var_1128; + A[492] = 0.0000000000000000000000000; + A[759] = 0.0000000000000000000000000; + A[674] = 0.0000000000000000000000000; + const double var_1130 = var_467 + 8.0000000000000000000000000*var_117; + const double var_1131 = 0.1714285714285714301574615*var_25; + const double var_1132 = var_94 + var_75; + const double var_1133 = 0.0152380952380952380820212*var_1132 + 0.0914285714285714284921269*var_76 + 0.0457142857142857142460635*var_288 + 0.3714285714285714412596917*var_660 + var_315 + 0.0495238095238095255012922*var_292 + 0.1961904761904761929081076*var_210 + 1.0857142857142856318120039*var_34 + var_817 + 0.1638095238095238215247917*var_21 + 0.1676190476190476119633388*var_33 + 0.1561904761904761851365464*var_212*var_7*var_8 + 0.0076190476190476190410106*var_175 + 0.0304761904761904761640423*var_1130 + 0.3542857142857142593861397*var_38 + 0.2628571428571428447718006*var_200 + 0.3676190476190476230655690*var_32 + 0.0038095238095238095205053*var_91 + 0.8857142857142856762209249*var_35 + 0.0419047619047619029908347*var_234 + 0.1485714285714285765038767*var_229 + var_1131 + var_805 + 0.2057142857142857106378386*var_16*var_61 + 0.1504761904761904856009380*var_52 + 0.2361904761904762006796688*var_23 + 0.0228571428571428571230317*var_232 + 0.0031746031746031746004211*var_1059; + A[280] = 8.0000000000000000000000000*var_1133*var_13/(var_14*var_14*var_14); + A[745] = A[280]; + A[782] = 0.0000000000000000000000000; + const double var_1134 = 1.5396825396825395415589810*var_51 + 4.5714285714285711748061658*var_125 + 2.3492063492063492979866624*var_186 + 3.5555555555555553581825734*var_145 + var_277; + const double var_1135 = 0.1561904761904761851365464*var_38; + const double var_1136 = var_257 + var_510; + const double var_1137 = 0.1295238095238095132888390*var_76; + const double var_1138 = 0.0412698412698412689381122*var_143 + 0.1746031746031745934821799*var_44 + var_1135 + 0.1261375661375661316743191*var_139 + 0.2000000000000000111022302*var_429 + 0.0184126984126984118150805*var_1*var_3*var_41 + 0.0165079365079365096569131*var_47*var_80 + 0.1739682539682539663683514*var_112 + 0.0946031746031746056946332*var_102 + var_866 + 0.1130158730158730140402668*var_506 + 0.0266666666666666683782605*var_200 + 0.0838095238095238059816694*var_149 + 0.0444444444444444461406185*var_98 + 0.1460317460317460402929868*var_222*var_80 + 0.0533333333333333367565210*var_22 + 0.2425396825396825273291057*var_1136 + var_851 + 0.0131216931216931228382228*var_194 + 0.0800000000000000016653345*var_1134*var_15 + 0.0260317460317460308560911*var_97 + var_1137; + A[36] = var_1138*var_13/(var_14*var_14*var_14); + A[646] = A[36]; + const double var_1139 = 0.9047619047619047671915382*var_204 + 1.1523809523809525057203018*var_36 + 10.2285714285714277593797306*var_216 + 9.3238095238095244354781244*var_214 + 10.7333333333333325043668083*var_41; + const double var_1140 = 0.0888888888888888922812370*var_594; + const double var_1141 = 0.1142857142857142821457117*var_281; + const double var_1142 = var_1141 + 0.3333333333333333148296163*var_251 + 0.6742857142857142660474778*var_21 + 0.4000000000000000222044605*var_430 + 0.8711111111111110583138384*var_140 + 1.1746031746031746489933312*var_120 + 0.0666666666666666657414808*var_1*var_1139*var_3 + 0.0622222222222222204335296*var_197 + 0.2800000000000000266453526*var_141 + var_1032 + 0.2095238095238095565875369*var_200 + 0.2158730158730158832369739*var_198 + 0.0019047619047619047602526*var_975 + 0.8914285714285714590232601*var_202 + 0.8634920634920635329478955*var_98 + 0.3904761904761905322303051*var_229 + 0.7174603174603174648993331*var_196 + 0.2000000000000000111022302*var_432 + var_311 + 0.0800000000000000016653345*var_16*var_939 + var_1140 + 0.0311111111111111102167648*var_201; + A[5] = var_1142*var_13/(var_14*var_14*var_14); + A[150] = A[5]; + A[841] = 0.0000000000000000000000000; + A[517] = 0.0000000000000000000000000; + const double var_1143 = var_271 + var_44 + var_726; + const double var_1144 = 0.0285714285714285705364279*var_282 + var_641; + const double var_1145 = var_230 + 2.0000000000000000000000000*var_977; + const double var_1146 = 0.0323809523809523783222097*var_152*var_16; + const double var_1147 = 31.0000000000000000000000000*var_204 + 61.0000000000000000000000000*var_101; + const double var_1148 = 0.2666666666666666629659233*var_135 + 0.0613756613756613819687935*var_833 + var_863 + 0.1650793650793650757524489*var_148 + var_583 + var_924 + 0.1619047619047619124277304*var_178 + 0.6285714285714285587403083*var_9 + 0.1481481481481481399242739*var_30 + var_1144 + 0.0539682539682539708092435*var_1041 + 0.1053968253968253915298092*var_16*var_167 + 0.7936507936507936067371816*var_766 + 0.0698412698412698429439871*var_185 + 0.1904761904761904656169236*var_103 + 0.2857142857142856984253854*var_105 + 0.9587301587301587657563573*var_164 + 0.8634920634920635329478955*var_144 + 0.4000000000000000222044605*var_147 + 0.0285714285714285705364279*var_410 + 0.2920634920634920805859736*var_15*var_759 + 1.4222222222222222764997923*var_149 + 0.1117460317460317459348218*var_29 + 0.4232804232804232569264968*var_831 + var_78 + 0.0336507936507936533665486*var_117 + 0.2380952380952380820211545*var_151 + 0.0249735449735449741015536*var_64 + 0.0812698412698412697707795*var_23 + 0.7015873015873015372534383*var_163*var_7*var_8 + 0.0846560846560846513852994*var_66 + 0.1238095238095238276310184*var_91 + 0.0004232804232804232981262*var_253 + 0.0082539682539682548284565*var_32 + 0.0476190476190476164042309*var_1145 + 0.0063492063492063492008421*var_1*var_1147*var_3 + 0.0253968253968253968033686*var_1143 + 0.2222222222222222098864108*var_280 + 0.3650793650793650590991035*var_90 + 0.6666666666666666296592325*var_1146 + 0.6539682539682539763603586*var_22 + 1.3333333333333332593184650*var_543; + A[158] = 16.0000000000000000000000000*var_1148*var_13/(var_14*var_14*var_14); + A[245] = A[158]; + const double var_1149 = var_382 + var_141; + const double var_1150 = 25.0000000000000000000000000*var_152 + 9.2000000000000010658141036*var_415 + 13.3333333333333321490954404*var_81; + const double var_1151 = 0.0253968253968253968033686*var_1092 + 0.0126984126984126984016843*var_1149 + 0.0306878306878306909843968*var_871 + 0.1333333333333333314829616*var_201 + 0.3142857142857142793701541*var_203 + 0.0101587301587301587213474*var_149 + 0.0158730158730158721347436*var_1150*var_16 + 0.1904761904761904656169236*var_189 + 0.0952380952380952328084618*var_142 + 0.0825396825396825378762244*var_282 + var_769 + 0.0406349206349206348853897*var_140; + const double var_1152 = var_26*var_3 + 0.6000000000000000888178420*var_145 + 1.2000000000000001776356839*var_219 + var_1*var_27; + const double var_1153 = var_215 + 2.0000000000000000000000000*var_217; + const double var_1154 = 2.0000000000000000000000000*var_147 + var_267; + const double var_1155 = 0.0306878306878306909843968*var_226; + const double var_1156 = var_533 + var_98; + const double var_1157 = var_1155 + 0.0209523809523809514954173*var_139 + 0.1142857142857142821457117*var_1152*var_15 + var_1151 + 0.1333333333333333314829616*var_1067 + 0.0516402116402116390103672*var_194 + 0.2666666666666666629659233*var_198 + 0.3142857142857142793701541*var_410 + 0.0158730158730158721347436*var_284 + 0.0571428571428571410728559*var_97 + 0.0253968253968253968033686*var_1154 + var_832 + 0.0666666666666666657414808*var_287 + 0.6285714285714285587403083*var_131 + 0.0613756613756613819687935*var_195 + 0.0228571428571428571230317*var_210 + 0.0380952380952380986744998*var_530 + 0.0052910052910052907115812*var_523 + 0.2984126984126984072354105*var_280 + 0.0057142857142857142807579*var_146 + 0.3047619047619047893959987*var_202 + 0.3936507936507936400438723*var_132 + 0.3968253968253968033685908*var_281 + 0.1206349206349206365507243*var_1*var_1153*var_3 + 0.1460317460317460402929868*var_205 + 0.0761904761904761973489997*var_199 + var_922 + var_914 + 0.0412698412698412689381122*var_1156; + A[93] = 32.0000000000000000000000000*var_1157*var_13/(var_14*var_14*var_14); + A[558] = A[93]; + A[672] = 0.0000000000000000000000000; + A[873] = 0.0000000000000000000000000; + const double var_1158 = 2.2380952380952381375323057*var_161 + 4.6380952380952384928036736*var_45 + 1.8761904761904764082913744*var_43 + 6.8000000000000007105427358*var_37 + 2.1619047619047622177390622*var_101; + const double var_1159 = 0.3333333333333333148296163*var_65 + var_158; + const double var_1160 = 0.9523809523809523280846179*var_1159*var_15; + const double var_1161 = 0.3714285714285714412596917*var_234 + var_144; + const double var_1162 = 0.1739682539682539663683514*var_74; + const double var_1163 = 0.2495238095238095366035225*var_117; + const double var_1164 = var_182 + var_363; + const double var_1165 = 0.3047619047619047893959987*var_34 + 0.1619047619047619124277304*var_1164 + var_1047 + var_711 + 2.5142857142857142349612332*var_76 + 0.0819047619047619107623959*var_28 + 0.2609523809523809356747392*var_231 + 1.0857142857142856318120039*var_147 + 0.6666666666666666296592325*var_528 + 0.2476190476190476552620368*var_257 + 2.0000000000000000000000000*var_923 + 0.2666666666666666629659233*var_1161 + 1.3523809523809524613113808*var_164 + 0.6285714285714285587403083*var_22 + 0.1980952380952381020051689*var_15*var_5 + 0.1041269841269841234243643*var_18 + 0.1961904761904761929081076*var_19 + 0.6247619047619047405461856*var_112 + 0.7485714285714285542994162*var_328 + 0.1314285714285714223859003*var_33 + 0.2438095238095238093123385*var_24 + var_1162 + 0.2780952380952381175482913*var_30 + 0.2412698412698412731014486*var_29 + 0.2171428571428571374646310*var_25 + 0.2000000000000000111022302*var_1*var_1158*var_3 + 1.7142857142857141905523122*var_75 + 0.0444444444444444461406185*var_236 + 1.0800000000000000710542736*var_150*var_7*var_8 + 0.3904761904761905322303051*var_90 + 0.3428571428571428603149229*var_35 + 1.1542857142857143593062119*var_103 + 0.3123809523809523702730928*var_185 + var_1160 + 0.0673015873015873067330972*var_64 + 1.0095238095238097120187604*var_31 + 0.2495238095238095366035225*var_20 + 0.4095238095238095676897672*var_9 + var_735 + 0.0933333333333333375891883*var_32 + 0.0857142857142857150787307*var_91 + var_489 + var_260 + 0.4171428571428571485668613*var_230 + 0.0419047619047619029908347*var_467 + 0.4761904761904761640423089*var_108 + 0.1219047619047619046561692*var_119 + var_495 + var_1163; + const double var_1166 = 0.8666666666666666962726140*var_81 + 1.7333333333333333925452280*var_65 + 9.4000000000000003552713679*var_169 + 13.0000000000000000000000000*var_167 + 9.2000000000000010658141036*var_129; + const double var_1167 = var_194 + var_21; + const double var_1168 = var_153 + var_18; + const double var_1169 = 3.4000000000000003552713679*var_140 + var_301 + 0.4000000000000000222044605*var_50 + 7.4000000000000003552713679*var_1167 + var_1166*var_16 + 0.8000000000000000444089210*var_233 + 11.8000000000000007105427358*var_121 + 2.0666666666666664298190881*var_195 + 6.4000000000000003552713679*var_132 + var_119 + 0.2000000000000000111022302*var_1168 + 5.5333333333333332149095440*var_64 + 12.2000000000000010658141036*var_196 + 12.8000000000000007105427358*var_197; + A[405] = 0.0000000000000000000000000; + const double var_1170 = 191.0000000000000000000000000*var_163 + 541.0000000000000000000000000*var_89 + 209.0000000000000000000000000*var_55; + A[884] = 0.0000000000000000000000000; + const double var_1171 = 0.6666666666666666296592325*var_340 + 0.0044444444444444444405895*var_345 + 0.0177777777777777777623580*var_523 + var_342; + const double var_1172 = var_46 + var_151; + const double var_1173 = var_31 + var_147; + const double var_1174 = var_468 + var_483; + const double var_1175 = 0.2000000000000000111022302*var_472 + 3.4000000000000003552713679*var_943 + var_609 + 0.4000000000000000222044605*var_226 + var_466 + 0.8000000000000000444089210*var_1174 + var_1173; + const double var_1176 = var_610 + var_1088; + const double var_1177 = 0.0107936507936507945087934*var_1172 + 0.0069841269841269841209264*var_841 + var_1171 + var_672 + 0.0006349206349206349200842*var_480 + 0.0044444444444444444405895*var_613 + 0.0171428571428571437096355*var_942 + 0.0088888888888888888811790*var_615 + 0.0063492063492063492008421*var_1175 + 0.0019047619047619047602526*var_457 + 0.0273015873015873024309830*var_460 + 0.0114285714285714285615159*var_1176; + A[251] = 16.0000000000000000000000000*var_1177*var_13/(var_14*var_14*var_14); + const double var_1178 = var_19 + var_31; + const double var_1179 = 0.0730158730158730201464934*var_284 + 0.0338624338624338647174561*var_47*var_80 + 0.0082539682539682548284565*var_23 + 0.0158730158730158721347436*var_842 + 0.0888888888888888922812370*var_843 + 0.0190476190476190493372499*var_1094; + const double var_1180 = 2.0000000000000000000000000*var_117 + var_367; + const double var_1181 = var_233 + 16.0000000000000000000000000*var_32; + const double var_1182 = 0.0203174603174603174426949*var_19; + const double var_1183 = 0.0139682539682539682418527*var_22; + const double var_1184 = var_271 + var_381; + const double var_1185 = var_185 + var_231; + const double var_1186 = 3.4444444444444441977282167*var_65 + 8.0000000000000000000000000*var_125 + 8.6666666666666660745477202*var_129; + const double var_1187 = 0.0368253968253968236301610*var_280 + 0.0069841269841269841209264*var_34 + 0.0078306878306878303919181*var_64 + var_687 + 0.0317460317460317442694873*var_205 + 0.0285714285714285705364279*var_1185 + var_851 + 0.0146031746031746040292987*var_132 + 0.0177777777777777777623580*var_234 + 0.0095238095238095246686250*var_1184 + 0.0196825396825396833899724*var_197 + var_1182 + 0.0184126984126984118150805*var_91 + 0.0082539682539682548284565*var_287 + var_986 + var_1065 + 0.0052910052910052907115812*var_82 + 0.0088888888888888888811790*var_108 + 0.3333333333333333148296163*var_654 + var_1179 + 0.0158730158730158721347436*var_1129 + 0.0063492063492063492008421*var_267 + 0.0035978835978835981695978*var_29 + 0.0393650793650793667799448*var_147 + 0.0234920634920634911757542*var_178 + 0.0120634920634920643489618*var_1180 + var_1183 + 0.0006349206349206349200842*var_1181 + var_539 + var_336 + 0.1111111111111111049432054*var_1144 + 0.0002116402116402116490631*var_30 + 0.0044444444444444444405895*var_18 + var_1014 + 0.0190476190476190493372499*var_386 + 0.0019047619047619047602526*var_1186*var_16; + A[253] = 32.0000000000000000000000000*var_1187*var_13/(var_14*var_14*var_14); + const double var_1188 = 0.1641269841269841212039182*var_601 + 0.0742857142857142882519383*var_463 + 0.1025396825396825417620050*var_943 + 1.2857142857142855874030829*var_396 + 0.0757142857142857200747343*var_942 + 0.1011111111111111099392090*var_460 + 0.1046031746031746006986296*var_840 + 0.1350793650793650768626719*var_326 + 0.1833333333333333203807314*var_457 + 0.5620634920634920428383907*var_324 + 0.4276190476190476208451230*var_325 + 0.4006349206349206215627134*var_609 + 0.0268253968253968251567176*var_613 + 0.5888888888888889061590248*var_459 + 0.1609523809523809578791997*var_600 + 0.0630158730158730112647092*var_606 + 0.0119576719576719586735081*var_470 + 0.3184126984126984249989789*var_615 + 0.3936507936507936400438723*var_464 + 0.0364021164021164009283460*var_603 + 0.0483597883597883596018541*var_478*var_80 + 0.0126984126984126984016843*var_468 + 0.8580952380952381330914136*var_465 + 0.2925396825396825439824511*var_458 + 0.2695238095238094988559396*var_461 + 0.4304761904761904567351394*var_602 + 0.0787301587301587335598896*var_466 + 0.2960317460317460347418717*var_945 + var_1140; + A[4] = var_1188*var_13/(var_14*var_14*var_14); + A[469] = A[4]; + A[130] = var_13*var_972/(var_14*var_14*var_14); + A[769] = A[130]; + const double var_1189 = 29.0000000000000000000000000*var_214 + 63.4000000000000056843418861*var_43 + 32.6000000000000014210854715*var_425 + 59.8000000000000042632564146*var_41; + const double var_1190 = var_154*var_80 + var_76; + const double var_1191 = 226.0000000000000000000000000*var_125 + 141.5000000000000000000000000*var_85 + 6.2777777777777776790912867*var_65 + 84.5000000000000000000000000*var_51 + 41.3333333333333285963817616*var_186; + const double var_1192 = 84.9444444444444428654605872*var_19 + 4.9444444444444437536390069*var_20 + 3.9444444444444441977282167*var_97 + var_426*var_80 + var_865; + const double var_1193 = 0.0007936507936507936501053*var_1*var_1189*var_3 + 0.0296296296296296307604123*var_287 + 0.0028571428571428571403790*var_1192 + 0.0364021164021164009283460*var_18 + 0.0644444444444444430875052*var_112 + 0.2182539682539682557305127*var_9 + 0.0563492063492063502416762*var_28 + 0.0822222222222222243193102*var_424 + 0.0608465608465608431831839*var_30 + 0.0587301587301587296741090*var_98 + 0.1707936507936508030436329*var_149 + 0.0126984126984126984016843*var_321 + 0.2196825396825396736755209*var_22 + 0.0057142857142857142807579*var_1190 + 0.0019047619047619047602526*var_1191*var_15 + 0.0742857142857142882519383*var_292 + 0.0244444444444444457242849*var_864; + A[37] = var_1193*var_13/(var_14*var_14*var_14); + A[211] = A[37]; + A[605] = 0.0000000000000000000000000; + const double var_1194 = 0.0539682539682539708092435*var_9; + A[484] = 0.0000000000000000000000000; + const double var_1195 = 0.0228571428571428571230317*var_20; + A[288] = 0.0000000000000000000000000; + const double var_1196 = var_164 + var_35; + const double var_1197 = var_185 + var_52; + const double var_1198 = var_56 + var_284; + const double var_1199 = 2.4000000000000003552713679*var_459 + var_1198 + 7.6000000000000005329070518*var_465 + 0.8571428571428570952761561*var_1196 + 2.1142857142857143237790751*var_943 + 0.5428571428571428159060019*var_635 + 6.5142857142857142349612332*var_396 + 1.3809523809523809312338471*var_474 + 1.2571428571428571174806166*var_469 + 1.0857142857142856318120039*var_279 + 2.1968253968253970143109655*var_226 + 4.2285714285714286475581503*var_615 + 1.1619047619047619956944573*var_476 + 0.6031746031746031411202580*var_478*var_80 + 0.4317460317460317664739478*var_603 + 0.5841269841269841611719471*var_1089 + 3.2761904761904765415181373*var_609 + 0.2793650793650793717759484*var_470 + 1.4476190476190478051421451*var_1086 + 1.2285714285714284255135453*var_471 + 0.1428571428571428492126927*var_458 + 2.9428571428571426160658575*var_324 + 5.4571428571428572951163005*var_457 + 2.6571428571428570286627746*var_942 + 1.6126984126984127421167159*var_483 + 0.1523809523809523946979994*var_1055 + 4.6571428571428565845735648*var_945 + 1.2952380952380952994218433*var_607 + 1.0761904761904763638824534*var_473 + 2.0761904761904763638824534*var_477 + 0.0952380952380952328084618*var_1197; + A[220] = 0.2000000000000000111022302*var_1199*var_13/(var_14*var_14*var_14); + A[307] = A[220]; + A[57] = 0.0000000000000000000000000; + A[275] = A[159]; + A[602] = 0.0000000000000000000000000; + A[451] = 0.0000000000000000000000000; + const double var_1200 = var_840 + var_606; + const double var_1201 = 0.4000000000000000222044605*var_610 + 1.3714285714285714412596917*var_396 + 0.3390476190476190421208003*var_943 + 0.1904761904761904656169236*var_463 + 0.6095238095238095787919974*var_459 + 0.9714285714285714190552312*var_465 + 0.0228571428571428571230317*var_468 + 0.7238095238095239025710725*var_609 + 0.0590476190476190501699172*var_613 + 0.5295238095238095077377238*var_615 + 0.2526984126984126999282410*var_483 + 0.4209523809523809667609839*var_945 + 0.2800000000000000266453526*var_942 + 0.2304761904761904733884847*var_460 + 0.5333333333333333259318465*var_601 + 0.3942857142857142949132765*var_457 + 0.5504761904761904522942473*var_324 + 0.0495238095238095255012922*var_1087*var_80 + 0.1352380952380952405800230*var_326 + 0.1638095238095238215247917*var_226 + 0.3123809523809523702730928*var_600 + 0.2361904761904762006796688*var_461 + 0.2647619047619047538688619*var_458 + 0.0139682539682539682418527*var_603 + 0.4952380952380953105240735*var_464 + 0.1257142857142857228502919*var_466 + 0.5485714285714285987083372*var_602 + 0.0888888888888888922812370*var_944 + 0.3028571428571428802989374*var_1200; + A[132] = 8.0000000000000000000000000*var_1201*var_13/(var_14*var_14*var_14); + A[574] = 0.0000000000000000000000000; + const double var_1202 = 0.7682539682539683001394337*var_746 + 0.3079365079365079527207172*var_7*var_755*var_8 + 0.1481481481481481399242739*var_286 + 0.4603174603174602919075653*var_178 + var_753; + const double var_1203 = 4.5714285714285711748061658*var_223 + 3.5555555555555553581825734*var_206 + 2.3492063492063492979866624*var_222 + 1.5396825396825395415589810*var_184 + var_938; + const double var_1204 = 0.1561904761904761851365464*var_105; + const double var_1205 = var_749 + var_208; + const double var_1206 = 0.2425396825396825273291057*var_1205 + 0.0946031746031746056946332*var_230 + 0.1130158730158730140402668*var_748 + var_1204 + 0.0266666666666666683782605*var_142 + 0.0165079365079365096569131*var_80*var_81 + 0.1746031746031745934821799*var_90 + 0.0800000000000000016653345*var_1203*var_16 + var_347 + 0.0260317460317460308560911*var_282 + 0.0184126984126984118150805*var_136*var_7*var_8 + 0.0838095238095238059816694*var_34 + 0.1261375661375661316743191*var_193 + 0.0412698412698412689381122*var_201 + 0.1739682539682539663683514*var_108 + 0.1460317460317460402929868*var_186*var_80 + 0.0444444444444444461406185*var_281 + 0.2000000000000000111022302*var_1202 + 0.0533333333333333367565210*var_23 + var_1012 + 0.0131216931216931228382228*var_195 + var_754; + const double var_1207 = 0.6444444444444444863862032*var_1*var_3*var_36 + 0.2000000000000000111022302*var_156; + const double var_1208 = var_1002 + 7.7428571428571428825193834*var_118 + 14.7142857142857135244184974*var_5 + var_774; + const double var_1209 = 0.2952380952380952439106920*var_267; + const double var_1210 = 0.1714285714285714301574615*var_38; + const double var_1211 = var_178 + var_562; + const double var_1212 = var_448 + var_52; + const double var_1213 = var_29 + var_50; + const double var_1214 = 0.4804232804232804743271856*var_1213 + 0.2222222222222222098864108*var_1208*var_15 + 0.7047619047619048116004592*var_144 + 2.9873015873015873467011261*var_19 + var_380 + 0.9873015873015873467011261*var_201 + var_807 + 1.2412698412698413008570242*var_9 + 3.2846560846560848290209833*var_30 + 0.0031746031746031746004211*var_1170*var_7*var_8 + 0.0984126984126984100109681*var_1211 + 2.2825396825396824240783644*var_1*var_3*var_43 + 1.2888888888888889727724063*var_149 + 0.2952380952380952439106920*var_199 + 1.9873015873015873467011261*var_112 + 0.3079365079365079527207172*var_33 + 1.8222222222222221876819503*var_24 + 2.0000000000000000000000000*var_108 + 0.5650793650793650702013338*var_16*var_61 + 0.4190476190476191131750738*var_288 + 0.1439153439153439129061240*var_47*var_80 + 0.2571428571428571174806166*var_1104 + 0.5375661375661375807055720*var_80*var_81 + 2.0296296296296296723937758*var_18 + 2.6920634920634922693238877*var_22 + 0.2444444444444444641817427*var_151 + 0.2698412698412698262906417*var_230 + 0.5904761904761904878213841*var_25 + 1.1047619047619048338049197*var_75 + 1.2698412698412697707794905*var_16*var_206 + 0.1555555555555555580227178*var_203 + var_1210 + 0.7238095238095239025710725*var_31 + 0.4666666666666666740681535*var_46 + 0.2476190476190476552620368*var_200 + 0.5079365079365079083117962*var_34 + 0.7746031746031746267888707*var_193 + 0.7174603174603174648993331*var_198 + 0.0507936507936507936067372*var_292 + 0.3428571428571428603149229*var_147 + 0.1904761904761904656169236*var_314 + var_173 + var_496 + 0.0476190476190476164042309*var_683 + 0.1587301587301587213474363*var_1212 + 0.2825396825396825351006669*var_91 + var_1209 + 2.4285714285714283811046243*var_1207; + A[9] = var_1214*var_13/(var_14*var_14*var_14); + A[692] = 0.0000000000000000000000000; + A[168] = 0.0000000000000000000000000; + A[312] = 8.0000000000000000000000000*var_13*var_902/(var_14*var_14*var_14); + A[370] = A[312]; + A[730] = 0.0000000000000000000000000; + A[851] = 0.0000000000000000000000000; + A[831] = A[192]; + const double var_1215 = 0.0114285714285714285615159*var_74 + var_1090; + const double var_1216 = var_31 + var_50 + var_196; + const double var_1217 = var_56 + var_155; + const double var_1218 = var_231 + var_207; + const double var_1219 = var_230 + var_761; + const double var_1220 = var_1215 + 0.0253968253968253968033686*var_208 + 0.0148148148148148153802062*var_29 + 0.1777777777777777845624740*var_34 + 0.0846560846560846513852994*var_79 + 0.0571428571428571410728559*var_1219 + var_312 + 0.0033862433862433863850094*var_64 + 0.0507936507936507936067372*var_82 + 0.0114285714285714285615159*var_21 + 0.0044444444444444444405895*var_28 + 0.0965079365079365147916945*var_24 + 0.0761904761904761973489997*var_1217 + 0.0069841269841269841209264*var_19 + var_845 + 0.1428571428571428492126927*var_1207 + 0.0031746031746031746004211*var_205 + 0.0088888888888888888811790*var_1218 + var_1093 + 0.0025396825396825396803369*var_90 + 0.0526984126984126957649046*var_1*var_3*var_43 + 0.0012698412698412698401684*var_1216 + 0.0165079365079365096569131*var_130 + 0.1460317460317460402929868*var_16*var_57 + var_1009 + 0.0287830687830687853567824*var_16*var_65 + var_636 + var_1015 + 0.1015873015873015872134744*var_232 + var_1183 + 0.0774603174603174654544446*var_23 + var_652 + 0.0063492063492063492008421*var_1181 + 0.0596825396825396842226397*var_112 + 1.3333333333333332593184650*var_260; + A[161] = 16.0000000000000000000000000*var_1220*var_13/(var_14*var_14*var_14); + A[800] = A[161]; + A[69] = var_1206*var_13/(var_14*var_14*var_14); + A[737] = A[69]; + A[491] = 0.0000000000000000000000000; + const double var_1221 = var_143 + var_157; + A[628] = A[163]; + const double var_1222 = 14.8000000000000007105427358*var_37 + 18.0666666666666664298190881*var_43 + 26.3333333333333321490954404*var_36; + const double var_1223 = var_147 + var_304 + var_292; + const double var_1224 = 0.0482539682539682573958473*var_22; + const double var_1225 = 0.0063492063492063492008421*var_151; + const double var_1226 = var_467 + var_91; + const double var_1227 = 0.0400000000000000008326673*var_65 + var_49; + const double var_1228 = var_497 + var_123; + const double var_1229 = 0.0253968253968253968033686*var_232 + 0.1333333333333333314829616*var_1228 + 0.0596825396825396842226397*var_52 + var_127 + 0.1650793650793650757524489*var_32 + 0.0846560846560846513852994*var_1227*var_16 + var_592 + 0.3809523809523809312338471*var_34 + 0.1047619047619047782937685*var_46 + 0.0247619047619047627506461*var_148 + 0.1092063492063492097239319*var_117 + 0.0685714285714285748385421*var_29 + 0.1790476190476190387901312*var_31 + var_1039 + 0.0095238095238095246686250*var_1*var_1222*var_3 + 0.1185185185185185230416494*var_82 + 0.2158730158730158832369739*var_56 + 0.0742857142857142882519383*var_28 + 0.0780952380952380925682732*var_20 + 0.1904761904761904656169236*var_105 + 0.0444444444444444461406185*var_33 + 0.3250793650793650790831180*var_24 + 0.0203174603174603174426949*var_88 + 0.2501587301587301359617754*var_112 + var_1016 + 0.0361904761904761895774385*var_102 + 0.0088888888888888888811790*var_1226 + 0.0533333333333333367565210*var_25 + 0.0044444444444444444405895*var_146 + 0.0241269841269841286979236*var_90 + 0.0165079365079365096569131*var_234 + 0.1841269841269841389674866*var_115*var_7*var_8 + 0.0317460317460317442694873*var_257 + 0.0584126984126984161171947*var_15*var_5 + 0.0110052910052910058597009*var_18 + 0.0507936507936507936067372*var_30 + var_1224 + 0.0287830687830687853567824*var_64 + var_532 + 0.2933333333333333348136307*var_23 + var_954 + 0.6666666666666666296592325*var_985 + 0.0057142857142857142807579*var_42 + 0.1460317460317460402929868*var_58 + 0.0012698412698412698401684*var_1223 + 0.0120634920634920643489618*var_19 + var_1225 + 0.0055026455026455029298504*var_48; + A[99] = 16.0000000000000000000000000*var_1229*var_13/(var_14*var_14*var_14); + A[564] = A[99]; + A[619] = A[125]; + A[603] = 0.0000000000000000000000000; + A[525] = A[2]; + A[611] = 0.0000000000000000000000000; + const double var_1230 = var_136 + var_115; + const double var_1231 = 149.0000000000000000000000000*var_163 + 5.2222222222222223209087133*var_1230 + 65.6666666666666571927635232*var_89 + 35.3333333333333285963817616*var_104; + const double var_1232 = 7.7428571428571428825193834*var_167 + 0.2285714285714285642914234*var_152 + 14.7142857142857135244184974*var_129 + 9.1333333333333328596381762*var_65 + var_168; + const double var_1233 = var_748 + var_82; + const double var_1234 = var_203 + var_117; + const double var_1235 = 63.8000000000000042632564146*var_389 + 161.2000000000000170530256582*var_110 + 88.3333333333333285963817616*var_47; + const double var_1236 = 0.0317460317460317442694873*var_1235*var_80 + 0.4232804232804232569264968*var_1233 + 3.3396825396825398080125069*var_108 + 0.5777777777777778345225101*var_185 + 0.9037037037037037867648337*var_29 + 4.4253968253968256618691157*var_147 + 0.8603174603174603696231770*var_151 + 1.1809523809523809756427681*var_75 + 0.1587301587301587213474363*var_235 + 0.4804232804232804743271856*var_64 + 1.2920634920634921360971248*var_282 + var_1131 + 7.8222222222222228538157651*var_144 + 0.2476190476190476552620368*var_587 + 0.0285714285714285705364279*var_1231*var_7*var_8 + 1.4412698412698412564481032*var_281 + 3.5650793650793652922459387*var_178 + 0.0984126984126984100109681*var_1234 + 0.7333333333333332815229255*var_497 + 0.2222222222222222098864108*var_1232*var_16 + 1.4634920634920633997211326*var_91; + A[68] = var_1236*var_13/(var_14*var_14*var_14); + A[242] = A[68]; + A[272] = A[69]; + const double var_1237 = 2.1587301587301586103251338*var_153 + 1.1957671957671958118396560*var_16*var_81; + const double var_1238 = 221.0000000000000000000000000*var_214 + 2291.0000000000000000000000000*var_43 + 2293.0000000000000000000000000*var_36 + 467.0000000000000000000000000*var_45 + 109.0000000000000000000000000*var_41; + A[763] = 0.0000000000000000000000000; + const double var_1239 = 8.7333333333333325043668083*var_89 + 6.7777777777777776790912867*var_150 + 19.3333333333333321490954404*var_163 + 7.8000000000000007105427358*var_104 + 1.0222222222222223653176343*var_115; + const double var_1240 = 42.8888888888888857309211744*var_65 + 7.3555555555555560687253092*var_49 + 20.6000000000000014210854715*var_184 + 15.8000000000000007105427358*var_169 + 62.9333333333333300174672331*var_129 + 5.2000000000000001776356839*var_152; + const double var_1241 = 163.0000000000000000000000000*var_101 + 446.0000000000000000000000000*var_161 + 139.0000000000000000000000000*var_204; + const double var_1242 = 0.9777777777777778567269706*var_22 + 0.0222222222222222230703093*var_283; + const double var_1243 = 4.0000000000000000000000000*var_112 + var_132; + const double var_1244 = 0.1297354497354497315786404*var_74; + const double var_1245 = 0.0539682539682539708092435*var_32; + const double var_1246 = var_410 + var_91; + const double var_1247 = var_75 + var_103; + const double var_1248 = 0.0565079365079365070201334*var_1246 + 0.6952380952380953216263038*var_240 + 0.1873015873015873022922051*var_148 + var_1244 + 0.7354497354497354644209395*var_47*var_80 + 0.0025396825396825396803369*var_131 + 0.0916402116402116467819283*var_80*var_81 + 0.2171428571428571374646310*var_142 + var_723 + 0.0019047619047619047602526*var_363 + var_1245 + var_1242 + var_369 + 0.0571428571428571410728559*var_1239*var_7*var_8 + 1.6031746031746030300979555*var_164 + 1.8634920634920635329478955*var_144 + 0.3451851851851851504804358*var_29 + 0.1993650793650793562328261*var_117 + 0.0761904761904761973489997*var_38 + 1.1460317460317459570262599*var_147 + 0.1523809523809523946979994*var_378 + 0.1111111111111111049432054*var_18 + 0.4571428571428571285828468*var_257 + 0.4603174603174602919075653*var_19 + 0.2736507936507936444847644*var_282 + 0.2577777777777777723500208*var_23 + 0.2154497354497354466573711*var_64 + 0.7587301587301586991429758*var_178 + 0.0412698412698412689381122*var_20 + 0.7492063492063492091688204*var_9 + 0.0400000000000000008326673*var_44 + 0.2408465608465608642774214*var_30 + 2.1650793650793649369745708*var_149 + 0.0095238095238095246686250*var_1240*var_16 + 0.0031746031746031746004211*var_1*var_1241*var_3 + 0.4634920634920635107434350*var_280 + 0.0800000000000000016653345*var_497 + 0.3301587301587301515048978*var_281 + 0.4063492063492063488538975*var_234 + 0.0222222222222222230703093*var_50 + 0.2285714285714285642914234*var_1247 + 0.5555555555555555802271783*var_108 + 0.0203174603174603174426949*var_1243 + 0.3047619047619047893959987*var_76; + A[218] = 8.0000000000000000000000000*var_1248*var_13/(var_14*var_14*var_14); + A[683] = A[218]; + A[448] = 0.0000000000000000000000000; + const double var_1249 = var_519 + var_88; + A[149] = 0.0000000000000000000000000; + A[140] = 0.0000000000000000000000000; + const double var_1250 = var_61 + var_152; + const double var_1251 = 0.0006349206349206349200842*var_94; + A[386] = 0.0000000000000000000000000; + const double var_1252 = 0.9047619047619047671915382*var_33 + 0.8571428571428570952761561*var_34; + const double var_1253 = var_103 + var_142; + const double var_1254 = 118.0000000000000000000000000*var_222 + 83.0000000000000000000000000*var_61 + 67.0000000000000000000000000*var_184; + const double var_1255 = var_495 + var_172; + const double var_1256 = 212.2000000000000170530256582*var_43 + 53.0000000000000000000000000*var_45 + 63.8000000000000042632564146*var_36 + 61.4000000000000056843418861*var_161 + 29.8000000000000007105427358*var_101; + const double var_1257 = 69.3333333333333285963817616*var_29 + 14.6000000000000014210854715*var_143 + 52.0000000000000000000000000*var_31 + 22.6666666666666642981908808*var_139 + 7.4000000000000003552713679*var_199 + var_1*var_1256*var_3 + 62.8000000000000042632564146*var_24 + 77.2000000000000028421709430*var_149 + 13.6000000000000014210854715*var_487 + 32.6000000000000014210854715*var_148 + 231.2000000000000170530256582*var_108 + 204.8000000000000113686837722*var_112 + 15.8000000000000007105427358*var_9 + 32.0000000000000000000000000*var_286 + 197.2000000000000170530256582*var_144 + 94.0000000000000000000000000*var_164 + 11.6000000000000014210854715*var_187 + var_283; + const double var_1258 = var_1069 + 0.0019047619047619047602526*var_377*var_7*var_8 + 0.1942857142857142838110462*var_105 + 0.1028571428571428553189193*var_15*var_85 + 0.2761904761904762084512299*var_1128 + 0.3428571428571428603149229*var_76 + 0.0044444444444444444405895*var_1041 + 0.1142857142857142821457117*var_75 + var_497 + 0.2514285714285714457005838*var_198 + var_302 + 0.2628571428571428447718006*var_38 + var_1224 + 0.1047619047619047782937685*var_178 + 0.3333333333333333148296163*var_1255 + 0.2539682539682539541558981*var_193 + 0.1504761904761904856009380*var_500 + 0.3809523809523809312338471*var_147 + var_639 + var_491 + 0.0038095238095238095205053*var_1254*var_16 + 0.1161904761904761912427730*var_141 + 0.4021164021164020940801720*var_30 + 0.1695238095238095210604001*var_201 + 0.0800000000000000016653345*var_1253 + 0.0895238095238095193950656*var_32 + 0.0400000000000000008326673*var_1252 + 0.1451851851851851671337812*var_47*var_80 + 0.0876190476190476241757921*var_15*var_51 + 0.0031746031746031746004211*var_1257; + A[219] = 4.0000000000000000000000000*var_1258*var_13/(var_14*var_14*var_14); + A[742] = A[219]; + const double var_1259 = var_154 + var_339; + const double var_1260 = var_211 + 0.3333333333333333148296163*var_174; + const double var_1261 = var_131 + var_24; + const double var_1262 = 0.4000000000000000222044605*var_201 + var_46; + const double var_1263 = var_267 + var_1262; + const double var_1264 = 0.0023280423280423283294294*var_253 + 0.3873015873015873133944353*var_341 + 0.0256084656084656081542761*var_195 + 0.0355555555555555555247160*var_207 + 0.0533333333333333367565210*var_142 + 0.0450793650793650801933410*var_198 + 0.0806349206349206287791631*var_141 + 0.0222222222222222230703093*var_323 + 0.1428571428571428492126927*var_640 + 0.0124867724867724870507768*var_49*var_80 + 0.1447619047619047583097540*var_154*var_16 + 0.0704761904761904700578157*var_235 + 0.3333333333333333148296163*var_715 + 0.1365079365079364948076801*var_94 + 0.0901587301587301603866820*var_16*var_222 + 0.1439153439153439129061240*var_65*var_80 + 0.0603174603174603182753621*var_345 + 0.0253968253968253968033686*var_156 + 0.3269841269841269881801793*var_1*var_3*var_41 + 0.1809523809523809756427681*var_88 + 0.0273015873015873024309830*var_33 + 0.3174603174603174426948726*var_121 + 0.0035978835978835981695978*var_193 + var_736 + 0.0582010582010581978273933*var_286 + 0.0590476190476190501699172*var_1260*var_7*var_8 + 0.1460317460317460402929868*var_140 + 0.4380952380952381486345359*var_352 + var_405 + 0.0311111111111111102167648*var_197 + var_554 + 0.1396825396825396858879742*var_196 + 0.1555555555555555580227178*var_229 + 0.0698412698412698429439871*var_31 + 0.0057142857142857142807579*var_271 + 0.0634920634920634885389745*var_1263 + 0.0241269841269841286979236*var_203 + 0.0006349206349206349200842*var_1261 + 0.0825396825396825378762244*var_143 + 0.0152380952380952380820212*var_386 + 0.0442328042328042347897110*var_194 + 0.2920634920634920805859736*var_21 + 0.0761904761904761973489997*var_1259*var_15 + var_661; + A[254] = 32.0000000000000000000000000*var_1264*var_13/(var_14*var_14*var_14); + A[719] = A[254]; + A[494] = 0.0000000000000000000000000; + A[464] = 0.0000000000000000000000000; + A[139] = 0.0000000000000000000000000; + A[840] = 0.0000000000000000000000000; + const double var_1265 = 0.0224338624338624344212167*var_49*var_80; + const double var_1266 = var_287 + var_18 + var_368; + const double var_1267 = var_35 + var_1094 + var_103; + const double var_1268 = var_102 + var_84; + const double var_1269 = var_203 + var_64; + const double var_1270 = var_1040 + 0.4571428571428571285828468*var_147 + 0.3047619047619047893959987*var_38 + var_1265 + 0.0761904761904761973489997*var_1267 + 0.0647619047619047566444195*var_23 + 0.2666666666666666629659233*var_151 + 0.0158730158730158721347436*var_20 + 0.1904761904761904656169236*var_178 + var_254 + 0.5333333333333333259318465*var_75 + 0.0171428571428571437096355*var_410 + 0.0095238095238095246686250*var_1025*var_7*var_8 + 0.3174603174603174426948726*var_108 + var_357 + 0.0222222222222222230703093*var_1266 + 0.0857142857142857150787307*var_66 + 0.1123809523809523869264382*var_91 + 0.0495238095238095255012922*var_131 + 0.2158730158730158832369739*var_1268 + 0.1600000000000000033306691*var_185 + 2.0000000000000000000000000*var_537 + 0.0603174603174603182753621*var_842 + 0.0933333333333333375891883*var_33 + 0.3873015873015873133944353*var_843 + 0.3809523809523809312338471*var_76 + 0.0355555555555555555247160*var_132 + 0.2984126984126984072354105*var_22 + 0.0031746031746031746004211*var_1*var_3*var_414 + 0.0791534391534391562617046*var_30 + 0.1161904761904761912427730*var_16*var_167 + 0.4825396825396825462028971*var_144 + var_780 + 0.1695238095238095210604001*var_129*var_16 + 0.0825396825396825378762244*var_1178 + 0.0888888888888888922812370*var_46 + 0.0400000000000000008326673*var_314 + 0.0893121693121693149830520*var_29 + 0.0323809523809523783222097*var_1269; + A[164] = 32.0000000000000000000000000*var_1270*var_13/(var_14*var_14*var_14); + A[425] = A[164]; + A[738] = A[99]; + const double var_1271 = 0.2628571428571428447718006*var_77 + 0.0196825396825396833899724*var_74; + const double var_1272 = 9.0000000000000000000000000*var_55 + 11.0000000000000000000000000*var_150; + const double var_1273 = var_58 + var_112; + const double var_1274 = var_233 + var_119; + const double var_1275 = var_28 + var_363; + const double var_1276 = var_766 + var_90; + const double var_1277 = var_29 + var_715; + const double var_1278 = var_208 + var_32; + const double var_1279 = var_121 + var_140; + const double var_1280 = 2.0000000000000000000000000*var_1279 + 2.1333333333333333037273860*var_64 + 1.0666666666666666518636930*var_286 + 3.8000000000000002664535259*var_108 + 8.2000000000000010658141036*var_1278 + 5.2000000000000001776356839*var_1*var_3*var_43 + 19.0000000000000000000000000*var_34 + 2.6000000000000000888178420*var_88 + 4.3333333333333330372738601*var_30 + 2.2000000000000001776356839*var_16*var_167 + var_1130 + 12.8000000000000007105427358*var_23 + var_102 + 6.2000000000000001776356839*var_185 + 8.5999999999999996447286321*var_1046 + 5.8000000000000007105427358*var_1048; + const double var_1281 = 0.0533333333333333367565210*var_1275 + var_834 + 0.0800000000000000016653345*var_103 + 0.0400000000000000008326673*var_1277 + 0.0457142857142857142460635*var_1145 + 0.0857142857142857150787307*var_156 + 0.0476190476190476164042309*var_1273 + 0.1733333333333333392545228*var_46 + 0.0514285714285714276594597*var_1274 + var_1271 + 0.0285714285714285705364279*var_143 + var_853 + var_658 + 0.2266666666666666829499377*var_31 + 0.1066666666666666735130420*var_24 + var_261 + 0.0114285714285714285615159*var_1272*var_7*var_8 + var_177 + var_693 + 0.1314285714285714223859003*var_147 + 0.0222222222222222230703093*var_79 + 0.0133333333333333341891302*var_1276 + 0.0685714285714285748385421*var_1103 + 0.0095238095238095246686250*var_1280; + A[373] = 64.0000000000000000000000000*var_1281*var_13/(var_14*var_14*var_14); + A[867] = A[373]; + A[642] = 0.0000000000000000000000000; + A[813] = 0.0000000000000000000000000; + A[315] = 0.0000000000000000000000000; + A[126] = 4.0000000000000000000000000*var_13*var_963/(var_14*var_14*var_14); + A[591] = A[126]; + A[872] = 0.0000000000000000000000000; + A[238] = 0.0000000000000000000000000; + A[233] = 0.0000000000000000000000000; + const double var_1282 = 16.0000000000000000000000000*var_115 + 23.0000000000000000000000000*var_150; + A[703] = 0.0000000000000000000000000; + A[143] = 0.0000000000000000000000000; + const double var_1283 = 0.0266666666666666683782605*var_941 + 0.0222222222222222230703093*var_470 + var_800 + 0.0533333333333333367565210*var_840 + 0.0476190476190476164042309*var_1055 + 0.0285714285714285705364279*var_617; + A[404] = 64.0000000000000000000000000*var_1283*var_13/(var_14*var_14*var_14); + A[850] = 0.0000000000000000000000000; + A[87] = 0.0000000000000000000000000; + A[601] = 0.0000000000000000000000000; + A[506] = A[41]; + A[26] = 0.0000000000000000000000000; + const double var_1284 = 0.0139682539682539682418527*var_29 + 0.0044444444444444444405895*var_742 + 0.0076190476190476190410106*var_16*var_507 + 0.0273015873015873024309830*var_55*var_7*var_8 + 0.0266666666666666683782605*var_1041 + var_734; + const double var_1285 = 0.0266666666666666683782605*var_19 + 0.0044444444444444444405895*var_193; + const double var_1286 = var_467 + var_108; + const double var_1287 = var_977 + var_140; + const double var_1288 = var_146 + 0.3333333333333333148296163*var_766; + const double var_1289 = var_267 + var_1288; + const double var_1290 = 0.0260317460317460308560911*var_115*var_7*var_8 + var_1195 + 0.0063492063492063492008421*var_1286 + 0.0673015873015873067330972*var_112 + 0.0152380952380952380820212*var_1046 + 0.0190476190476190493372499*var_46 + 0.0114285714285714285615159*var_1289 + 0.0076190476190476190410106*var_1048 + 0.0317460317460317442694873*var_30 + var_725 + 0.0698412698412698429439871*var_24 + var_949 + 0.0050793650793650793606737*var_207 + 0.2857142857142856984253854*var_1285 + 0.0031746031746031746004211*var_117 + 0.0444444444444444461406185*var_44 + var_1012 + 0.0419047619047619029908347*var_31 + 0.0228571428571428571230317*var_28 + 0.0469841269841269823515084*var_1*var_3*var_36 + 0.0006349206349206349200842*var_743 + 0.0069841269841269841209264*var_90 + 0.0101587301587301587213474*var_121 + var_850 + 0.0165079365079365096569131*var_833 + 0.0038095238095238095205053*var_1287 + var_959 + var_1284 + var_770; + A[96] = 16.0000000000000000000000000*var_1290*var_13/(var_14*var_14*var_14); + A[561] = A[96]; + const double var_1291 = 2.0000000000000000000000000*var_1*var_216*var_3 + var_142; + const double var_1292 = 25.8888888888888857309211744*var_136 + 18.0000000000000000000000000*var_212 + 7.8888888888888883954564335*var_89; + const double var_1293 = 1.4476190476190478051421451*var_16*var_223; + const double var_1294 = 17.8000000000000007105427358*var_49 + 23.0000000000000000000000000*var_5 + 38.2000000000000028421709430*var_118; + const double var_1295 = var_370 + 0.4000000000000000222044605*var_25 + var_863 + 0.2634920634920634996412048*var_91 + 0.0783068783068783108580746*var_195 + 0.2190476190476190743172680*var_201 + var_331 + 2.1587301587301586103251338*var_131 + 1.7079365079365078639028752*var_16*var_184 + 1.0412698412698413452659452*var_198 + 0.8222222222222222987042528*var_175 + var_1202 + 0.0285714285714285705364279*var_1292*var_7*var_8 + 1.4190476190476191131750738*var_203 + var_1293 + 0.3047619047619047893959987*var_16*var_167 + var_1237 + 0.6031746031746031411202580*var_281 + 0.1365079365079364948076801*var_33 + 0.0317460317460317442694873*var_1294*var_80 + 0.0825396825396825378762244*var_438 + 0.0042328042328042330896820*var_64 + 0.2603174603174603363164863*var_235; + A[198] = 0.0000000000000000000000000; + const double var_1296 = 331.0000000000000000000000000*var_215 + 1889.0000000000000000000000000*var_217; + const double var_1297 = 0.1225396825396825456477856*var_193 + 1.6882539682539683401074626*var_194 + 0.1828571428571428569842539*var_144 + var_904 + 0.7428571428571428825193834*var_198 + var_1209 + 2.1142857142857143237790751*var_826 + 0.0019047619047619047602526*var_1*var_1296*var_3 + 3.9333333333333331260917021*var_153 + var_990 + 1.3371428571428571885348902*var_1291 + 2.0171428571428573484070057*var_143 + 1.5860317460317461257801597*var_383 + 4.0000000000000000000000000*var_497 + 0.2000000000000000111022302*var_1118*var_7*var_8 + 5.4380952380952383151679896*var_280 + 0.4647619047619047649710922*var_117 + 0.0533333333333333367565210*var_88 + 2.2095238095238096676098394*var_147 + 0.0419047619047619029908347*var_500 + 1.6063492063492064154672789*var_16*var_81 + 3.0698412698412700372330164*var_49*var_80 + 0.8685714285714285498585241*var_1288 + 3.0590476190476190154754477*var_283 + 1.4666666666666665630458510*var_282 + 0.7619047619047618624676943*var_208 + 1.5238095238095237249353886*var_185 + 7.7142857142857135244184974*var_131 + 2.1028571428571427581744047*var_103 + 0.9447619047619048027186750*var_20 + 0.2361904761904762006796688*var_178 + 6.6571428571428565845735648*var_132 + 8.1619047619047631059174819*var_281 + 2.3123809523809524257842440*var_140 + var_310 + 0.5790476190476190332390161*var_120 + 0.4374603174603174382539805*var_758 + 1.0419047619047618891130469*var_15*var_759 + 2.3790476190476188556033321*var_205 + 0.3142857142857142793701541*var_112 + 0.4114285714285714212756773*var_108 + 0.4723809523809524013593375*var_467 + 0.4273015873015872934104209*var_16*var_47 + 1.0190476190476192019929158*var_203 + 1.4476190476190478051421451*var_700; + const double var_1298 = var_208 + var_34; + A[866] = A[343]; + A[638] = 0.0000000000000000000000000; + A[7] = var_13*var_228/(var_14*var_14*var_14); + A[472] = A[7]; + const double var_1299 = var_826 + var_271 + var_386; + const double var_1300 = var_205 + var_102 + var_828; + const double var_1301 = var_301 + var_423 + var_383; + const double var_1302 = 4.1388888888888883954564335*var_194 + 4.6000000000000005329070518*var_1299 + 6.2416666666666662521834041*var_197 + 3.5523809523809526389470648*var_280 + 0.2551587301587301404026675*var_758 + 1.7702380952380953882396852*var_140 + 0.3011904761904762306556904*var_120 + 2.0694444444444441977282167*var_1301 + 2.9583333333333330372738601*var_283 + 7.5583333333333335701809119*var_132 + 2.3642857142857143237790751*var_143 + 0.5940476190476190465616924*var_1300 + 0.5000000000000000000000000*var_80*var_984 + 0.7988095238095238581621516*var_148 + 0.5500000000000000444089210*var_146 + 0.8428571428571428603149229*var_15*var_154 + 1.6416666666666666074547720*var_199 + 0.2488095238095238415088062*var_766 + 0.5238095238095238359576911*var_165; + A[1] = 0.0666666666666666657414808*var_13*var_1302/(var_14*var_14*var_14); + A[30] = A[1]; + A[774] = A[280]; + const double var_1303 = 3.6666666666666665186369300*var_51 + 11.3333333333333321490954404*var_110 + 4.4666666666666667850904560*var_209 + 6.2000000000000001776356839*var_47 + 0.1066666666666666735130420*var_186 + 1.1733333333333333392545228*var_145 + var_580; + const double var_1304 = 10.8518518518518511939419113*var_65 + 1.0666666666666666518636930*var_152 + 21.0888888888888885730921174*var_129 + 1.2296296296296296279848548*var_49 + 3.5333333333333332149095440*var_184 + 17.4444444444444428654605872*var_167 + var_170; + const double var_1305 = 0.0571428571428571410728559*var_1304*var_16 + 0.0012698412698412698401684*var_34 + var_1245 + 0.1561904761904761851365464*var_25 + 0.4526984126984127110304712*var_91 + 0.0711111111111111110494321*var_82 + var_1065 + 0.3955555555555555491409336*var_117 + 0.5845502645502645977515499*var_29 + 0.3949206349206348942715294*var_23 + 0.4118518518518518578552801*var_64 + 0.1314285714285714223859003*var_328 + 0.1726984126984127121406942*var_748 + 1.2507936507936507908311796*var_147 + 0.3492063492063491869643599*var_281 + 0.5377777777777777989953734*var_7*var_8*var_89 + 0.9873015873015873467011261*var_178 + 0.2965079365079364981383492*var_282 + var_255 + 1.9428571428571428381104624*var_144 + 0.0006349206349206349200842*var_175 + 0.0952380952380952328084618*var_1303*var_80 + 0.4190476190476191131750738*var_75 + 0.2634920634920634996412048*var_1128 + 0.9904761904761906210481470*var_108; + A[66] = var_13*var_1305/(var_14*var_14*var_14); + A[354] = 0.0000000000000000000000000; + A[606] = 0.0000000000000000000000000; + A[78] = 0.0000000000000000000000000; + A[54] = 0.0000000000000000000000000; + A[388] = 0.0000000000000000000000000; + const double var_1306 = var_141 + var_156; + const double var_1307 = 0.0560846560846560912572123*var_226; + const double var_1308 = 0.1142857142857142821457117*var_439; + const double var_1309 = 0.0184126984126984118150805*var_201 + var_391 + var_1110 + 0.0126984126984126984016843*var_56 + 0.3269841269841269881801793*var_21 + 0.6952380952380953216263038*var_121 + var_1307 + var_859 + 0.1841269841269841389674866*var_467 + 0.0888888888888888922812370*var_33 + 0.4603174603174602919075653*var_88 + 0.0247619047619047627506461*var_16*var_61 + 0.4793650793650793828781786*var_1*var_3*var_41 + 0.7333333333333332815229255*var_760 + 0.2719576719576719536775045*var_65*var_80 + 0.0867724867724867787721621*var_194 + 0.0025396825396825396803369*var_203 + 0.0939682539682539647030168*var_16*var_206 + 0.7936507936507936067371816*var_120 + 0.2539682539682539541558981*var_267 + var_1308 + 0.1269841269841269770779490*var_286 + 0.0368253968253968236301610*var_193 + 0.5619047619047619068766153*var_98 + 0.2952380952380952439106920*var_196 + 0.0920634920634920694837433*var_229 + var_659 + var_1095 + 0.1714285714285714301574615*var_31 + 0.1587301587301587213474363*var_46 + 0.2349206349206349186964360*var_94 + 0.0222222222222222230703093*var_175 + 0.3873015873015873133944353*var_140 + var_190 + 0.0476190476190476164042309*var_232 + 0.0929100529100529148873733*var_195 + 0.0507936507936507936067372*var_1306 + 0.3333333333333333148296163*var_450; + A[248] = 32.0000000000000000000000000*var_13*var_1309/(var_14*var_14*var_14); + A[197] = 0.0000000000000000000000000; + A[457] = 0.0000000000000000000000000; + A[167] = 0.0000000000000000000000000; + A[581] = 0.0000000000000000000000000; + A[214] = A[127]; + A[570] = 0.0000000000000000000000000; + A[179] = 0.0000000000000000000000000; + A[109] = 0.0000000000000000000000000; + A[183] = A[96]; + A[147] = 0.0000000000000000000000000; + const double var_1310 = var_20 + var_42; + A[587] = A[64]; + A[844] = 0.0000000000000000000000000; + const double var_1311 = var_39*var_8 + 0.6000000000000000888178420*var_206 + var_40*var_7 + 1.2000000000000001776356839*var_154; + const double var_1312 = 0.0190476190476190493372499*var_16*var_427 + 0.0338624338624338647174561*var_49*var_80 + 0.0888888888888888922812370*var_549 + 0.0158730158730158721347436*var_550; + const double var_1313 = var_207 + var_91; + const double var_1314 = var_287 + var_386; + const double var_1315 = var_120 + var_205; + const double var_1316 = var_146 + var_760; + const double var_1317 = var_229 + var_196; + const double var_1318 = var_97 + var_20; + const double var_1319 = var_233 + var_1318; + const double var_1320 = 0.3333333333333333148296163*var_257 + 0.5714285714285713968507707*var_280; + const double var_1321 = var_267 + var_142; + const double var_1322 = var_408 + var_88; + const double var_1323 = 0.2857142857142856984253854*var_1321 + 0.2063492063492063377516672*var_195 + 0.3809523809523809312338471*var_201 + var_189 + 0.0952380952380952328084618*var_121 + 0.1428571428571428492126927*var_283 + var_125*var_80 + 0.1904761904761904656169236*var_1322 + 1.0952380952380951217861593*var_132; + const double var_1324 = var_492 + 0.0019047619047619047602526*var_1319 + var_1285 + var_395 + 0.0247619047619047627506461*var_367 + 0.0800000000000000016653345*var_1320 + 0.0012698412698412698401684*var_21 + 0.0063492063492063492008421*var_1317 + 0.0006349206349206349200842*var_1313 + var_127 + 0.0647619047619047566444195*var_52 + 0.0097354497354497360195325*var_65*var_80 + 0.0171428571428571437096355*var_1*var_3*var_41 + 0.0031746031746031746004211*var_18 + 0.0114285714285714285615159*var_22 + 0.0120634920634920643489618*var_129*var_16 + 0.0215873015873015890175868*var_197 + 0.0234920634920634911757542*var_1314 + var_1312 + 0.0533333333333333367565210*var_1323 + 0.0082539682539682548284565*var_66 + 0.0730158730158730201464934*var_410 + 0.0317460317460317442694873*var_175 + 0.0209523809523809514954173*var_1316 + 0.0520634920634920617121821*var_198 + 0.4000000000000000222044605*var_769 + 0.0380952380952380986744998*var_1315 + 0.0507936507936507936067372*var_271 + var_1068; + A[104] = 32.0000000000000000000000000*var_13*var_1324/(var_14*var_14*var_14); + A[569] = A[104]; + A[502] = A[37]; + A[615] = A[5]; + A[398] = A[253]; + A[215] = A[157]; + A[207] = 0.0000000000000000000000000; + A[609] = 0.0000000000000000000000000; + A[583] = 0.0000000000000000000000000; + const double var_1325 = 1.4000000000000001332267630*var_215 + 2.9873015873015873467011261*var_101 + 4.8571428571428567622092487*var_37 + 3.1460317460317459570262599*var_161 + 1.8698412698412698595973325*var_45; + const double var_1326 = 46.0000000000000000000000000*var_158 + 15.3333333333333321490954404*var_186 + 20.6666666666666642981908808*var_145 + 61.0000000000000000000000000*var_125 + var_514 + 5.7777777777777776790912867*var_81; + const double var_1327 = var_33 + var_9; + const double var_1328 = 0.9460317460317460014351809*var_164 + 0.3161904761904761884672155*var_257 + 0.0120634920634920643489618*var_28 + 0.6387301587301587035838679*var_144 + 0.0349206349206349214719936*var_56 + 0.5066666666666667095952903*var_25 + 1.5085714285714286742035029*var_75 + 0.2253968253968254009667049*var_1327 + 0.0400000000000000008326673*var_1127*var_7*var_8 + 0.2006349206349206382160588*var_23 + 0.0869841269841269831841757*var_203 + 0.1485714285714285765038767*var_52 + 0.0203174603174603174426949*var_207 + 0.1225396825396825456477856*var_201 + 0.3168253968253968433366197*var_148 + 0.2038095238095238015407773*var_271 + 0.3860317460317460591667782*var_31 + 0.2787301587301587169065442*var_178 + 2.0000000000000000000000000*var_538 + 0.1441269841269841311959254*var_20 + 0.0057142857142857142807579*var_381 + 0.1790476190476190387901312*var_208 + 0.1964021164021164111979090*var_47*var_80 + 0.4609523809523809467769695*var_103 + 0.0520634920634920617121821*var_131 + 0.3619047619047619512855363*var_185 + 0.0076190476190476190410106*var_1326*var_15 + var_595 + 0.1346031746031746134661944*var_129*var_16 + 0.1358730158730158676938515*var_197 + 0.0253968253968253968033686*var_533 + 0.9574603174603174560175489*var_147 + var_954 + 0.2000000000000000111022302*var_1*var_1325*var_3 + 0.0146031746031746040292987*var_19 + 0.5409523809523809623200918*var_16*var_223 + 0.6120634920634920872473117*var_22 + 0.0491005291005291027994772*var_253 + 0.1917460317460317476001563*var_132 + 1.4323809523809523103210495*var_76 + 0.2755555555555555535818257*var_108 + 0.8546031746031745868208418*var_149 + 0.2812698412698412808730097*var_91 + var_450; + A[14] = 2.0000000000000000000000000*var_13*var_1328/(var_14*var_14*var_14); + A[479] = A[14]; + A[883] = 0.0000000000000000000000000; + A[543] = 0.0000000000000000000000000; + A[625] = A[160]; + A[704] = 0.0000000000000000000000000; + A[339] = A[281]; + A[596] = A[131]; + A[495] = A[1]; + A[116] = 0.0000000000000000000000000; + A[853] = 0.0000000000000000000000000; + A[731] = 0.0000000000000000000000000; + const double var_1329 = var_1026 + var_500; + A[21] = 0.0000000000000000000000000; + A[28] = 0.0000000000000000000000000; + A[842] = 0.0000000000000000000000000; + A[351] = 0.0000000000000000000000000; + A[232] = 0.0000000000000000000000000; + A[772] = A[220]; + A[724] = 0.0000000000000000000000000; + A[579] = 0.0000000000000000000000000; + A[261] = 0.0000000000000000000000000; + A[764] = 0.0000000000000000000000000; + const double var_1330 = 0.0380952380952380986744998*var_38 + 0.0069841269841269841209264*var_230; + A[725] = 0.0000000000000000000000000; + const double var_1331 = 3.5333333333333332149095440*var_51 + 21.0888888888888885730921174*var_118 + 17.4444444444444428654605872*var_5 + 1.0666666666666666518636930*var_110 + 10.8518518518518511939419113*var_49 + var_774 + 1.2296296296296296279848548*var_65; + const double var_1332 = 6.2000000000000001776356839*var_81 + 3.6666666666666665186369300*var_184 + 4.4666666666666667850904560*var_169 + 0.1066666666666666735130420*var_222 + var_1028 + 1.1733333333333333392545228*var_206 + 11.3333333333333321490954404*var_152; + const double var_1333 = 0.4118518518518518578552801*var_18 + 0.1561904761904761851365464*var_103 + 0.1726984126984127121406942*var_506 + 0.9904761904761906210481470*var_112 + 0.0711111111111111110494321*var_236 + 0.2965079365079364981383492*var_97 + 0.4526984126984127110304712*var_20 + 0.5377777777777777989953734*var_1*var_3*var_43 + 1.2507936507936507908311796*var_31 + 1.9428571428571428381104624*var_24 + 0.0012698412698412698401684*var_149 + 0.5845502645502645977515499*var_30 + 0.3492063492063491869643599*var_98 + 0.1314285714285714223859003*var_179 + 0.3955555555555555491409336*var_19 + 0.3949206349206348942715294*var_22 + 0.9873015873015873467011261*var_28 + var_1194 + 0.0571428571428571410728559*var_1331*var_15 + 0.2634920634920634996412048*var_486 + 0.0006349206349206349200842*var_267 + 0.4190476190476191131750738*var_76 + 0.0952380952380952328084618*var_1332*var_80 + var_651 + var_1019; + A[832] = A[222]; + const double var_1334 = var_147 + var_66 + var_197; + const double var_1335 = 0.0069841269841269841209264*var_91; + const double var_1336 = var_284 + var_288; + const double var_1337 = var_321 + var_363; + const double var_1338 = 0.0666666666666666657414808*var_199 + 0.4000000000000000222044605*var_200 + 0.3333333333333333148296163*var_97; + const double var_1339 = var_102 + var_1338; + const double var_1340 = var_1335 + var_1330 + 0.0761904761904761973489997*var_1336 + 0.0114285714285714285615159*var_280 + 0.1777777777777777845624740*var_149 + 0.0148148148148148153802062*var_30 + var_256 + var_727 + 0.0031746031746031746004211*var_229 + 0.0846560846560846513852994*var_159 + 0.0571428571428571410728559*var_1339 + 0.1428571428571428492126927*var_166 + var_1182 + 0.0287830687830687853567824*var_15*var_49 + 0.1015873015873015872134744*var_378 + 0.0088888888888888888811790*var_1337 + 0.0507936507936507936067372*var_236 + 0.0012698412698412698401684*var_1334 + 0.0253968253968253968033686*var_257 + 0.0774603174603174654544446*var_22 + 0.0033862433862433863850094*var_18 + var_958 + 0.1460317460317460402929868*var_15*var_158 + 0.0165079365079365096569131*var_119 + 0.0596825396825396842226397*var_108 + var_1215 + 0.0044444444444444444405895*var_178 + 0.0025396825396825396803369*var_44 + 0.0063492063492063492008421*var_920 + 0.0526984126984126957649046*var_7*var_8*var_89 + 0.0069841269841269841209264*var_117 + var_1017 + var_1284 + 0.0965079365079365147916945*var_144 + 1.3333333333333332593184650*var_655; + A[355] = 0.0000000000000000000000000; + A[811] = 0.0000000000000000000000000; + A[406] = 0.0000000000000000000000000; + A[63] = var_13*var_586/(var_14*var_14*var_14); + A[557] = A[63]; + const double var_1341 = 0.0262433862433862456764455*var_74; + const double var_1342 = var_347 + var_144; + A[413] = 0.0000000000000000000000000; + A[511] = 0.0000000000000000000000000; + const double var_1343 = 0.0380952380952380986744998*var_98; + const double var_1344 = var_1343 + 0.0495238095238095255012922*var_149 + 0.0069841269841269841209264*var_141 + var_241; + const double var_1345 = 0.0533333333333333367565210*var_155; + const double var_1346 = var_199 + var_235; + const double var_1347 = var_378 + var_102; + const double var_1348 = var_200 + var_205; + const double var_1349 = var_130 + var_203; + const double var_1350 = var_175 + var_723; + const double var_1351 = 71.0000000000000000000000000*var_163 + 103.0000000000000000000000000*var_114 + 61.0000000000000000000000000*var_136; + const double var_1352 = 106.0000000000000000000000000*var_215 + var_705; + const double var_1353 = 8.0000000000000000000000000*var_201 + var_1351*var_7*var_8 + 22.3333333333333321490954404*var_195 + 12.3333333333333321490954404*var_16*var_65 + 89.0000000000000000000000000*var_131 + var_1*var_1352*var_3 + 137.0000000000000000000000000*var_132 + 104.0000000000000000000000000*var_21 + 43.0000000000000000000000000*var_139 + 10.3333333333333321490954404*var_64 + 31.0000000000000000000000000*var_287 + 31.3333333333333321490954404*var_47*var_80 + 75.6666666666666571927635232*var_194 + 151.0000000000000000000000000*var_197; + const double var_1354 = 0.1447619047619047583097540*var_189 + var_10 + 0.0412698412698412689381122*var_1350 + 0.1066666666666666735130420*var_870 + 0.0285714285714285705364279*var_1346 + 0.0177777777777777777623580*var_1349 + var_687 + 0.1600000000000000033306691*var_1320 + var_529 + 0.0698412698412698429439871*var_281 + 0.0044444444444444444405895*var_90 + var_1344 + 0.0342857142857142874192711*var_22 + 0.0704761904761904700578157*var_367 + var_1345 + 0.0444444444444444461406185*var_1161 + 0.0228571428571428571230317*var_283 + 0.0311111111111111102167648*var_282 + 0.0025396825396825396803369*var_196 + var_1251 + var_783 + 0.0019047619047619047602526*var_284 + 0.0304761904761904761640423*var_1347 + var_688 + 0.0400000000000000008326673*var_97 + 0.0685714285714285748385421*var_1348 + var_633 + 0.0780952380952380925682732*var_145*var_15 + var_403 + 0.0006349206349206349200842*var_1353; + A[654] = A[189]; + A[107] = 0.0000000000000000000000000; + A[356] = 0.0000000000000000000000000; + A[136] = 0.0000000000000000000000000; + A[438] = 0.0000000000000000000000000; + A[675] = A[7]; + A[152] = A[65]; + A[582] = 0.0000000000000000000000000; + A[481] = 0.0000000000000000000000000; + const double var_1355 = var_211 + 2.0000000000000000000000000*var_87; + A[665] = 0.0000000000000000000000000; + A[801] = A[191]; + const double var_1356 = 0.0139682539682539682418527*var_18 + 0.0190476190476190493372499*var_35; + A[15] = 0.0000000000000000000000000; + A[17] = 0.0000000000000000000000000; + A[446] = 0.0000000000000000000000000; + const double var_1357 = var_338*var_80 + 3.9444444444444441977282167*var_282 + var_752 + 4.9444444444444437536390069*var_91 + 84.9444444444444428654605872*var_117; + A[205] = 0.0000000000000000000000000; + A[287] = 0.0000000000000000000000000; + A[364] = A[132]; + A[117] = 0.0000000000000000000000000; + const double var_1358 = var_61 + var_129; + A[411] = 0.0000000000000000000000000; + A[380] = 0.0000000000000000000000000; + A[20] = 0.0000000000000000000000000; + A[76] = 0.0000000000000000000000000; + const double var_1359 = 1.0296296296296296723937758*var_65 + 0.1756613756613756849311869*var_49 + 0.3714285714285714412596917*var_184 + 3.0126984126984126532988739*var_167 + 0.5047619047619048560093802*var_169 + 2.4920634920634920916882038*var_129; + A[55] = 0.0000000000000000000000000; + const double var_1360 = 0.0914285714285714284921269*var_155; + const double var_1361 = var_205 + var_91; + const double var_1362 = var_229 + var_42; + const double var_1363 = 0.0552380952380952389146884*var_1249 + var_702 + 0.0317460317460317442694873*var_232 + 0.0063492063492063492008421*var_1169 + 0.0819047619047619107623959*var_386 + 0.0260317460317460308560911*var_203 + 0.0285714285714285705364279*var_332 + var_673 + 0.0419047619047619029908347*var_212*var_7*var_8 + var_1360 + 0.0266666666666666683782605*var_285 + 0.0088888888888888888811790*var_280 + 0.0228571428571428571230317*var_131 + 0.0006349206349206349200842*var_726 + var_1171 + 0.0196825396825396833899724*var_94 + 0.0031746031746031746004211*var_1221 + 0.0146031746031746040292987*var_1105 + var_511 + 0.0400000000000000008326673*var_271 + 0.0082539682539682548284565*var_1361 + 0.0273015873015873024309830*var_1362; + A[249] = 16.0000000000000000000000000*var_13*var_1363/(var_14*var_14*var_14); + A[278] = A[249]; + A[49] = 0.0000000000000000000000000; + const double var_1364 = 15.8533333333333334991266383*var_89 + 20.4933333333333358439176664*var_55 + 3.6666666666666665186369300*var_163 + 8.2400000000000002131628207*var_104 + 3.5066666666666668206175927*var_114 + 11.7466666666666679219588332*var_115; + const double var_1365 = 0.3714285714285714412596917*var_51 + 0.1756613756613756849311869*var_65 + 2.4920634920634920916882038*var_118 + 0.5047619047619048560093802*var_209 + 3.0126984126984126532988739*var_5 + 1.0296296296296296723937758*var_49; + const double var_1366 = 0.6497354497354498326089356*var_74; + const double var_1367 = var_149 + var_144; + const double var_1368 = var_1137 + var_24; + const double var_1369 = 0.1663492063492063577356816*var_1367 + 0.2000000000000000111022302*var_1293 + 0.0082539682539682548284565*var_94 + 0.0520634920634920617121821*var_232 + 0.0615873015873015863808071*var_91 + var_1366 + 0.4317460317460317664739478*var_16*var_57 + 0.2355555555555555458102646*var_9 + 0.2177777777777777645784596*var_20 + var_584 + 0.0694179894179894202421721*var_47*var_80 + var_1163 + 0.3415873015873016060872658*var_16*var_61 + 0.6510052910052910313254415*var_80*var_81 + 1.1238095238095238137532306*var_35 + 0.6793650793650793939804089*var_29 + 0.1149206349206349231373281*var_97 + 0.6019047619047619424037521*var_75 + 0.2095238095238095565875369*var_25 + 0.6450793650793650302333049*var_22 + 0.6201058201058201602151598*var_18 + 0.7853968253968254265018345*var_19 + 0.0296296296296296307604123*var_64 + var_1135 + 0.8088888888888888795136722*var_23 + 0.0304761904761904761640423*var_995 + 0.4000000000000000222044605*var_1365*var_15 + 0.8165079365079365159019176*var_108 + 0.0006349206349206349200842*var_1*var_1238*var_3 + 0.4590476190476190376799082*var_32 + 0.0476190476190476164042309*var_1364*var_7*var_8 + 0.1479365079365079493900481*var_33 + 1.6723809523809523014392653*var_112 + 0.5441269841269841256448103*var_28 + 0.1752380952380952483515841*var_21 + 0.1841269841269841389674866*var_98 + var_1038 + 1.2698412698412697707794905*var_30 + 0.8406349206349206237831595*var_31 + 0.0008465608465608465962524*var_286 + 1.4349206349206349297986662*var_34 + var_785 + 0.0609523809523809523280846*var_292 + 2.0000000000000000000000000*var_1368; + A[11] = var_13*var_1369/(var_14*var_14*var_14); + A[330] = A[11]; + A[298] = 0.0000000000000000000000000; + A[500] = A[35]; + A[352] = 0.0000000000000000000000000; + const double var_1370 = var_475 + var_1115; + const double var_1371 = var_1197 + var_606; + const double var_1372 = var_600 + var_480; + const double var_1373 = 0.2285714285714285642914234*var_840 + var_1172 + 0.2857142857142856984253854*var_1372 + 0.3238095238095238248554608*var_472 + var_601 + 0.1428571428571428492126927*var_1198 + 0.9142857142857142571656937*var_1173 + 0.0380952380952380986744998*var_462 + 1.1428571428571427937015414*var_1371 + var_248 + 0.0571428571428571410728559*var_1370; + const double var_1374 = 14.3333333333333321490954404*var_81 + 8.6666666666666660745477202*var_65 + 41.0000000000000000000000000*var_186; + const double var_1375 = 13.0000000000000000000000000*var_22 + var_874 + var_1282*var_7*var_8; + A[60] = A[2]; + A[635] = 0.0000000000000000000000000; + A[507] = A[42]; + A[316] = 0.0000000000000000000000000; + A[185] = A[156]; + const double var_1376 = var_487 + var_1318; + A[171] = 0.0000000000000000000000000; + A[182] = A[66]; + A[151] = A[35]; + A[463] = 0.0000000000000000000000000; + A[697] = 0.0000000000000000000000000; + A[193] = 32.0000000000000000000000000*var_13*var_1354/(var_14*var_14*var_14); + A[658] = A[193]; + A[614] = 0.0000000000000000000000000; + A[891] = A[194]; + A[88] = 0.0000000000000000000000000; + A[547] = 0.0000000000000000000000000; + A[459] = 0.0000000000000000000000000; + const double var_1377 = 11.7466666666666679219588332*var_101 + 8.2400000000000002131628207*var_37 + 3.5066666666666668206175927*var_204 + 3.6666666666666665186369300*var_36 + 20.4933333333333358439176664*var_161 + 15.8533333333333334991266383*var_43; + const double var_1378 = 109.0000000000000000000000000*var_136 + 467.0000000000000000000000000*var_150 + 2291.0000000000000000000000000*var_89 + 221.0000000000000000000000000*var_174 + 2293.0000000000000000000000000*var_163; + const double var_1379 = 0.2495238095238095366035225*var_19; + const double var_1380 = var_24 + var_34; + const double var_1381 = 0.1841269841269841389674866*var_281 + 0.6450793650793650302333049*var_23 + var_536 + 0.6201058201058201602151598*var_64 + 0.4590476190476190376799082*var_9 + 0.5441269841269841256448103*var_178 + 0.0615873015873015863808071*var_20 + 0.2000000000000000111022302*var_433 + 0.0520634920634920617121821*var_378 + 0.8406349206349206237831595*var_147 + var_1379 + 2.0000000000000000000000000*var_1342 + 1.1238095238095238137532306*var_164 + var_1345 + 0.4317460317460317664739478*var_15*var_158 + 0.8165079365079365159019176*var_112 + 1.6723809523809523014392653*var_108 + var_1031 + 0.0082539682539682548284565*var_283 + 0.3415873015873016060872658*var_15*var_85 + 0.1149206349206349231373281*var_282 + 0.7853968253968254265018345*var_117 + 1.2698412698412697707794905*var_29 + 0.2355555555555555458102646*var_32 + var_1366 + 0.2177777777777777645784596*var_91 + 0.0008465608465608465962524*var_287 + 0.0006349206349206349200842*var_1378*var_7*var_8 + 0.6793650793650793939804089*var_30 + 0.0476190476190476164042309*var_1*var_1377*var_3 + 0.4000000000000000222044605*var_1359*var_16 + 1.4349206349206349297986662*var_149 + 0.0694179894179894202421721*var_80*var_81 + 0.1663492063492063577356816*var_1380 + 0.6510052910052910313254415*var_47*var_80 + var_1204 + 0.2095238095238095565875369*var_103 + 0.0609523809523809523280846*var_153 + 0.1479365079365079493900481*var_148 + 0.8088888888888888795136722*var_22 + 0.0296296296296296307604123*var_18 + 0.6019047619047619424037521*var_76 + 0.1752380952380952483515841*var_280 + 0.0304761904761904761640423*var_1121; + A[8] = var_13*var_1381/(var_14*var_14*var_14); + A[173] = 0.0000000000000000000000000; + A[893] = A[254]; + const double var_1382 = 15.7333333333333325043668083*var_150 + 18.0000000000000000000000000*var_104 + 12.7333333333333325043668083*var_163 + 4.0666666666666664298190881*var_89 + 2.2666666666666666074547720*var_115; + const double var_1383 = var_25 + var_288; + const double var_1384 = 15.1428571428571423496123316*var_184 + 7.4761904761904753868861917*var_65 + 14.0000000000000000000000000*var_1358; + const double var_1385 = var_708 + 0.2171428571428571374646310*var_38 + 0.0533333333333333367565210*var_117 + 0.1942857142857142838110462*var_314 + 0.1041269841269841234243643*var_15*var_49 + 0.0209523809523809514954173*var_363 + 0.0380952380952380986744998*var_22 + 0.1231746031746031727616142*var_30 + var_666 + 0.5828571428571428514331387*var_103 + var_1160 + 0.0266666666666666683782605*var_1384*var_16 + 0.0819047619047619107623959*var_1*var_3*var_43 + 0.1523809523809523946979994*var_234 + 1.6000000000000000888178420*var_75 + 0.1142857142857142821457117*var_280 + 0.0571428571428571410728559*var_1382*var_7*var_8 + 0.0628571428571428614251460*var_205 + 1.5047619047619049670316826*var_149 + var_10 + 1.4571428571428570730716956*var_284 + 0.1828571428571428569842539*var_23 + 0.2419047619047619002152771*var_143 + 0.2800000000000000266453526*var_102 + 2.0000000000000000000000000*var_1356 + 1.4095238095238096232009184*var_147 + var_165 + 0.2476190476190476552620368*var_378 + 0.0609523809523809523280846*var_410 + 0.5904761904761904878213841*var_236 + 0.0990476190476190510025845*var_33 + 0.1219047619047619046561692*var_233 + 0.1980952380952381020051689*var_118*var_15 + 0.0723809523809523791548770*var_32 + 0.4723809523809524013593375*var_91 + 0.5428571428571428159060019*var_148 + 0.0114285714285714285615159*var_34 + 0.0215873015873015890175868*var_193 + 0.3238095238095238248554608*var_210 + 0.0400000000000000008326673*var_20 + 0.5104761904761905277894130*var_178 + 0.0304761904761904761640423*var_1243 + 0.0514285714285714276594597*var_283 + 0.0342857142857142874192711*var_82 + 1.2380952380952381375323057*var_144 + var_248 + 0.5714285714285713968507707*var_1383 + var_967; + A[224] = 8.0000000000000000000000000*var_13*var_1385/(var_14*var_14*var_14); + A[689] = A[224]; + A[754] = 0.0000000000000000000000000; + A[696] = 0.0000000000000000000000000; + const double var_1386 = 0.0228571428571428571230317*var_288; + const double var_1387 = 0.7333333333333332815229255*var_618 + 0.4793650793650793828781786*var_136*var_7*var_8 + 0.0476190476190476164042309*var_378 + 0.1714285714285714301574615*var_147 + 0.0939682539682539647030168*var_145*var_15 + 0.0184126984126984118150805*var_143 + 0.5619047619047619068766153*var_281 + 0.6952380952380953216263038*var_132 + 0.1587301587301587213474363*var_151 + var_1151 + 0.0867724867724867787721621*var_195 + 0.0247619047619047627506461*var_15*var_85 + 0.2349206349206349186964360*var_283 + var_264 + 0.1269841269841269770779490*var_287 + 0.4603174603174602919075653*var_271 + 0.0025396825396825396803369*var_146 + 0.3269841269841269881801793*var_280 + 0.2719576719576719536775045*var_49*var_80 + 0.0888888888888888922812370*var_148 + 0.1841269841269841389674866*var_367 + 0.0126984126984126984016843*var_284 + var_1307 + var_1386 + var_1108 + 0.0929100529100529148873733*var_194 + 0.3873015873015873133944353*var_198 + 0.3333333333333333148296163*var_525 + 0.2539682539682539541558981*var_175 + 0.7936507936507936067371816*var_131 + var_770 + 0.0507936507936507936067372*var_763 + 0.0222222222222222230703093*var_267 + var_730 + 0.2952380952380952439106920*var_197 + 0.0920634920634920694837433*var_205 + 0.0368253968253968236301610*var_139 + var_807; + A[341] = 32.0000000000000000000000000*var_13*var_1387/(var_14*var_14*var_14); + A[806] = A[341]; + A[338] = A[251]; + const double var_1388 = var_19 + var_410; + const double var_1389 = var_141 + var_826; + const double var_1390 = var_271 + var_283; + const double var_1391 = var_731 + var_146; + const double var_1392 = var_1109 + 0.1085714285714285687323155*var_282 + 0.1809523809523809756427681*var_196 + 0.5428571428571428159060019*var_1338 + 0.1466666666666666674068153*var_232 + var_1141 + 0.0768253968253968244628282*var_195 + 0.0571428571428571410728559*var_1391 + 0.0165079365079365096569131*var_383 + var_1146 + var_965 + 0.0171428571428571437096355*var_969 + 0.0196825396825396833899724*var_80*var_81 + 0.0038095238095238095205053*var_1390 + 0.0609523809523809523280846*var_32 + 0.1619047619047619124277304*var_280 + 0.2952380952380952439106920*var_120 + 0.9142857142857142571656937*var_352 + 0.1333333333333333314829616*var_140 + 0.0742857142857142882519383*var_175 + 0.1371428571428571496770843*var_94 + 0.0495238095238095255012922*var_198 + var_875 + 0.0057142857142857142807579*var_1388 + 0.0120634920634920643489618*var_79 + 0.0247619047619047627506461*var_117 + 0.4190476190476191131750738*var_98 + 0.0241269841269841286979236*var_193 + 0.0076190476190476190410106*var_132 + 0.1009523809523809462218580*var_16*var_222 + 0.1485714285714285765038767*var_1291 + 0.1390476190476190587741456*var_1*var_214*var_3 + 0.4285714285714285476380780*var_21 + 0.0761904761904761973489997*var_386 + 0.2380952380952380820211545*var_349 + 0.0095238095238095246686250*var_828 + 0.1123809523809523869264382*var_197 + 0.1580952380952380942336077*var_205 + 0.0793650793650793606737182*var_758 + 0.0400000000000000008326673*var_1389 + 0.0692063492063492019523707*var_194 + 0.3047619047619047893959987*var_121 + var_1360 + 0.0546031746031746048619659*var_16*var_47 + 0.0552380952380952389146884*var_1298; + A[434] = 64.0000000000000000000000000*var_13*var_1392/(var_14*var_14*var_14); + A[899] = A[434]; + A[662] = 0.0000000000000000000000000; + A[848] = 0.0000000000000000000000000; + A[176] = 0.0000000000000000000000000; + A[396] = A[193]; + A[422] = A[74]; + const double var_1393 = 2.1619047619047622177390622*var_115 + 1.8761904761904764082913744*var_89 + 6.8000000000000007105427358*var_104 + 4.6380952380952384928036736*var_150 + 2.2380952380952381375323057*var_55; + A[870] = 0.0000000000000000000000000; + const double var_1394 = var_219*var_80 + var_75; + const double var_1395 = var_304 + 19.0000000000000000000000000*var_234 + 116.0000000000000000000000000*var_112 + 38.0000000000000000000000000*var_117 + 13.0000000000000000000000000*var_64 + 188.0000000000000000000000000*var_31 + 54.3333333333333285963817616*var_29 + 8.0000000000000000000000000*var_147 + var_1013 + 103.0000000000000000000000000*var_28 + 23.0000000000000000000000000*var_1376 + 208.0000000000000000000000000*var_24 + 52.0000000000000000000000000*var_9 + var_408; + const double var_1396 = var_1225 + 0.0317460317460317442694873*var_230 + var_1341 + 0.0571428571428571410728559*var_1117 + 0.0264550264550264535579061*var_139 + 0.0412698412698412689381122*var_108 + 0.0342857142857142874192711*var_7*var_8*var_89 + 0.0590476190476190501699172*var_44 + var_911 + 0.0609523809523809523280846*var_1394 + 0.0666666666666666657414808*var_363 + 0.0103703703703703700722549*var_15*var_49 + var_561 + 0.0044444444444444444405895*var_286 + 0.0539682539682539708092435*var_486 + 0.0057142857142857142807579*var_231 + 0.0222222222222222230703093*var_149 + 0.0253968253968253968033686*var_98 + var_1011 + 0.0323809523809523783222097*var_126 + var_636 + var_258 + var_933 + 0.0552380952380952389146884*var_52 + var_1335 + 0.0006349206349206349200842*var_1395; + A[342] = 32.0000000000000000000000000*var_13*var_1396/(var_14*var_14*var_14); + A[371] = A[342]; + A[212] = A[67]; + const double var_1397 = var_203 + var_148; + A[115] = 0.0000000000000000000000000; + A[331] = A[41]; + A[452] = 0.0000000000000000000000000; + A[623] = A[158]; + const double var_1398 = 29.0000000000000000000000000*var_174 + 63.4000000000000056843418861*var_89 + 32.6000000000000014210854715*var_755 + 59.8000000000000042632564146*var_136; + A[761] = 0.0000000000000000000000000; + const double var_1399 = 52.0000000000000000000000000*var_32 + 208.0000000000000000000000000*var_144 + 13.0000000000000000000000000*var_18 + 38.0000000000000000000000000*var_19 + 116.0000000000000000000000000*var_108 + var_1180 + 19.0000000000000000000000000*var_233 + var_533 + 8.0000000000000000000000000*var_31 + 23.0000000000000000000000000*var_1329 + 103.0000000000000000000000000*var_178 + 54.3333333333333285963817616*var_30 + var_411 + 188.0000000000000000000000000*var_147; + const double var_1400 = var_1341 + 0.0323809523809523783222097*var_314 + 0.0590476190476190501699172*var_90 + 0.0057142857142857142807579*var_363 + 0.0317460317460317442694873*var_102 + 0.0412698412698412689381122*var_112 + 0.0342857142857142874192711*var_1*var_3*var_43 + 0.0222222222222222230703093*var_34 + 0.0264550264550264535579061*var_193 + var_540 + var_398 + var_353 + 0.0103703703703703700722549*var_16*var_65 + 0.0571428571428571410728559*var_1242 + var_653 + var_1009 + var_1330 + 0.0044444444444444444405895*var_287 + 0.0666666666666666657414808*var_231 + var_1179 + 0.0006349206349206349200842*var_1399 + 0.0253968253968253968033686*var_281 + 0.0552380952380952389146884*var_185 + var_703 + 0.0539682539682539708092435*var_1128 + 0.0609523809523809523280846*var_1190; + A[252] = 32.0000000000000000000000000*var_13*var_1400/(var_14*var_14*var_14); + A[717] = A[252]; + A[266] = 0.0000000000000000000000000; + A[580] = 0.0000000000000000000000000; + A[784] = 0.0000000000000000000000000; + A[389] = 0.0000000000000000000000000; + const double var_1401 = 15.8000000000000007105427358*var_209 + 20.6000000000000014210854715*var_51 + 7.3555555555555560687253092*var_65 + 62.9333333333333300174672331*var_118 + 42.8888888888888857309211744*var_49 + 5.2000000000000001776356839*var_110; + A[830] = A[162]; + A[392] = A[73]; + A[387] = 0.0000000000000000000000000; + A[753] = 0.0000000000000000000000000; + A[894] = A[284]; + A[286] = 0.0000000000000000000000000; + A[875] = 0.0000000000000000000000000; + A[748] = A[283]; + A[679] = A[127]; + A[138] = 0.0000000000000000000000000; + A[534] = A[69]; + A[552] = 0.0000000000000000000000000; + A[16] = 0.0000000000000000000000000; + A[640] = 0.0000000000000000000000000; + const double var_1402 = var_257 + var_9; + A[259] = 0.0000000000000000000000000; + A[637] = 0.0000000000000000000000000; + A[51] = 0.0000000000000000000000000; + const double var_1403 = var_46 + var_288; + A[13] = 2.0000000000000000000000000*var_13*var_597/(var_14*var_14*var_14); + A[855] = A[13]; + A[426] = A[194]; + A[847] = 0.0000000000000000000000000; + const double var_1404 = var_97 + var_760 + var_9; + const double var_1405 = 0.0228571428571428571230317*var_142; + const double var_1406 = var_392 + var_445; + const double var_1407 = 6.4000000000000003552713679*var_163 + 23.0000000000000000000000000*var_136; + const double var_1408 = var_1107 + var_715 + 0.0914285714285714284921269*var_200 + 0.0939682539682539647030168*var_198 + 0.0888888888888888922812370*var_271 + 0.0438095238095238120878960*var_1404 + 0.0012698412698412698401684*var_178 + 0.1371428571428571496770843*var_189 + 0.3333333333333333148296163*var_912 + 0.0495238095238095255012922*var_283 + 0.0031746031746031746004211*var_1407*var_7*var_8 + 0.1244444444444444408670591*var_988 + 0.0300529100529100534622273*var_195 + var_1344 + 0.0196825396825396833899724*var_721 + var_1386 + var_1308 + 0.0019047619047619047602526*var_1374*var_15 + 0.0044444444444444444405895*var_66 + 0.1384126984126984039047414*var_132 + 0.0444444444444444461406185*var_229 + var_1312 + 0.1257142857142857228502919*var_280 + var_337 + 0.1752380952380952483515841*var_202 + 0.0768253968253968244628282*var_1*var_215*var_3 + 0.0120634920634920643489618*var_207 + 0.0304761904761904761640423*var_257 + var_1405 + 0.0215873015873015890175868*var_1092 + 0.2095238095238095565875369*var_1406 + 0.0761904761904761973489997*var_205 + var_738 + 0.0076190476190476190410106*var_674 + var_877 + 0.0082539682539682548284565*var_193; + A[102] = 32.0000000000000000000000000*var_13*var_1408/(var_14*var_14*var_14); + A[825] = A[12]; + A[677] = A[67]; + const double var_1409 = 163.0000000000000000000000000*var_115 + 446.0000000000000000000000000*var_55 + 139.0000000000000000000000000*var_114; + A[393] = A[103]; + A[98] = 16.0000000000000000000000000*var_13*var_1340/(var_14*var_14*var_14); + A[243] = A[98]; + A[27] = 0.0000000000000000000000000; + A[489] = 0.0000000000000000000000000; + A[476] = A[11]; + A[106] = 0.0000000000000000000000000; + const double var_1410 = 83.0000000000000000000000000*var_161 + 229.0000000000000000000000000*var_101; + A[747] = A[282]; + A[487] = 0.0000000000000000000000000; + A[538] = A[73]; + A[706] = A[38]; + A[571] = 0.0000000000000000000000000; + A[871] = 0.0000000000000000000000000; + A[794] = 0.0000000000000000000000000; + A[783] = 0.0000000000000000000000000; + A[577] = 0.0000000000000000000000000; + A[544] = 0.0000000000000000000000000; + A[780] = 0.0000000000000000000000000; + A[708] = A[98]; + const double var_1411 = 226.0000000000000000000000000*var_223 + 41.3333333333333285963817616*var_222 + 141.5000000000000000000000000*var_61 + 6.2777777777777776790912867*var_49 + 84.5000000000000000000000000*var_184; + const double var_1412 = 0.0822222222222222243193102*var_746 + 0.0126984126984126984016843*var_207 + 0.0563492063492063502416762*var_178 + 0.0587301587301587296741090*var_281 + 0.2196825396825396736755209*var_23 + 0.0364021164021164009283460*var_64 + 0.0057142857142857142807579*var_1394 + 0.0296296296296296307604123*var_286 + 0.1707936507936508030436329*var_34 + 0.0644444444444444430875052*var_108 + 0.0608465608465608431831839*var_29 + 0.0019047619047619047602526*var_1411*var_16 + 0.2182539682539682557305127*var_32 + 0.0028571428571428571403790*var_1357 + 0.0244444444444444457242849*var_750 + 0.0742857142857142882519383*var_153 + 0.0007936507936507936501053*var_1398*var_7*var_8; + A[70] = var_13*var_1412/(var_14*var_14*var_14); + A[302] = A[70]; + A[816] = 0.0000000000000000000000000; + A[257] = 0.0000000000000000000000000; + A[490] = 0.0000000000000000000000000; + A[750] = 0.0000000000000000000000000; + A[699] = 0.0000000000000000000000000; + const double var_1413 = var_367 + var_38; + const double var_1414 = 0.0685714285714285748385421*var_881 + 0.1257142857142857228502919*var_1413 + 0.1282539682539682590611818*var_65*var_80 + 0.1504761904761904856009380*var_1*var_3*var_41 + 0.0457142857142857142460635*var_201 + var_960 + 0.0761904761904761973489997*var_23 + 0.1771428571428571296930699*var_19 + var_1356 + 0.1523809523809523946979994*var_24 + 0.1714285714285714301574615*var_88 + 0.0914285714285714284921269*var_30 + var_1343 + 0.0888888888888888922812370*var_287 + var_798 + 0.0228571428571428571230317*var_321 + 0.1428571428571428492126927*var_363 + 0.0780952380952380925682732*var_1154 + 0.0361904761904761895774385*var_20 + 0.0742857142857142882519383*var_9 + 0.2342857142857142915826074*var_44 + 0.2133333333333333470260840*var_31 + 0.0342857142857142874192711*var_861 + 0.0266666666666666683782605*var_847 + 0.1123809523809523869264382*var_148 + 0.0152380952380952380820212*var_196 + 0.0095238095238095246686250*var_28 + 0.0520634920634920617121821*var_29 + 0.0190476190476190493372499*var_94 + var_122 + 0.0253968253968253968033686*var_871 + 0.2704761904761904811600459*var_112 + var_1405 + 0.1485714285714285765038767*var_106 + var_1049 + 0.0419047619047619029908347*var_849 + 0.1561904761904761851365464*var_182 + 0.0495238095238095255012922*var_141 + 0.0076190476190476190410106*var_1375; + A[223] = 8.0000000000000000000000000*var_13*var_1414/(var_14*var_14*var_14); + A[862] = A[223]; + A[812] = 0.0000000000000000000000000; + A[523] = 0.0000000000000000000000000; + const double var_1415 = var_448 + var_500; + const double var_1416 = var_210 + var_229; + const double var_1417 = var_321 + var_59; + const double var_1418 = var_385 + var_859; + const double var_1419 = 0.0143915343915343926783912*var_139 + 0.0666666666666666657414808*var_1338 + 0.2000000000000000111022302*var_1418 + 0.2101587301587301559457899*var_121 + 0.0082539682539682548284565*var_1417 + 0.0533333333333333367565210*var_439 + 0.0126984126984126984016843*var_52 + var_762 + 0.0158730158730158721347436*var_1306 + 0.0546031746031746048619659*var_143 + 0.1746031746031745934821799*var_98 + 0.0507936507936507936067372*var_1416 + 0.0571428571428571410728559*var_267 + 0.0793650793650793606737182*var_65*var_80 + 0.1523809523809523946979994*var_42 + 0.0069841269841269841209264*var_131 + 0.0076190476190476190410106*var_848 + 0.2349206349206349186964360*var_120 + 0.1269841269841269770779490*var_88 + 0.0019047619047619047602526*var_24 + 0.0234920634920634911757542*var_33 + 0.0378835978835978873235923*var_194 + 0.0247619047619047627506461*var_1415 + 0.0152380952380952380820212*var_203 + 0.0006349206349206349200842*var_271 + 0.0406349206349206348853897*var_31 + 0.0825396825396825378762244*var_146 + 0.0869841269841269831841757*var_196 + 0.0380952380952380986744998*var_1403 + 0.0209523809523809514954173*var_197 + 0.3333333333333333148296163*var_990 + 0.0711111111111111110494321*var_381 + 0.0590476190476190501699172*var_201 + 0.0241269841269841286979236*var_16*var_62 + 0.0730158730158730201464934*var_110*var_15 + 0.1339682539682539585967902*var_21 + 0.0831746031746031788678408*var_94 + 0.0025396825396825396803369*var_175 + 0.0514285714285714276594597*var_871 + 0.0615873015873015863808071*var_198 + 0.0044444444444444444405895*var_119 + 0.0423280423280423256926497*var_1054*var_15 + 0.0495238095238095255012922*var_618 + 0.1117460317460317459348218*var_140; + A[188] = 32.0000000000000000000000000*var_13*var_1419/(var_14*var_14*var_14); + A[653] = A[188]; + A[651] = A[186]; + A[329] = 0.0000000000000000000000000; + A[289] = 0.0000000000000000000000000; + A[385] = 0.0000000000000000000000000; + A[852] = 0.0000000000000000000000000; + A[256] = 0.0000000000000000000000000; + A[632] = 0.0000000000000000000000000; + A[647] = A[66]; + const double var_1420 = var_1096 + var_22; + A[790] = 0.0000000000000000000000000; + A[757] = 0.0000000000000000000000000; + A[767] = A[70]; + A[18] = 0.0000000000000000000000000; + A[567] = A[102]; + A[549] = 0.0000000000000000000000000; + const double var_1421 = var_576 + var_81; + const double var_1422 = 10.9861111111111107163651468*var_110 + 1.0694444444444444197728217*var_1421 + 4.2996031746031739828595164*var_389 + 9.4523809523809525501292228*var_222 + 1.4761904761904760530200065*var_154 + 0.0575396825396825364884457*var_1250 + 1.5337301587301586103251338*var_60 + 4.3571428571428567622092487*var_206 + 6.1646825396825395415589810*var_47; + A[62] = 0.2000000000000000111022302*var_13*var_1422*var_16/(var_14*var_14*var_14); + const double var_1423 = 10.2285714285714277593797306*var_212 + 10.7333333333333325043668083*var_136 + 0.9047619047619047671915382*var_114 + 9.3238095238095244354781244*var_174 + 1.1523809523809525057203018*var_163; + const double var_1424 = 229.6666666666666571927635232*var_215 + 302.0000000000000000000000000*var_216 + 390.3333333333333143855270464*var_217; + const double var_1425 = var_185 + var_21; + const double var_1426 = 59.0000000000000000000000000*var_97 + 0.4444444444444444197728217*var_66 + 508.0000000000000000000000000*var_202 + 539.3333333333332575421081856*var_132 + 149.0000000000000000000000000*var_283 + 32.3333333333333285963817616*var_141 + 16.0000000000000000000000000*var_234 + 9.5555555555555553581825734*var_47*var_80 + 241.0000000000000000000000000*var_203 + 206.0000000000000000000000000*var_200 + 27.3333333333333321490954404*var_1425 + 131.0000000000000000000000000*var_201 + 7.3333333333333330372738601*var_149 + 179.3333333333333143855270464*var_16*var_169 + 191.7777777777777714618423488*var_49*var_80 + 77.6666666666666571927635232*var_282 + 0.3333333333333333148296163*var_381 + var_1*var_1424*var_3 + 44.6666666666666642981908808*var_144 + 97.0000000000000000000000000*var_267 + var_42; + const double var_1427 = 0.8711111111111110583138384*var_198 + 0.2000000000000000111022302*var_1237 + 0.0666666666666666657414808*var_1423*var_7*var_8 + 0.8634920634920635329478955*var_281 + var_957 + var_585 + 0.0311111111111111102167648*var_143 + 0.0622222222222222204335296*var_196 + var_876 + var_1140 + 0.4000000000000000222044605*var_331 + 1.1746031746031746489933312*var_131 + 0.2095238095238095565875369*var_142 + 0.3333333333333333148296163*var_10 + 0.2800000000000000266453526*var_199 + 0.3904761904761905322303051*var_205 + 0.7174603174603174648993331*var_197 + 0.6742857142857142660474778*var_280 + 0.8914285714285714590232601*var_189 + 0.2158730158730158832369739*var_140 + 0.0800000000000000016653345*var_15*var_278 + 0.0019047619047619047602526*var_1426; + A[3] = var_13*var_1427/(var_14*var_14*var_14); + A[90] = A[3]; + A[702] = 0.0000000000000000000000000; + A[727] = 0.0000000000000000000000000; + A[548] = 0.0000000000000000000000000; + A[573] = 0.0000000000000000000000000; + A[807] = A[342]; + A[40] = var_1080*var_13/(var_14*var_14*var_14); + A[301] = A[40]; + A[657] = A[192]; + A[880] = 0.0000000000000000000000000; + A[276] = A[189]; + A[180] = A[6]; + const double var_1428 = var_231 + var_562; + const double var_1429 = 0.3123809523809523702730928*var_52 + 1.0095238095238097120187604*var_147 + 2.0000000000000000000000000*var_692 + 0.2000000000000000111022302*var_1393*var_7*var_8 + 0.1619047619047619124277304*var_1428 + 0.7485714285714285542994162*var_179 + 1.7142857142857141905523122*var_76 + 0.6285714285714285587403083*var_23 + 0.1041269841269841234243643*var_64 + 0.2666666666666666629659233*var_782 + var_239 + 0.2495238095238095366035225*var_91 + 0.4095238095238095676897672*var_32 + 0.2438095238095238093123385*var_144 + 0.0444444444444444461406185*var_82 + 0.6666666666666666296592325*var_1420 + 0.3428571428571428603149229*var_164 + 0.0419047619047619029908347*var_367 + 0.0673015873015873067330972*var_18 + 1.1542857142857143593062119*var_25 + 2.5142857142857142349612332*var_75 + var_497 + 1.3523809523809524613113808*var_35 + 1.0800000000000000710542736*var_1*var_3*var_45 + 0.3047619047619047893959987*var_149 + var_1162 + 0.2412698412698412731014486*var_30 + 0.1314285714285714223859003*var_148 + 0.4171428571428571485668613*var_102 + 0.6247619047619047405461856*var_108 + 0.4761904761904761640423089*var_112 + 0.3904761904761905322303051*var_44 + 0.0819047619047619107623959*var_178 + 0.0857142857142857150787307*var_20 + 0.0933333333333333375891883*var_9 + 0.1961904761904761929081076*var_117 + var_1252 + 0.2780952380952381175482913*var_29 + 0.1980952380952381020051689*var_16*var_167 + 0.2171428571428571374646310*var_103 + var_555 + var_896 + 0.2609523809523809356747392*var_363 + 1.0857142857142856318120039*var_31 + 0.1219047619047619046561692*var_130 + var_798 + var_655 + 0.2476190476190476552620368*var_208 + var_1379; + A[133] = 8.0000000000000000000000000*var_13*var_1429/(var_14*var_14*var_14); + A[394] = A[133]; + A[826] = A[42]; + A[377] = 0.0000000000000000000000000; + A[501] = A[36]; + A[433] = A[404]; + A[83] = 0.0000000000000000000000000; + A[118] = 0.0000000000000000000000000; + A[199] = 0.0000000000000000000000000; + A[142] = 0.0000000000000000000000000; + A[325] = 0.0000000000000000000000000; + A[369] = A[282]; + A[367] = A[222]; + A[639] = 0.0000000000000000000000000; + const double var_1430 = var_604 + var_148 + var_33 + var_314 + var_126; + const double var_1431 = 0.0114285714285714285615159*var_724 + 0.0095238095238095246686250*var_1430 + 0.0052910052910052907115812*var_946 + 0.0038095238095238095205053*var_456 + 0.0685714285714285748385421*var_77 + 0.0730158730158730201464934*var_463 + 0.0019047619047619047602526*var_471 + 0.0571428571428571410728559*var_1088 + 0.0082539682539682548284565*var_468 + 0.0423280423280423256926497*var_944 + 0.0158730158730158721347436*var_1196 + 0.0044444444444444444405895*var_1086 + 0.0444444444444444461406185*var_1373; + A[95] = 32.0000000000000000000000000*var_13*var_1431/(var_14*var_14*var_14); + A[153] = A[95]; + A[165] = 0.0000000000000000000000000; + A[729] = 0.0000000000000000000000000; + A[622] = A[157]; + A[226] = 0.0000000000000000000000000; + A[888] = A[104]; + const double var_1432 = 11.0000000000000000000000000*var_45 + 9.0000000000000000000000000*var_161; + const double var_1433 = var_130 + var_234; + const double var_1434 = var_240 + var_108; + const double var_1435 = var_44 + var_59; + const double var_1436 = var_132 + var_198; + const double var_1437 = 1.0666666666666666518636930*var_287 + 2.6000000000000000888178420*var_271 + 6.2000000000000001776356839*var_52 + var_815 + 2.0000000000000000000000000*var_1436 + 2.1333333333333333037273860*var_18 + var_230 + 3.8000000000000002664535259*var_112 + 5.2000000000000001776356839*var_7*var_8*var_89 + 5.8000000000000007105427358*var_849 + 19.0000000000000000000000000*var_149 + 2.2000000000000001776356839*var_15*var_5 + 4.3333333333333330372738601*var_29 + 12.8000000000000007105427358*var_22 + 8.5999999999999996447286321*var_847 + 8.2000000000000010658141036*var_1402; + const double var_1438 = 0.0476190476190476164042309*var_1434 + 0.0400000000000000008326673*var_504 + var_263 + 0.0685714285714285748385421*var_1397 + 0.0285714285714285705364279*var_201 + 0.0857142857142857150787307*var_165 + 0.0800000000000000016653345*var_25 + var_1210 + 0.0114285714285714285615159*var_1*var_1432*var_3 + var_1195 + var_1271 + 0.0222222222222222230703093*var_159 + 0.2266666666666666829499377*var_147 + 0.0514285714285714276594597*var_1433 + 0.0457142857142857142460635*var_107 + 0.1733333333333333392545228*var_151 + var_656 + 0.0533333333333333367565210*var_669 + var_968 + var_925 + 0.1314285714285714223859003*var_31 + 0.1066666666666666735130420*var_144 + 0.0133333333333333341891302*var_1435 + 0.0095238095238095246686250*var_1437; + A[440] = 0.0000000000000000000000000; + A[470] = A[5]; + A[604] = 0.0000000000000000000000000; + A[857] = A[73]; + A[655] = A[190]; + A[39] = var_13*var_1333/(var_14*var_14*var_14); + A[736] = A[39]; + const double var_1439 = var_97 + var_550; + const double var_1440 = var_233 + var_21; + const double var_1441 = 0.0006349206349206349200842*var_1*var_1410*var_3 + var_1251 + 0.0387301587301587327272223*var_283 + 0.0107936507936507945087934*var_201 + 0.0160846560846560869550981*var_139 + 0.0050793650793650793606737*var_1440 + 0.1320634920634920772553045*var_108 + 0.0615873015873015863808071*var_146 + 0.0590476190476190501699172*var_271 + 0.0203174603174603174426949*var_197 + 0.1688888888888888939465716*var_144 + 0.2666666666666666629659233*var_430 + var_1265 + 0.0025396825396825396803369*var_551 + 0.0177777777777777777623580*var_198 + var_302 + 0.0194708994708994720390649*var_50 + 0.0704761904761904700578157*var_179 + var_671 + 0.0431746031746031780351736*var_22 + 0.0537566137566137594583360*var_47*var_80 + 2.0000000000000000000000000*var_913 + 0.2361904761904762006796688*var_15*var_219 + var_327 + 0.0082539682539682548284565*var_1439 + 0.0222222222222222230703093*var_165 + 0.0169312169312169323587280*var_29 + var_620 + var_1018 + 0.0088888888888888888811790*var_120 + 0.0114285714285714285615159*var_439 + 0.0977777777777777828971395*var_132 + 0.0019047619047619047602526*var_7*var_8*var_940 + 0.1022222222222222282050907*var_143 + 0.1257142857142857228502919*var_15*var_4 + 0.0057142857142857142807579*var_560 + 0.0033862433862433863850094*var_30 + var_670 + var_1137; + A[221] = 4.0000000000000000000000000*var_13*var_1441/(var_14*var_14*var_14); + A[802] = A[221]; + A[277] = A[219]; + A[210] = A[7]; + A[172] = 0.0000000000000000000000000; + A[374] = 64.0000000000000000000000000*var_13*var_1438/(var_14*var_14*var_14); + A[432] = A[374]; + A[454] = 0.0000000000000000000000000; + A[531] = A[66]; + A[56] = 0.0000000000000000000000000; + A[45] = 0.0000000000000000000000000; + A[649] = A[126]; + A[427] = A[224]; + A[834] = A[282]; + A[787] = 0.0000000000000000000000000; + A[765] = A[10]; + A[359] = 0.0000000000000000000000000; + A[372] = 12.8000000000000007105427358*var_13*var_485/(var_14*var_14*var_14); + A[837] = A[372]; + A[688] = A[223]; + A[670] = 0.0000000000000000000000000; + A[803] = A[251]; + A[381] = 0.0000000000000000000000000; + A[533] = A[68]; + A[799] = A[131]; + const double var_1442 = 19.3333333333333321490954404*var_36 + 1.0222222222222223653176343*var_101 + 7.8000000000000007105427358*var_37 + 8.7333333333333325043668083*var_43 + 6.7777777777777776790912867*var_45; + A[565] = A[100]; + A[420] = A[14]; + A[322] = 0.0000000000000000000000000; + A[46] = 0.0000000000000000000000000; + A[808] = A[343]; + A[85] = 0.0000000000000000000000000; + A[777] = A[312]; + A[466] = A[1]; + A[82] = 0.0000000000000000000000000; + A[22] = 0.0000000000000000000000000; + A[134] = 8.0000000000000000000000000*var_1165*var_13/(var_14*var_14*var_14); + A[424] = A[134]; + A[735] = A[9]; + A[401] = A[343]; + A[617] = A[65]; + A[854] = 0.0000000000000000000000000; + A[556] = A[33]; + A[846] = 0.0000000000000000000000000; + A[52] = 0.0000000000000000000000000; + A[442] = 0.0000000000000000000000000; + A[59] = 0.0000000000000000000000000; + A[838] = A[373]; + A[839] = A[374]; + A[170] = 0.0000000000000000000000000; + A[682] = A[217]; + A[710] = A[158]; + A[71] = 0.2000000000000000111022302*var_1295*var_13/(var_14*var_14*var_14); + A[332] = A[71]; + A[618] = A[95]; + A[237] = 0.0000000000000000000000000; + A[624] = A[159]; + A[378] = 0.0000000000000000000000000; + A[863] = A[253]; + A[486] = 0.0000000000000000000000000; + A[326] = 0.0000000000000000000000000; + A[554] = 0.0000000000000000000000000; + A[122] = A[64]; + A[756] = 0.0000000000000000000000000; + A[518] = 0.0000000000000000000000000; + A[593] = A[128]; + A[306] = A[190]; + A[450] = 0.0000000000000000000000000; + A[240] = A[8]; + A[545] = 0.0000000000000000000000000; + A[206] = 0.0000000000000000000000000; + A[379] = 0.0000000000000000000000000; + A[499] = A[34]; + A[246] = A[188]; + A[295] = 0.0000000000000000000000000; + A[629] = A[164]; + A[739] = A[129]; + A[664] = 0.0000000000000000000000000; + A[594] = A[129]; + A[80] = 0.0000000000000000000000000; + A[304] = A[130]; + A[822] = 0.0000000000000000000000000; + A[821] = 0.0000000000000000000000000; + A[485] = 0.0000000000000000000000000; + A[417] = 0.0000000000000000000000000; + const double var_1443 = var_304 + var_281; + const double var_1444 = var_1155 + 0.1460317460317460402929868*var_229 + var_391 + 0.3047619047619047893959987*var_189 + 0.0253968253968253968033686*var_1050 + 0.0052910052910052907115812*var_301 + 0.0761904761904761973489997*var_141 + 0.3936507936507936400438723*var_121 + 0.0666666666666666657414808*var_286 + 0.0209523809523809514954173*var_193 + 0.3968253968253968033685908*var_98 + var_404 + var_966 + 0.0228571428571428571230317*var_235 + 0.2666666666666666629659233*var_140 + 0.6285714285714285587403083*var_120 + 0.1206349206349206365507243*var_1355*var_7*var_8 + 0.2984126984126984072354105*var_21 + 0.0158730158730158721347436*var_56 + 0.0057142857142857142807579*var_203 + 0.1142857142857142821457117*var_1311*var_16 + 0.0613756613756613819687935*var_194 + 0.3142857142857142793701541*var_42 + var_690 + 0.0571428571428571410728559*var_282 + 0.1333333333333333314829616*var_1321 + 0.0380952380952380986744998*var_1262 + 0.0516402116402116390103672*var_195 + 0.0412698412698412689381122*var_1443; + A[155] = 32.0000000000000000000000000*var_13*var_1444/(var_14*var_14*var_14); + A[620] = A[155]; + A[429] = A[284]; + A[196] = 0.0000000000000000000000000; + A[418] = 0.0000000000000000000000000; + const double var_1445 = var_25 + var_76; + const double var_1446 = 0.2285714285714285642914234*var_1445 + var_1117 + 0.1111111111111111049432054*var_64 + 0.3047619047619047893959987*var_75 + 0.0031746031746031746004211*var_1409*var_7*var_8 + var_790 + 0.0800000000000000016653345*var_495 + var_1194 + var_1244 + 0.4063492063492063488538975*var_233 + 0.5555555555555555802271783*var_112 + 2.1650793650793649369745708*var_34 + 0.2171428571428571374646310*var_200 + 0.6952380952380953216263038*var_58 + 0.0571428571428571410728559*var_1*var_1442*var_3 + 0.0761904761904761973489997*var_105 + 0.0565079365079365070201334*var_1310 + 0.0916402116402116467819283*var_47*var_80 + 0.7354497354497354644209395*var_80*var_81 + 0.4571428571428571285828468*var_208 + 0.2577777777777777723500208*var_22 + 0.2154497354497354466573711*var_18 + 0.1993650793650793562328261*var_19 + 1.1460317460317459570262599*var_31 + 0.4603174603174602919075653*var_117 + 0.2736507936507936444847644*var_97 + 0.2408465608465608642774214*var_29 + 0.0400000000000000008326673*var_90 + 1.8634920634920635329478955*var_24 + 0.1873015873015873022922051*var_33 + var_571 + 1.6031746031746030300979555*var_35 + 0.0222222222222222230703093*var_66 + 0.0019047619047619047602526*var_231 + 0.4634920634920635107434350*var_21 + 0.7587301587301586991429758*var_28 + 0.1523809523809523946979994*var_232 + 0.0095238095238095246686250*var_1401*var_15 + 0.0412698412698412689381122*var_91 + 0.7492063492063492091688204*var_32 + 0.0203174603174603174426949*var_245 + 0.3301587301587301515048978*var_98 + 0.3451851851851851504804358*var_30 + 0.0025396825396825396803369*var_120; + A[311] = 8.0000000000000000000000000*var_13*var_1446/(var_14*var_14*var_14); + A[805] = A[311]; + A[50] = 0.0000000000000000000000000; + A[539] = A[74]; + A[897] = A[374]; + A[461] = 0.0000000000000000000000000; + A[546] = 0.0000000000000000000000000; + A[575] = 0.0000000000000000000000000; + A[310] = 2.0000000000000000000000000*var_1297*var_13/(var_14*var_14*var_14); + A[775] = A[310]; + A[415] = 0.0000000000000000000000000; + A[528] = A[63]; + A[337] = A[221]; + A[698] = 0.0000000000000000000000000; + A[292] = 0.0000000000000000000000000; + A[270] = A[9]; + A[676] = A[37]; + A[740] = A[159]; + A[520] = 0.0000000000000000000000000; + A[563] = A[98]; + A[684] = A[219]; + A[695] = 0.0000000000000000000000000; + A[382] = 0.0000000000000000000000000; + A[285] = 0.0000000000000000000000000; + A[751] = 0.0000000000000000000000000; + A[483] = 0.0000000000000000000000000; + A[297] = 0.0000000000000000000000000; + A[644] = 0.0000000000000000000000000; + A[468] = A[3]; + A[608] = 0.0000000000000000000000000; + A[235] = 0.0000000000000000000000000; + A[760] = 0.0000000000000000000000000; + A[562] = A[97]; + A[770] = A[160]; + A[758] = 0.0000000000000000000000000; + A[290] = 0.0000000000000000000000000; + A[535] = A[70]; + A[437] = 0.0000000000000000000000000; + A[412] = 0.0000000000000000000000000; + A[536] = A[71]; + A[715] = A[250]; + A[701] = 0.0000000000000000000000000; + A[262] = 0.0000000000000000000000000; + A[384] = 0.0000000000000000000000000; + A[445] = 0.0000000000000000000000000; + A[436] = 0.0000000000000000000000000; + A[146] = 0.0000000000000000000000000; + A[508] = A[43]; + A[23] = 0.0000000000000000000000000; + A[559] = A[94]; + A[497] = A[32]; + A[659] = A[194]; + A[504] = A[39]; + A[762] = 0.0000000000000000000000000; + A[169] = 0.0000000000000000000000000; + A[184] = A[126]; + A[723] = 0.0000000000000000000000000; + A[786] = 0.0000000000000000000000000; + A[474] = A[9]; + A[778] = A[313]; + A[895] = A[314]; + A[588] = A[94]; + A[239] = 0.0000000000000000000000000; + A[267] = 0.0000000000000000000000000; + A[120] = A[4]; + A[555] = A[3]; + A[874] = 0.0000000000000000000000000; + A[700] = 0.0000000000000000000000000; + A[522] = 0.0000000000000000000000000; + A[613] = 0.0000000000000000000000000; + A[878] = 0.0000000000000000000000000; + A[473] = A[8]; + A[685] = A[220]; + A[869] = A[404]; + A[48] = 0.0000000000000000000000000; + A[201] = 0.0000000000000000000000000; + A[453] = 0.0000000000000000000000000; + A[885] = A[14]; + A[576] = 0.0000000000000000000000000; + A[532] = A[67]; + A[648] = A[96]; + A[294] = 0.0000000000000000000000000; + A[493] = 0.0000000000000000000000000; + A[340] = A[311]; + A[462] = 0.0000000000000000000000000; + A[291] = 0.0000000000000000000000000; + A[889] = A[134]; + A[789] = 0.0000000000000000000000000; + A[773] = A[250]; + A[636] = 0.0000000000000000000000000; + A[641] = 0.0000000000000000000000000; + A[656] = A[191]; + A[890] = A[164]; + A[666] = 0.0000000000000000000000000; + A[721] = 0.0000000000000000000000000; + A[444] = 0.0000000000000000000000000; + A[598] = A[133]; + A[631] = 0.0000000000000000000000000; + A[271] = A[39]; + A[203] = 0.0000000000000000000000000; + A[693] = 0.0000000000000000000000000; + A[269] = 0.0000000000000000000000000; + A[768] = A[100]; + A[260] = 0.0000000000000000000000000; + A[439] = 0.0000000000000000000000000; + A[105] = 0.0000000000000000000000000; + A[691] = 0.0000000000000000000000000; + A[524] = 0.0000000000000000000000000; + A[200] = 0.0000000000000000000000000; + A[335] = A[161]; + A[305] = A[160]; + A[77] = 0.0000000000000000000000000; + A[84] = 0.0000000000000000000000000; + A[458] = 0.0000000000000000000000000; + A[733] = 0.0000000000000000000000000; + A[694] = 0.0000000000000000000000000; + A[480] = 0.0000000000000000000000000; + A[300] = A[10]; + A[81] = 0.0000000000000000000000000; + A[428] = A[254]; + A[898] = A[404]; + A[836] = A[342]; + A[881] = 0.0000000000000000000000000; + A[828] = A[102]; + A[749] = A[284]; + A[791] = 0.0000000000000000000000000; + A[712] = A[218]; + A[690] = 0.0000000000000000000000000; + A[112] = 0.0000000000000000000000000; + A[732] = 0.0000000000000000000000000; + A[383] = 0.0000000000000000000000000; + A[551] = 0.0000000000000000000000000; + A[788] = 0.0000000000000000000000000; + A[835] = A[312]; + A[318] = 0.0000000000000000000000000; + A[707] = A[68]; + A[529] = A[64]; + A[815] = 0.0000000000000000000000000; + A[818] = 0.0000000000000000000000000; + A[195] = 0.0000000000000000000000000; + A[755] = 0.0000000000000000000000000; + A[720] = 0.0000000000000000000000000; + A[348] = 0.0000000000000000000000000; + A[225] = 0.0000000000000000000000000; + A[407] = 0.0000000000000000000000000; + A[324] = 0.0000000000000000000000000; + A[349] = 0.0000000000000000000000000; + A[391] = A[43]; + A[296] = 0.0000000000000000000000000; + A[521] = 0.0000000000000000000000000; + A[498] = A[33]; + A[541] = 0.0000000000000000000000000; + A[864] = A[283]; + A[144] = 0.0000000000000000000000000; + A[376] = 0.0000000000000000000000000; + A[795] = A[11]; + A[667] = 0.0000000000000000000000000; + A[861] = A[193]; + A[776] = A[311]; + A[137] = 0.0000000000000000000000000; + A[560] = A[95]; + A[113] = 0.0000000000000000000000000; + A[119] = 0.0000000000000000000000000; + A[793] = 0.0000000000000000000000000; + A[227] = 0.0000000000000000000000000; + A[726] = 0.0000000000000000000000000; + A[668] = 0.0000000000000000000000000; + A[713] = A[248]; + A[595] = A[130]; + A[402] = A[373]; + A[716] = A[251]; + A[53] = 0.0000000000000000000000000; + A[610] = 0.0000000000000000000000000; + A[797] = A[71]; + A[882] = 0.0000000000000000000000000; + A[141] = 0.0000000000000000000000000; + A[627] = A[162]; + A[718] = A[253]; + A[600] = 0.0000000000000000000000000; + A[510] = 0.0000000000000000000000000; + A[478] = A[13]; + A[590] = A[125]; + A[728] = 0.0000000000000000000000000; + A[268] = 0.0000000000000000000000000; + A[175] = 0.0000000000000000000000000; + A[496] = A[31]; + A[553] = 0.0000000000000000000000000; + A[308] = A[250]; + A[397] = A[223]; + A[395] = A[163]; + A[410] = 0.0000000000000000000000000; + A[833] = A[252]; + A[299] = 0.0000000000000000000000000; + A[660] = 0.0000000000000000000000000; + A[669] = 0.0000000000000000000000000; + A[823] = 0.0000000000000000000000000; + A[597] = A[132]; + A[824] = 0.0000000000000000000000000; + A[519] = 0.0000000000000000000000000; + A[333] = A[101]; + A[273] = A[99]; + A[79] = 0.0000000000000000000000000; + A[357] = 0.0000000000000000000000000; + A[317] = 0.0000000000000000000000000; + A[89] = 0.0000000000000000000000000; + A[363] = A[102]; + A[447] = 0.0000000000000000000000000; + A[421] = A[44]; + A[145] = 0.0000000000000000000000000; + A[409] = 0.0000000000000000000000000; + A[216] = A[187]; + A[859] = A[133]; + A[414] = 0.0000000000000000000000000; + A[111] = 0.0000000000000000000000000; + A[114] = 0.0000000000000000000000000; + A[709] = A[128]; + A[202] = 0.0000000000000000000000000; + A[829] = A[132]; + A[820] = 0.0000000000000000000000000; + A[599] = A[134]; + A[177] = 0.0000000000000000000000000; + A[827] = A[72]; + A[92] = A[63]; + A[686] = A[221]; + A[431] = A[344]; + A[181] = A[36]; + A[327] = 0.0000000000000000000000000; + A[208] = 0.0000000000000000000000000; + A[652] = A[187]; + A[263] = 0.0000000000000000000000000; + A[247] = A[218]; + A[505] = A[40]; + A[423] = A[104]; + A[435] = 0.0000000000000000000000000; + A[858] = A[103]; + A[328] = 0.0000000000000000000000000; + A[798] = A[101]; + A[320] = 0.0000000000000000000000000; + A[766] = A[40]; + A[353] = 0.0000000000000000000000000; + A[678] = A[97]; + A[236] = 0.0000000000000000000000000; + A[714] = A[249]; + A[488] = 0.0000000000000000000000000; + A[744] = A[279]; + A[743] = A[249]; + A[75] = 0.0000000000000000000000000; + A[24] = 0.0000000000000000000000000; + A[645] = A[6]; + A[892] = A[224]; + A[375] = 0.0000000000000000000000000; + A[849] = 0.0000000000000000000000000; + A[319] = 0.0000000000000000000000000; + A[607] = 0.0000000000000000000000000; + A[809] = A[344]; + A[390] = A[13]; + A[843] = 0.0000000000000000000000000; + A[578] = 0.0000000000000000000000000; + A[368] = A[252]; + A[309] = A[280]; + A[681] = A[187]; + A[711] = A[188]; + A[845] = 0.0000000000000000000000000; + A[810] = 0.0000000000000000000000000; + A[585] = A[4]; + A[626] = A[161]; + A[123] = A[94]; + A[705] = A[8]; + A[362] = A[72]; + A[430] = A[314]; + A[86] = 0.0000000000000000000000000; + A[408] = 0.0000000000000000000000000; + A[542] = 0.0000000000000000000000000; + A[526] = A[32]; + A[722] = 0.0000000000000000000000000; + A[148] = 0.0000000000000000000000000; + A[360] = A[12]; + A[785] = 0.0000000000000000000000000; + A[586] = A[34]; + A[527] = A[62]; + A[455] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q4_quadrature.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q4_quadrature.h new file mode 100644 index 0000000..a37d745 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q4_quadrature.h @@ -0,0 +1,23576 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P3_Q4_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F1_P3_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q4_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 15; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q4_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 30; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 15: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 20: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 21: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 22: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 23: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 24: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 25: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 26: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 27: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 28: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 29: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[20] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[21] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[22] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[23] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[24] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[25] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[26] = vals[1]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[27] = vals[1]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[28] = vals[1]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[29] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[15]; + vertex_values[3] = dof_values[16]; + vertex_values[5] = dof_values[17]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q4_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q4_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 3*m.num_entities[1] + 3*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 15; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 15; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 5; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 3; + break; + } + case 2: + { + return 3; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q4_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q4_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 6*m.num_entities[1] + 6*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 30; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 30; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 10; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 6; + break; + } + case 2: + { + return 6; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + dofs[15] = offset + c.entity_indices[0][0]; + dofs[16] = offset + c.entity_indices[0][1]; + dofs[17] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[18] = offset + 3*c.entity_indices[1][0]; + dofs[19] = offset + 3*c.entity_indices[1][0] + 1; + dofs[20] = offset + 3*c.entity_indices[1][0] + 2; + dofs[21] = offset + 3*c.entity_indices[1][1]; + dofs[22] = offset + 3*c.entity_indices[1][1] + 1; + dofs[23] = offset + 3*c.entity_indices[1][1] + 2; + dofs[24] = offset + 3*c.entity_indices[1][2]; + dofs[25] = offset + 3*c.entity_indices[1][2] + 1; + dofs[26] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[27] = offset + 3*c.entity_indices[2][0]; + dofs[28] = offset + 3*c.entity_indices[2][0] + 1; + dofs[29] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + dofs[5] = 16; + dofs[6] = 17; + dofs[7] = 18; + dofs[8] = 19; + dofs[9] = 20; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + dofs[5] = 15; + dofs[6] = 17; + dofs[7] = 21; + dofs[8] = 22; + dofs[9] = 23; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + dofs[5] = 15; + dofs[6] = 16; + dofs[7] = 24; + dofs[8] = 25; + dofs[9] = 26; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 15; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 16; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 17; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + dofs[3] = 18; + dofs[4] = 19; + dofs[5] = 20; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + dofs[3] = 21; + dofs[4] = 22; + dofs[5] = 23; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + dofs[3] = 24; + dofs[4] = 25; + dofs[5] = 26; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + dofs[3] = 27; + dofs[4] = 28; + dofs[5] = 29; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + coordinates[15][0] = x[0][0]; + coordinates[15][1] = x[0][1]; + coordinates[16][0] = x[1][0]; + coordinates[16][1] = x[1][1]; + coordinates[17][0] = x[2][0]; + coordinates[17][1] = x[2][1]; + coordinates[18][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[18][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[19][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[19][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[20][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[20][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[21][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[21][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[22][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[22][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[23][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[23][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[24][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[24][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[25][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[25][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[26][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[26][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[27][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[27][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[28][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[28][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[29][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[29][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p3_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // 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_C0_D01[25][9] = \ + {{-4.06985505689898, 0.663106420235969, -0.175302395384938, -0.154276912360605, 6.38350227154709, -2.97675363488409, -0.910265045258717, 0.175302395384938, 1.06454195761932}, + {-2.00814585648569, -0.252795026479633, -0.150188294074804, 0.0318412090086047, 1.25227625167256, 1.00866463129277, -0.607126650247005, 0.150188294074805, 0.575285441238399}, + {-0.0526400567928259, -0.352177177674818, -0.109257126458971, 0.193129457653329, -2.90035813312996, 3.3051753675976, -0.262666599764851, 0.109257126458972, 0.0695371421115214}, + {0.474941577440673, 1.27037403921984, -0.0615309418396494, 0.203965934922007, -2.48940602426171, 0.744090407601198, -0.0476680983174364, 0.06153094183965, -0.15629783660457}, + {-0.273849606287232, 3.85744215792178, -0.0205118631588732, 0.0917041355203092, 1.46725382984054, -5.0508463814751, 0.00907981301713612, 0.0205118631588739, -0.100783948537443}, + {-1.71738066252314, 0.663106420235969, -0.334293160134967, -0.758936398143236, 3.42636839138862, -2.37209414910146, -3.42173020438459, 0.334293160134968, 4.18066660252782}, + {-0.585657258114945, -0.252795026479634, -0.370427430918426, 0.156636868781983, -0.0454166869248133, 0.883868971519392, -2.24985438546138, 0.370427430918427, 2.09321751667939}, + {0.367697406585462, -0.352177177674818, -0.356547729279486, 0.950064223635603, -2.56376083052597, 2.54824060161532, -0.930294665963655, 0.356547729279487, -0.0197695576719498}, + {0.367488895063862, 1.27037403921984, -0.249570091588417, 1.00337224556198, -1.58254703124493, -0.0553159030387718, -0.128254565689394, 0.249570091588417, -0.875117679872583}, + {-0.395389762697828, 3.85744215792178, -0.0953431525243795, 0.451121332684868, 1.9482111834157, -5.41026357863966, 0.0557886800622256, 0.0953431525243796, -0.506910012747092}, + {0.209223394941008, 0.663106420235969, 0.951204426693189, -1.64438988513856, 0.614310846929156, -1.48664066210613, -4.06283667502057, -0.951204426693188, 5.70722656015913}, + {0.438198756619908, -0.252795026479634, 0.366271053164474, 0.339385597126489, -0.88652397331516, 0.701120243174886, -2.53701191611333, -0.366271053164474, 2.19762631898684}, + {0.463044294418704, -0.352177177674817, -0.198487617475322, 2.05850714684467, -1.55066479515014, 1.43979767840625, -0.867581441992734, 0.198487617475323, -1.19092570485194}, + {0.05740649019504, 1.27037403921984, -0.37220110524072, 2.1740098059172, -0.101827066020882, -1.225953463394, 0.059196825527124, 0.372201105240721, -2.23320663144433}, + {-0.589360539480447, 3.85744215792178, -0.188935517472192, 0.977446012936142, 2.66850664044959, -5.93658825889093, 0.156167091897032, 0.188935517472193, -1.13361310483317}, + {0.331396903120676, 0.663106420235969, 4.04113256280582, -2.52984337213388, -0.393316148245832, -0.601187175110812, -1.09508204708761, -4.04113256280582, 3.62492541922149}, + {0.203245627121679, -0.252795026479634, 2.36177868148046, 0.522134325470996, -0.468822115472425, 0.51837151483038, -0.306551158299116, -2.36177868148046, -0.215583167171879}, + {-0.0598205552003695, -0.352177177674817, 0.577784231781157, 3.16695007005374, 0.0806429776780028, 0.331354755197185, 0.431555256882819, -0.577784231781157, -3.59850532693656}, + {-0.434186594374313, 1.27037403921984, -0.313321439192493, 3.34464736627243, 1.5604035789037, -2.39659102374922, 0.609669576144705, 0.313321439192493, -3.95431694241714}, + {-0.80233367368868, 3.85744215792178, -0.263525524994391, 1.50377069318741, 3.4078044549091, -6.4629129391422, 0.294550218583066, 0.263525524994391, -1.79832091177048}, + {-0.622005933550942, 0.663106420235969, 7.18801902910325, -3.13450285791651, -0.044572797356847, 0.00347231067182019, 3.00520725588144, -7.18801902910325, 0.129295602035074}, + {-0.680516070372195, -0.252795026479634, 4.44778984050145, 0.646929985244375, 0.539735241794825, 0.393575855057002, 2.66322169821576, -4.44778984050146, -3.31015168346013}, + {-0.772101971290909, -0.352177177674817, 1.46311250842947, 3.92388483603602, 1.54985915975082, -0.42558001078509, 2.02916494962167, -1.46311250842947, -5.95304978565769}, + {-0.874182983380276, 1.27037403921984, -0.168816882312108, 4.1440536769124, 2.79980627854963, -3.19599733438919, 1.19417052203105, 0.168816882312108, -5.33822419894345}, + {-0.958687838748414, 3.85744215792179, -0.303542805710757, 1.86318789035197, 3.92357581713339, -6.82233013630676, 0.410887102926433, 0.303542805710758, -2.27407499327841}}; + + // Array of non-zero columns + static const unsigned int nzc4[9] = {10, 12, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc1[9] = {0, 2, 3, 4, 5, 6, 7, 8, 9}; + + static const double FE0_C0_D10[25][9] = \ + {{-4.06985505689897, 0.622005933550942, -0.130729598028097, -0.157749223032423, -0.804516757556157, 0.157749223032423, 6.27775398384453, -2.8299048604965, 0.935246355584253}, + {-2.00814585648569, 0.680516070372195, -0.689923535869632, -0.361734646048397, -3.1955135888289, 0.361734646048396, 3.84066319025445, -2.51303340414095, 3.88543712469853}, + {-0.0526400567928263, 0.772101971290909, -1.65911628620979, 0.61870946843842, -4.36347064155943, -0.618709468438421, 1.20044590866462, -1.9199078231627, 6.02258692776921}, + {0.474941577440673, 0.874182983380277, -2.86133722038928, 3.3999632693112, -2.3205891419496, -3.3999632693112, -0.216484980629545, -1.13263958019141, 5.18192636233889}, + {-0.273849606287233, 0.958687838748415, -3.94408768029226, 6.91403427182707, 1.7707966355513, -6.91403427182707, -0.294462992693626, -0.390375239767558, 2.17329104474096}, + {-1.71738066252313, -0.331396903120676, 0.0590229881108634, -0.157749223032423, -0.614764171417199, 0.157749223032423, 0.619402358421233, 1.42937520722258, 0.555741183306335}, + {-0.585657258114945, -0.203245627121679, 0.0983946845539977, -0.361734646048396, -2.40719536840527, 0.361734646048397, 0.11192429601908, 0.676978589217543, 2.30880068385127}, + {0.367697406585462, 0.0598205552003702, -0.43719070695749, 0.61870946843842, -3.14154506230713, -0.61870946843842, -0.352510434182498, -0.0750075276033341, 3.57873576926462}, + {0.367488895063862, 0.434186594374314, -1.80997367049212, 3.3999632693112, -1.26922559205244, -3.3999632693112, -0.441576004881888, -0.36009948455629, 3.07919926254456}, + {-0.395389762697828, 0.80233367368868, -3.50314760743348, 6.91403427182707, 2.21173670841009, -6.91403427182707, -0.20773684493217, -0.199207066058685, 1.29141089902339}, + {0.209223394941008, -0.209223394941008, 0.336893579764031, -0.157749223032423, -0.336893579764031, 0.157749223032423, -3.11163224832739, 3.11163224832739, 0.0}, + {0.438198756619908, -0.438198756619908, 1.25279502647963, -0.361734646048396, -1.25279502647963, 0.361734646048397, -2.17074086294885, 2.17074086294885, 0.0}, + {0.463044294418704, -0.463044294418704, 1.35217717767482, 0.618709468438421, -1.35217717767482, -0.61870946843842, -1.06606905946806, 1.06606905946806, 0.0}, + {0.0574064901950401, -0.05740649019504, -0.27037403921984, 3.3999632693112, 0.270374039219839, -3.3999632693112, -0.313004279713597, 0.313004279713597, 0.0}, + {-0.589360539480447, 0.589360539480448, -2.85744215792178, 6.91403427182707, 2.85744215792178, -6.91403427182707, -0.0327684255751637, 0.0327684255751611, 0.0}, + {0.331396903120676, 1.71738066252313, 0.614764171417198, -0.157749223032423, -0.0590229881108647, 0.157749223032423, -1.42937520722258, -0.619402358421231, -0.555741183306333}, + {0.203245627121679, 0.585657258114945, 2.40719536840527, -0.361734646048395, -0.098394684553998, 0.361734646048396, -0.676978589217543, -0.111924296019081, -2.30880068385127}, + {-0.0598205552003698, -0.367697406585462, 3.14154506230712, 0.618709468438422, 0.43719070695749, -0.618709468438421, 0.075007527603333, 0.352510434182498, -3.57873576926461}, + {-0.434186594374313, -0.367488895063862, 1.26922559205244, 3.3999632693112, 1.80997367049211, -3.3999632693112, 0.360099484556288, 0.441576004881886, -3.07919926254455}, + {-0.80233367368868, 0.395389762697828, -2.21173670841009, 6.91403427182707, 3.50314760743348, -6.91403427182707, 0.199207066058682, 0.207736844932168, -1.29141089902339}, + {-0.622005933550944, 4.06985505689897, 0.804516757556154, -0.157749223032423, 0.130729598028091, 0.157749223032423, 2.8299048604965, -6.27775398384453, -0.935246355584244}, + {-0.680516070372195, 2.00814585648569, 3.1955135888289, -0.361734646048395, 0.689923535869631, 0.361734646048396, 2.51303340414095, -3.84066319025445, -3.88543712469853}, + {-0.772101971290909, 0.0526400567928262, 4.36347064155942, 0.618709468438424, 1.65911628620979, -0.618709468438422, 1.9199078231627, -1.20044590866462, -6.02258692776921}, + {-0.874182983380276, -0.474941577440672, 2.3205891419496, 3.3999632693112, 2.86133722038928, -3.3999632693112, 1.1326395801914, 0.216484980629545, -5.18192636233888}, + {-0.958687838748414, 0.273849606287233, -1.7707966355513, 6.91403427182707, 3.94408768029227, -6.91403427182707, 0.390375239767556, 0.294462992693624, -2.17329104474096}}; + + // Array of non-zero columns + static const unsigned int nzc5[9] = {10, 11, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc2[9] = {0, 1, 3, 4, 5, 6, 7, 8, 9}; + + static const double FE1_C0_D01[25][14] = \ + {{-4.92348092472479, -0.489501772856739, 0.179203488876249, 0.100666813761961, 0.134603486992305, 8.63375492668695, -5.79126584504057, 2.57049361593515, -2.43064495934601, 0.933695301413292, -0.179203488876251, 3.14676539989352, -1.03436211517524, -0.850723927539827}, + {-1.22072339702365, 0.353412468851741, 0.157627099145873, -0.0746718571074941, -0.0873088916887541, -1.74300688822412, 4.51684211570302, -1.90652429930699, -1.17372701640678, 0.653887982994551, -0.157627099145872, 0.673966720836549, -0.579216125887057, 0.587069187258981}, + {0.358599061347387, -0.199260154242238, 0.11915032151674, -0.236201006974522, 0.0489368169731712, -3.17391758456232, 1.80243660692675, 1.21214207053042, -0.205074293683275, 0.309924093033935, -0.119150321516738, -0.697548150238492, -0.0737230860594163, 0.853685626948599}, + {-0.256528017544188, 0.335981245709448, 0.0697846126615126, -0.245883039206206, 0.324765406089899, 1.6058038662832, -5.69992944155756, 4.01467234710911, 0.0351330450820346, 0.0712264684545085, -0.0697846126615112, -0.398938571740192, 0.174656570751691, 0.0390401205682623}, + {0.0106140386976448, 4.47094346923701, 0.023972721189482, -0.112725965267303, 0.238775264288607, -0.15332389817035, 0.879973096214445, -5.20820670597875, -0.00208846471084578, -0.00451319159940933, -0.0239727211894847, 0.0244881945022275, 0.117239156866706, -0.261174994079983}, + {-0.839131599831696, -0.48950177285674, 0.0748108288829812, 0.0686708574696078, 0.662156663835007, 2.56379098442514, -3.27809805082916, 2.04294043909245, -6.18031729659934, 0.494625653780274, -0.0748108288829797, 8.85005639822322, -0.563296511249881, -3.33189576545889}, + {0.202323839685595, 0.353412468851741, 0.161465637815132, -0.112302905481113, -0.429499753205215, -1.75503086478979, 2.76362799404298, -1.56433343779053, -2.69567005199158, 0.756622320539373, -0.161465637815132, 0.747255447904154, -0.644319415058259, 2.37791435729265}, + {0.183058222345733, -0.199260154242238, 0.246520964624723, -0.625066207389066, 0.240735512799229, -0.923343083643203, -0.080798359164653, 1.02034337470436, -0.206029746712401, 0.613791028172696, -0.246520964624722, -3.16049155954138, 0.0112751792163715, 3.12578579345455}, + {-0.350190108838501, 0.335981245709448, 0.231575301617104, -0.922258421214661, 1.59762263690684, 1.87432390421406, -4.60193015737717, 2.74181511629217, 0.1851747050734, 0.176637588713045, -0.231575301617103, -1.40021356037656, 0.745620832501613, -0.38258378160367}, + {0.145502825089315, 4.47094346923701, 0.105228292166946, -0.513593117920688, 1.17461022697504, -0.858753730257821, 2.38634910459668, -6.14404166866518, -0.0276892592294179, -0.0325456124950437, -0.105228292166949, 0.219762882063215, 0.546138730415726, -1.36668384980883}, + {0.300790618534486, -0.48950177285674, -0.0938175098322176, -1.20457509757173, 1.43469692987617, -0.25744128910517, -0.824247729623862, 1.27040017305129, -1.97325425970202, -5.02098794019842, 0.0938175098322148, 5.0510574614487, 6.22556303777016, -4.51250013162285}, + {0.0858949745717573, 0.353412468851741, -0.255769112851834, 0.565857929720685, -0.9305984685516, -0.305589684505477, 0.92951696352612, -1.06323472244414, -0.100890713389922, -2.13896290361542, 0.255769112851833, -2.50237537066618, 1.57310497389473, 3.5338645526077}, + {-0.277867342742944, -0.199260154242238, -0.0814276204367423, 0.349126846459827, 0.521602394099412, 1.03258701566852, -1.29493601208752, 0.739476493404178, 0.714772028659139, -0.174033767171633, 0.0814276204367425, -4.60210481528708, -0.175093079288193, 3.36573039252853}, + {-0.270988583314474, 0.335981245709448, 0.22078989418089, -1.08663594700873, 3.46157400122766, 1.2250859535242, -2.16794236789051, 0.877863751971334, 0.219884789139037, 0.0519405716871661, -0.22078989418089, -1.02926474507045, 1.03469537532157, -2.65219404529625}, + {0.388816964556487, 4.47094346923701, 0.190189287582516, -0.982902206430993, 2.54503167978712, -2.05527310001484, 4.70997578769861, -7.51446312147727, -0.122720710220877, -0.0958673055551886, -0.19018928758252, 0.798690474834211, 1.07876951198618, -3.22100144440045}, + {-0.3573245679932, -0.489501772856741, 3.67417591105398, -3.93531150769328, 2.20723719591734, 0.176854297338599, 0.172112136501218, 0.497859907010124, 1.89326182738164, -4.4613954198682, -3.67417591105398, -1.32237543567259, 8.39670692756148, -2.77812358762638}, + {-0.340773582195419, 0.353412468851741, 1.12915777685523, 2.11546133033649, -1.43169718389799, 0.582648622018157, -0.033151501576722, -0.562136007097758, 1.31220636814439, -1.74046453867549, -1.12915777685523, -2.82743880134114, -0.374996791661011, 2.94692961709474}, + {-0.187879798307207, -0.199260154242237, -0.227593922486541, 3.15784151189363, 0.802469275399596, 0.603082393870928, -0.674552053425481, 0.458609612103994, 0.351965301970183, -0.0473808869682165, 0.227593922486542, -1.09106634580247, -3.11046062492541, -0.063368231567311}, + {0.191532755133864, 0.335981245709449, 0.0418084423543278, -0.269250078420215, 5.32552536554849, -0.789235204472549, 1.24780881597873, -0.986087612349495, -0.343848708253603, -0.0258287211950972, -0.0418084423543293, 1.90365444045913, 0.295078799615313, -6.88533109775401}, + {0.690818483697246, 4.47094346923701, 0.238984215828931, -1.3123152230897, 3.9154531325992, -3.45037592129704, 7.17349854265214, -8.88488457428935, -0.298960853390353, -0.172833753280059, -0.238984215828935, 1.73861890348643, 1.48514897636976, -5.35511118269528}, + {0.432860334906831, -0.489501772856743, 10.7820243913322, -6.63755958969328, 2.73479037276005, 0.0713069027774886, 0.0150278050049932, -0.0296932698325705, -2.4803228061571, 6.22985279104878, -10.7820243913322, -0.335676392472756, 0.40770679864449, 0.081208825869822}, + {0.513886950347987, 0.353412468851742, 4.43471670367803, 3.6743905576189, -1.77388804541445, -0.457548926037692, -0.189805347580739, -0.219945145581301, -2.37468364726229, 4.39732387101058, -4.43471670367803, 2.60391745686038, -8.07171442862948, 1.54465423581636}, + {0.645901171050298, -0.199260154242236, 0.232818028669783, 6.1299830446049, 0.994267971225654, -1.51667164669493, 0.803219713608937, 0.266810916277931, -2.0006750758256, 1.93189047262638, -0.232818028669786, 5.51968863591294, -8.06187351723128, -4.51328153131299}, + {0.800146649057353, 0.33598124570945, -0.104550979384442, 0.853052384530374, 6.59838259636543, -3.02166899671853, 4.14448594511816, -2.25894484316643, -1.29020890800348, 0.165558162892518, 0.10455097938444, 5.59613700148209, -1.01861054742289, -10.904310689844}, + {0.933227768613883, 4.47094346923701, 0.253980335569297, -1.45688033140528, 4.85128809528563, -4.51962829624728, 8.93617659537217, -9.82071953697578, -0.473343193721761, -0.225864578124923, -0.253980335569301, 2.59527922553586, 1.6827449095302, -6.97322412709974}}; + + // Array of non-zero columns + static const unsigned int nzc10[14] = {15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; + + // Array of non-zero columns + static const unsigned int nzc7[14] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + + static const double FE1_C0_D10[25][14] = \ + {{-4.92348092472479, -0.432860334906833, 0.107896586098764, 0.0856390087569554, 0.164296756824886, -2.14826946464529, 0.846293744652697, -0.164296756824886, 8.35137943198624, -5.29615748963549, 2.30111931728087, 2.73905860124902, -0.698685722702495, -0.931932753409652}, + {-1.22072339702365, -0.513886950347988, 0.61517602518356, 0.115133490473251, 0.132636253892541, -6.17772359190216, 0.842451558084123, -0.132636253892543, 3.26098968727126, -3.74343588801603, 2.21705654811641, 8.74568114946603, -3.18313358274743, -0.957585048557372}, + {0.358599061347386, -0.645901171050299, 1.63582196821167, -1.03942072058345, -0.217874099304767, -3.4067356132321, -4.32754643767815, 0.217874099304766, 0.0277437349865084, -1.62196637959246, 1.88152475430886, 7.3643253669928, -5.59341172197236, 5.3669671582616}, + {-0.256528017544188, -0.800146649057355, 3.09145360938005, -4.39036898432437, 2.58371024925633, 1.71035484566764, -6.55298182608794, -2.58371024925633, -0.0694179343024073, -0.0943316944380133, 1.22042429534196, 0.619671975682703, -5.42148043073039, 10.9433508104123}, + {0.0106140386976428, -0.93322776861388, 4.54360101743677, -9.04890256063947, 10.0594948012644, -0.407304233739641, 2.33685342761973, -10.0594948012644, 0.251891870858455, 0.221351386525507, 0.449370472532274, -1.65825671502798, -2.47804006866914, 6.71204913301973}, + {-0.839131599831697, 0.357324567993201, -0.102043468455618, -0.103441279031611, 0.164296756824885, -1.11038492662884, 0.657213456864125, -0.164296756824885, -2.50614138554535, 4.95602107364847, -1.96807265626462, 0.453349470661745, 0.759078924422711, -0.553772177832514}, + {0.202323839685595, 0.340773582195419, -0.421182984203023, -0.0791514039043915, 0.132636253892542, -2.88418864164502, 0.648166663706482, -0.132636253892543, -1.56651227513635, 2.49708685921486, -1.47367200595952, 1.12225223956517, 2.18311938628288, -0.56901525980209}, + {0.183058222345733, 0.187879798307206, -0.356561429246204, 0.0494858460364144, -0.217874099304766, -0.695749161156662, -3.23863987105828, 0.217874099304766, -0.433623669198942, 0.661171915140911, -0.598486266594907, -0.0500309346159661, 1.10234152501883, 3.18915402502186}, + {-0.350190108838501, -0.191532755133865, 1.02081050608965, -2.17006723719339, 2.58371024925633, 1.83251546185973, -4.33268007895696, -2.58371024925633, 0.22698314742773, 0.202466309908141, 0.112273406636495, -1.69529235999188, -1.15803360795751, 6.50274731615034}, + {0.145502825089312, -0.690818483697242, 3.55560421346399, -7.68709166057282, 10.0594948012644, -1.09773794608675, 3.69866432768638, -10.0594948012644, 0.211294956599518, 0.140288140785009, 0.193732561223402, -1.26538609430655, -1.19248017307069, 3.98842733288643}, + {0.300790618534486, -0.300790618534487, 0.163623779272956, -0.380327367947866, 0.164296756824884, -0.163623779272954, 0.38032736794787, -0.164296756824884, -2.06707176953424, 0.0, 2.06707176953424, -1.17450557632146, 1.17450557632145, 0.0}, + {0.085894974571757, -0.0858949745717575, 0.0498205716536449, -0.363659033805437, 0.132636253892543, -0.0498205716536459, 0.363659033805436, -0.132636253892543, -0.356659826241754, 0.0, 0.356659826241756, -4.07548034456091, 4.07548034456091, 0.0}, + {-0.277867342742944, 0.277867342742944, -1.11401463610527, 1.64406285854735, -0.217874099304766, 1.11401463610526, -1.64406285854735, 0.217874099304766, 0.633344408222398, 0.0, -0.633344408222397, -4.42701173599888, 4.42701173599888, 0.0}, + {-0.270988583314474, 0.270988583314474, -1.00429605934332, 1.08130642088178, 2.58371024925633, 1.00429605934331, -1.08130642088178, -2.58371024925633, 0.440674683319929, 0.0, -0.44067468331993, -2.06396012039201, 2.06396012039201, 0.0}, + {0.388816964556484, -0.388816964556484, 2.24546238759736, -5.6928779941296, 10.0594948012644, -2.24546238759735, 5.6928779941296, -10.0594948012644, 0.0674685773616459, 0.0, -0.0674685773616422, -0.280079037151977, 0.280079037151975, -1.6970983117735e-14}, + {-0.357324567993201, 0.839131599831695, 1.11038492662884, -0.657213456864119, 0.164296756824883, 0.102043468455623, 0.103441279031613, -0.164296756824883, 1.96807265626462, -4.95602107364847, 2.50614138554536, -0.759078924422717, -0.453349470661745, 0.553772177832506}, + {-0.340773582195419, -0.202323839685595, 2.88418864164502, -0.648166663706484, 0.132636253892543, 0.421182984203023, 0.0791514039043915, -0.132636253892543, 1.47367200595952, -2.49708685921486, 1.56651227513635, -2.18311938628288, -1.12225223956516, 0.569015259802091}, + {-0.187879798307206, -0.183058222345732, 0.695749161156661, 3.23863987105828, -0.217874099304765, 0.356561429246203, -0.0494858460364157, 0.217874099304765, 0.598486266594908, -0.661171915140912, 0.433623669198941, -1.10234152501884, 0.0500309346159713, -3.18915402502186}, + {0.191532755133864, 0.3501901088385, -1.83251546185973, 4.33268007895695, 2.58371024925633, -1.02081050608966, 2.17006723719339, -2.58371024925633, -0.112273406636495, -0.202466309908141, -0.22698314742773, 1.15803360795751, 1.69529235999188, -6.50274731615035}, + {0.690818483697243, -0.145502825089313, 1.09773794608676, -3.69866432768638, 10.0594948012644, -3.55560421346399, 7.68709166057283, -10.0594948012644, -0.1937325612234, -0.140288140785019, -0.211294956599513, 1.1924801730707, 1.26538609430654, -3.98842733288646}, + {0.432860334906832, 4.92348092472478, 2.14826946464528, -0.846293744652684, 0.164296756824883, -0.10789658609876, -0.0856390087569605, -0.164296756824883, -2.30111931728086, 5.29615748963548, -8.35137943198624, 0.6986857227025, -2.73905860124902, 0.931932753409644}, + {0.513886950347989, 1.22072339702365, 6.17772359190216, -0.84245155808413, 0.132636253892544, -0.615176025183567, -0.115133490473247, -0.132636253892544, -2.21705654811641, 3.74343588801603, -3.26098968727125, 3.18313358274743, -8.74568114946602, 0.957585048557374}, + {0.645901171050299, -0.358599061347386, 3.40673561323211, 4.32754643767814, -0.217874099304764, -1.63582196821167, 1.03942072058346, 0.217874099304764, -1.88152475430886, 1.62196637959245, -0.0277437349865067, 5.59341172197235, -7.36432536699278, -5.3669671582616}, + {0.800146649057353, 0.256528017544187, -1.71035484566764, 6.55298182608793, 2.58371024925633, -3.09145360938005, 4.39036898432437, -2.58371024925633, -1.22042429534196, 0.0943316944380134, 0.0694179343024074, 5.42148043073038, -0.619671975682697, -10.9433508104123}, + {0.93322776861388, -0.0106140386976432, 0.407304233739652, -2.33685342761973, 10.0594948012644, -4.54360101743676, 9.04890256063948, -10.0594948012644, -0.449370472532272, -0.221351386525517, -0.25189187085845, 2.47804006866915, 1.65825671502797, -6.71204913301977}}; + + // Array of non-zero columns + static const unsigned int nzc11[14] = {15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; + + // Array of non-zero columns + static const unsigned int nzc8[14] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 900; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 60. + double G[12]; + G[0] = K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_00*det*(K_00*K_10 + K_01*K_11); + G[5] = K_10*det*(K_00*K_10 + K_01*K_11); + G[6] = K_01*det*(K_00*K_10 + K_01*K_11); + G[7] = K_11*det*(K_00*K_10 + K_01*K_11); + G[8] = K_00*det*(K_00*K_00 + K_01*K_01); + G[9] = K_10*det*(K_00*K_00 + K_01*K_01); + G[10] = K_01*det*(K_00*K_00 + K_01*K_01); + G[11] = K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 120000 + for (unsigned int ip = 0; ip < 25; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + + // Total number of operations to compute function values = 72 + for (unsigned int r = 0; r < 9; r++) + { + F0 += FE0_C0_D10[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D10[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 24 + double I[3]; + // Number of operations: 8 + I[0] = W25[ip]*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]); + + // Number of operations: 8 + I[1] = W25[ip]*(F0*G[4] + F1*G[5] + F2*G[6] + F3*G[7]); + + // Number of operations: 8 + I[2] = W25[ip]*(F0*G[8] + F1*G[9] + F2*G[10] + F3*G[11]); + + + // Number of operations for primary indices: 4704 + for (unsigned int j = 0; j < 14; j++) + { + for (unsigned int k = 0; k < 14; k++) + { + // Number of operations to compute entry: 3 + A[nzc10[j]*30 + nzc10[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc10[j]*30 + nzc11[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*30 + nzc10[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*30 + nzc11[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc7[j]*30 + nzc7[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc7[j]*30 + nzc8[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*30 + nzc7[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*30 + nzc8[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p3_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q4_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q4_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f1_p3_q4_tensor.h b/vector_laplacian_2d/vector_laplacian_f1_p3_q4_tensor.h new file mode 100644 index 0000000..7b7581e --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f1_p3_q4_tensor.h @@ -0,0 +1,24405 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F1_P3_Q4_TENSOR_H +#define __VECTOR_LAPLACIAN_F1_P3_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q4_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 15; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f1_p3_q4_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 30; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 15: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 20: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 21: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 22: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 23: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 24: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 25: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 26: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 27: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 28: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 29: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[20] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[21] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[22] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[23] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[24] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[25] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[26] = vals[1]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[27] = vals[1]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[28] = vals[1]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[29] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[15]; + vertex_values[3] = dof_values[16]; + vertex_values[5] = dof_values[17]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q4_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q4_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 3*m.num_entities[1] + 3*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 15; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 15; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 5; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 3; + break; + } + case 2: + { + return 3; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f1_p3_q4_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f1_p3_q4_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 6*m.num_entities[1] + 6*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 30; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 30; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 10; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 6; + break; + } + case 2: + { + return 6; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + dofs[15] = offset + c.entity_indices[0][0]; + dofs[16] = offset + c.entity_indices[0][1]; + dofs[17] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[18] = offset + 3*c.entity_indices[1][0]; + dofs[19] = offset + 3*c.entity_indices[1][0] + 1; + dofs[20] = offset + 3*c.entity_indices[1][0] + 2; + dofs[21] = offset + 3*c.entity_indices[1][1]; + dofs[22] = offset + 3*c.entity_indices[1][1] + 1; + dofs[23] = offset + 3*c.entity_indices[1][1] + 2; + dofs[24] = offset + 3*c.entity_indices[1][2]; + dofs[25] = offset + 3*c.entity_indices[1][2] + 1; + dofs[26] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[27] = offset + 3*c.entity_indices[2][0]; + dofs[28] = offset + 3*c.entity_indices[2][0] + 1; + dofs[29] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + dofs[5] = 16; + dofs[6] = 17; + dofs[7] = 18; + dofs[8] = 19; + dofs[9] = 20; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + dofs[5] = 15; + dofs[6] = 17; + dofs[7] = 21; + dofs[8] = 22; + dofs[9] = 23; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + dofs[5] = 15; + dofs[6] = 16; + dofs[7] = 24; + dofs[8] = 25; + dofs[9] = 26; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 15; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 16; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 17; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + dofs[3] = 18; + dofs[4] = 19; + dofs[5] = 20; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + dofs[3] = 21; + dofs[4] = 22; + dofs[5] = 23; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + dofs[3] = 24; + dofs[4] = 25; + dofs[5] = 26; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + dofs[3] = 27; + dofs[4] = 28; + dofs[5] = 29; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + coordinates[15][0] = x[0][0]; + coordinates[15][1] = x[0][1]; + coordinates[16][0] = x[1][0]; + coordinates[16][1] = x[1][1]; + coordinates[17][0] = x[2][0]; + coordinates[17][1] = x[2][1]; + coordinates[18][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[18][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[19][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[19][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[20][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[20][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[21][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[21][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[22][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[22][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[23][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[23][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[24][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[24][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[25][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[25][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[26][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[26][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[27][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[27][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[28][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[28][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[29][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[29][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f1_p3_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 432 + // Number of operations (multiply-add pairs) for tensor contraction: 19061 + // Total number of operations (multiply-add pairs): 19504 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0 = det*(w[0][0]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1 = det*(w[0][0]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0 = det*(w[0][1]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1 = det*(w[0][2]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0 = det*(w[0][3]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1 = det*(w[0][3]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0 = det*(w[0][4]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1 = det*(w[0][4]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0 = det*(w[0][5]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1 = det*(w[0][5]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_0_0 = det*(w[0][6]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_0_1 = det*(w[0][6]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_0_0 = det*(w[0][7]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_0_1 = det*(w[0][7]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_0_0 = det*(w[0][8]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_0_1 = det*(w[0][8]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_0_0 = det*(w[0][9]*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_0_1 = det*(w[0][9]*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0 = det*(w[0][10]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1 = det*(w[0][10]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0 = det*(w[0][11]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_12_1_1 = det*(w[0][12]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_13_1_0 = det*(w[0][13]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_13_1_1 = det*(w[0][13]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_14_1_0 = det*(w[0][14]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_14_1_1 = det*(w[0][14]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_15_1_0 = det*(w[0][15]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_15_1_1 = det*(w[0][15]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_16_1_0 = det*(w[0][16]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_16_1_1 = det*(w[0][16]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_17_1_0 = det*(w[0][17]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_17_1_1 = det*(w[0][17]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_18_1_0 = det*(w[0][18]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_18_1_1 = det*(w[0][18]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_19_1_0 = det*(w[0][19]*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_19_1_1 = det*(w[0][19]*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0 = det*(w[0][0]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1 = det*(w[0][0]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0 = det*(w[0][1]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1 = det*(w[0][2]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0 = det*(w[0][3]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1 = det*(w[0][3]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0 = det*(w[0][4]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1 = det*(w[0][4]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0 = det*(w[0][5]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1 = det*(w[0][5]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_0_0 = det*(w[0][6]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_0_1 = det*(w[0][6]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_0_0 = det*(w[0][7]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_0_1 = det*(w[0][7]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_0_0 = det*(w[0][8]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_0_1 = det*(w[0][8]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_0_0 = det*(w[0][9]*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_0_1 = det*(w[0][9]*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0 = det*(w[0][10]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1 = det*(w[0][10]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0 = det*(w[0][11]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_12_1_1 = det*(w[0][12]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_13_1_0 = det*(w[0][13]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_13_1_1 = det*(w[0][13]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_14_1_0 = det*(w[0][14]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_14_1_1 = det*(w[0][14]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_15_1_0 = det*(w[0][15]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_15_1_1 = det*(w[0][15]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_16_1_0 = det*(w[0][16]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_16_1_1 = det*(w[0][16]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_17_1_0 = det*(w[0][17]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_17_1_1 = det*(w[0][17]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_18_1_0 = det*(w[0][18]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_18_1_1 = det*(w[0][18]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_19_1_0 = det*(w[0][19]*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_19_1_1 = det*(w[0][19]*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0 = det*(w[0][0]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1 = det*(w[0][0]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0 = det*(w[0][1]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1 = det*(w[0][2]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0 = det*(w[0][3]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1 = det*(w[0][3]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0 = det*(w[0][4]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1 = det*(w[0][4]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0 = det*(w[0][5]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1 = det*(w[0][5]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_0_0 = det*(w[0][6]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_0_1 = det*(w[0][6]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_0_0 = det*(w[0][7]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_0_1 = det*(w[0][7]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_0_0 = det*(w[0][8]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_0_1 = det*(w[0][8]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_0_0 = det*(w[0][9]*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_0_1 = det*(w[0][9]*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0 = det*(w[0][10]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1 = det*(w[0][10]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0 = det*(w[0][11]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_12_1_1 = det*(w[0][12]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_13_1_0 = det*(w[0][13]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_13_1_1 = det*(w[0][13]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_14_1_0 = det*(w[0][14]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_14_1_1 = det*(w[0][14]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_15_1_0 = det*(w[0][15]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_15_1_1 = det*(w[0][15]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_16_1_0 = det*(w[0][16]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_16_1_1 = det*(w[0][16]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_17_1_0 = det*(w[0][17]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_17_1_1 = det*(w[0][17]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_18_1_0 = det*(w[0][18]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_18_1_1 = det*(w[0][18]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_19_1_0 = det*(w[0][19]*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_19_1_1 = det*(w[0][19]*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0 = det*(w[0][0]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1 = det*(w[0][0]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0 = det*(w[0][1]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1 = det*(w[0][2]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0 = det*(w[0][3]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1 = det*(w[0][3]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0 = det*(w[0][4]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1 = det*(w[0][4]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0 = det*(w[0][5]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1 = det*(w[0][5]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_0_0 = det*(w[0][6]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_0_1 = det*(w[0][6]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_0_0 = det*(w[0][7]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_0_1 = det*(w[0][7]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_0_0 = det*(w[0][8]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_0_1 = det*(w[0][8]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_0_0 = det*(w[0][9]*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_0_1 = det*(w[0][9]*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0 = det*(w[0][10]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1 = det*(w[0][10]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0 = det*(w[0][11]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_12_1_1 = det*(w[0][12]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_13_1_0 = det*(w[0][13]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_13_1_1 = det*(w[0][13]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_14_1_0 = det*(w[0][14]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_14_1_1 = det*(w[0][14]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_15_1_0 = det*(w[0][15]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_15_1_1 = det*(w[0][15]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_16_1_0 = det*(w[0][16]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_16_1_1 = det*(w[0][16]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_17_1_0 = det*(w[0][17]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_17_1_1 = det*(w[0][17]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_18_1_0 = det*(w[0][18]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_18_1_1 = det*(w[0][18]*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_19_1_0 = det*(w[0][19]*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_19_1_1 = det*(w[0][19]*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[213] = -0.106666666666667*G0_0_0_0_0_0 - 0.106666666666667*G0_0_0_0_0_1 - 0.167619047619047*G0_0_0_1_0_0 + 0.15238095238095*G0_0_0_2_0_1 + 0.426666666666669*G0_0_0_3_0_0 + 0.060952380952382*G0_0_0_3_0_1 - 0.0761904761904781*G0_0_0_4_0_0 - 0.0304761904761869*G0_0_0_4_0_1 + 1.03619047619047*G0_0_0_5_0_0 + 0.914285714285709*G0_0_0_5_0_1 + 0.0761904761904785*G0_0_0_6_0_0 - 0.959999999999992*G0_0_0_6_0_1 - 0.18285714285714*G0_0_0_7_0_0 - 0.0609523809523795*G0_0_0_7_0_1 + 0.457142857142853*G0_0_0_8_0_0 - 0.060952380952382*G0_0_0_8_0_1 - 1.46285714285714*G0_0_0_9_0_0 + 0.0914285714285665*G0_0_0_9_0_1 - 0.106666666666667*G0_0_0_10_1_0 - 0.106666666666667*G0_0_0_10_1_1 - 0.167619047619047*G0_0_0_11_1_0 + 0.15238095238095*G0_0_0_12_1_1 + 0.426666666666669*G0_0_0_13_1_0 + 0.060952380952382*G0_0_0_13_1_1 - 0.0761904761904781*G0_0_0_14_1_0 - 0.0304761904761869*G0_0_0_14_1_1 + 1.03619047619047*G0_0_0_15_1_0 + 0.914285714285709*G0_0_0_15_1_1 + 0.0761904761904785*G0_0_0_16_1_0 - 0.959999999999992*G0_0_0_16_1_1 - 0.18285714285714*G0_0_0_17_1_0 - 0.0609523809523795*G0_0_0_17_1_1 + 0.457142857142853*G0_0_0_18_1_0 - 0.060952380952382*G0_0_0_18_1_1 - 1.46285714285714*G0_0_0_19_1_0 + 0.0914285714285665*G0_0_0_19_1_1 - 0.0313227513227506*G0_0_1_0_0_0 - 0.0313227513227506*G0_0_1_0_0_1 - 0.0550264550264596*G0_0_1_1_0_0 + 0.0414814814814782*G0_0_1_2_0_1 + 0.0152380952380967*G0_0_1_3_0_0 - 0.0634920634920711*G0_0_1_3_0_1 + 0.00761904761904413*G0_0_1_4_0_0 - 0.0101587301587259*G0_0_1_4_0_1 + 0.182857142857141*G0_0_1_5_0_0 + 0.193015873015871*G0_0_1_5_0_1 - 0.00761904761904406*G0_0_1_6_0_0 - 0.203174603174599*G0_0_1_6_0_1 - 0.0253968253968269*G0_0_1_7_0_0 - 0.0355555555555575*G0_0_1_7_0_1 + 0.111746031746037*G0_0_1_8_0_0 + 0.0634920634920711*G0_0_1_8_0_1 - 0.198095238095237*G0_0_1_9_0_0 + 0.0457142857142834*G0_0_1_9_0_1 - 0.0313227513227506*G0_0_1_10_1_0 - 0.0313227513227506*G0_0_1_10_1_1 - 0.0550264550264596*G0_0_1_11_1_0 + 0.0414814814814782*G0_0_1_12_1_1 + 0.0152380952380967*G0_0_1_13_1_0 - 0.0634920634920711*G0_0_1_13_1_1 + 0.00761904761904413*G0_0_1_14_1_0 - 0.0101587301587259*G0_0_1_14_1_1 + 0.182857142857141*G0_0_1_15_1_0 + 0.193015873015871*G0_0_1_15_1_1 - 0.00761904761904406*G0_0_1_16_1_0 - 0.203174603174599*G0_0_1_16_1_1 - 0.0253968253968269*G0_0_1_17_1_0 - 0.0355555555555575*G0_0_1_17_1_1 + 0.111746031746037*G0_0_1_18_1_0 + 0.0634920634920711*G0_0_1_18_1_1 - 0.198095238095237*G0_0_1_19_1_0 + 0.0457142857142834*G0_0_1_19_1_1 - 0.163386243386242*G0_1_0_0_0_0 - 0.163386243386242*G0_1_0_0_0_1 - 0.0347089947089953*G0_1_0_1_0_0 + 0.0567195767195755*G0_1_0_2_0_1 + 0.0609523809523838*G0_1_0_3_0_0 - 0.0304761904761902*G0_1_0_3_0_1 - 0.0533333333333339*G0_1_0_4_0_0 - 0.0533333333333304*G0_1_0_4_0_1 + 0.25904761904762*G0_1_0_5_0_0 + 0.464761904761902*G0_1_0_5_0_1 + 0.053333333333334*G0_1_0_6_0_0 - 0.358095238095236*G0_1_0_6_0_1 + 0.167619047619046*G0_1_0_7_0_0 - 0.0380952380952365*G0_1_0_7_0_1 + 0.0304761904761913*G0_1_0_8_0_0 + 0.0304761904761903*G0_1_0_8_0_1 - 0.320000000000004*G0_1_0_9_0_0 + 0.0914285714285668*G0_1_0_9_0_1 - 0.163386243386242*G0_1_0_10_1_0 - 0.163386243386242*G0_1_0_10_1_1 - 0.0347089947089953*G0_1_0_11_1_0 + 0.0567195767195755*G0_1_0_12_1_1 + 0.0609523809523838*G0_1_0_13_1_0 - 0.0304761904761902*G0_1_0_13_1_1 - 0.0533333333333339*G0_1_0_14_1_0 - 0.0533333333333304*G0_1_0_14_1_1 + 0.25904761904762*G0_1_0_15_1_0 + 0.464761904761902*G0_1_0_15_1_1 + 0.053333333333334*G0_1_0_16_1_0 - 0.358095238095236*G0_1_0_16_1_1 + 0.167619047619046*G0_1_0_17_1_0 - 0.0380952380952365*G0_1_0_17_1_1 + 0.0304761904761913*G0_1_0_18_1_0 + 0.0304761904761903*G0_1_0_18_1_1 - 0.320000000000004*G0_1_0_19_1_0 + 0.0914285714285668*G0_1_0_19_1_1 + 0.0101587301587311*G0_1_1_0_0_0 + 0.0101587301587311*G0_1_1_0_0_1 + 0.0101587301587276*G0_1_1_2_0_1 - 0.0330158730158721*G0_1_1_3_0_0 - 0.00253968253968514*G0_1_1_4_0_0 - 0.0457142857142823*G0_1_1_4_0_1 - 0.0126984126984139*G0_1_1_5_0_0 - 0.0101587301587319*G0_1_1_5_0_1 + 0.00253968253968513*G0_1_1_6_0_0 - 0.0101587301587268*G0_1_1_6_0_1 - 0.0431746031746049*G0_1_1_7_0_0 - 0.045714285714287*G0_1_1_7_0_1 + 0.0330158730158776*G0_1_1_8_0_0 + 0.045714285714286*G0_1_1_9_0_0 + 0.0914285714285691*G0_1_1_9_0_1 + 0.0101587301587311*G0_1_1_10_1_0 + 0.0101587301587311*G0_1_1_10_1_1 + 0.0101587301587276*G0_1_1_12_1_1 - 0.0330158730158721*G0_1_1_13_1_0 - 0.00253968253968514*G0_1_1_14_1_0 - 0.0457142857142823*G0_1_1_14_1_1 - 0.0126984126984139*G0_1_1_15_1_0 - 0.0101587301587319*G0_1_1_15_1_1 + 0.00253968253968513*G0_1_1_16_1_0 - 0.0101587301587268*G0_1_1_16_1_1 - 0.0431746031746049*G0_1_1_17_1_0 - 0.045714285714287*G0_1_1_17_1_1 + 0.0330158730158776*G0_1_1_18_1_0 + 0.045714285714286*G0_1_1_19_1_0 + 0.0914285714285691*G0_1_1_19_1_1; + A[489] = 0.0; + A[208] = 0.0; + A[574] = 0.0; + A[530] = -0.423280423280422*G0_1_0_0_0_0 - 0.423280423280422*G0_1_0_0_0_1 + 0.423280423280422*G0_1_0_1_0_0 + 2.80423280423279*G0_1_0_2_0_1 - 2.02539682539681*G0_1_0_3_0_0 - 0.149206349206346*G0_1_0_3_0_1 + 5.11746031746029*G0_1_0_4_0_0 + 0.860317460317457*G0_1_0_4_0_1 + 2.02539682539682*G0_1_0_5_0_0 + 1.87619047619047*G0_1_0_5_0_1 - 5.11746031746029*G0_1_0_6_0_0 - 4.25714285714284*G0_1_0_6_0_1 + 0.14920634920635*G0_1_0_7_0_1 + 0.149206349206346*G0_1_0_8_0_1 - 1.00952380952381*G0_1_0_9_0_1 - 0.423280423280422*G0_1_0_10_1_0 - 0.423280423280422*G0_1_0_10_1_1 + 0.423280423280422*G0_1_0_11_1_0 + 2.80423280423279*G0_1_0_12_1_1 - 2.02539682539681*G0_1_0_13_1_0 - 0.149206349206346*G0_1_0_13_1_1 + 5.11746031746029*G0_1_0_14_1_0 + 0.860317460317457*G0_1_0_14_1_1 + 2.02539682539682*G0_1_0_15_1_0 + 1.87619047619047*G0_1_0_15_1_1 - 5.11746031746029*G0_1_0_16_1_0 - 4.25714285714284*G0_1_0_16_1_1 + 0.14920634920635*G0_1_0_17_1_1 + 0.149206349206346*G0_1_0_18_1_1 - 1.00952380952381*G0_1_0_19_1_1 - 0.139682539682539*G0_1_1_0_0_0 - 0.139682539682539*G0_1_1_0_0_1 - 0.0571428571428575*G0_1_1_1_0_0 + 0.77460317460317*G0_1_1_2_0_1 - 0.561904761904759*G0_1_1_3_0_0 - 0.406349206349205*G0_1_1_3_0_1 + 1.55238095238094*G0_1_1_4_0_0 + 0.565079365079363*G0_1_1_4_0_1 + 0.733333333333329*G0_1_1_5_0_0 + 0.634920634920632*G0_1_1_5_0_1 - 1.55238095238094*G0_1_1_6_0_0 - 1.26984126984126*G0_1_1_6_0_1 + 0.0984126984126979*G0_1_1_7_0_0 + 0.196825396825395*G0_1_1_7_0_1 + 0.0984126984126982*G0_1_1_8_0_0 + 0.406349206349205*G0_1_1_8_0_1 - 0.17142857142857*G0_1_1_9_0_0 - 0.761904761904758*G0_1_1_9_0_1 - 0.139682539682539*G0_1_1_10_1_0 - 0.139682539682539*G0_1_1_10_1_1 - 0.0571428571428575*G0_1_1_11_1_0 + 0.77460317460317*G0_1_1_12_1_1 - 0.561904761904759*G0_1_1_13_1_0 - 0.406349206349205*G0_1_1_13_1_1 + 1.55238095238094*G0_1_1_14_1_0 + 0.565079365079363*G0_1_1_14_1_1 + 0.733333333333329*G0_1_1_15_1_0 + 0.634920634920632*G0_1_1_15_1_1 - 1.55238095238094*G0_1_1_16_1_0 - 1.26984126984126*G0_1_1_16_1_1 + 0.0984126984126979*G0_1_1_17_1_0 + 0.196825396825395*G0_1_1_17_1_1 + 0.0984126984126982*G0_1_1_18_1_0 + 0.406349206349205*G0_1_1_18_1_1 - 0.17142857142857*G0_1_1_19_1_0 - 0.761904761904758*G0_1_1_19_1_1; + A[235] = 0.0; + A[679] = A[213] + 0.128253968253968*G0_0_0_0_0_0 + 0.128253968253968*G0_0_0_0_0_1 + 0.146031746031746*G0_0_0_1_0_0 - 0.825396825396811*G0_0_0_2_0_1 + 0.639999999999984*G0_0_0_3_0_0 - 0.171428571428553*G0_0_0_4_0_0 + 1.43999999999999*G0_0_0_4_0_1 - 2.10285714285713*G0_0_0_5_0_0 - 1.91999999999999*G0_0_0_5_0_1 + 0.171428571428553*G0_0_0_6_0_0 + 2.61714285714283*G0_0_0_6_0_1 + 0.822857142857136*G0_0_0_7_0_0 + 0.639999999999995*G0_0_0_7_0_1 - 1.09714285714285*G0_0_0_8_0_0 + 1.46285714285714*G0_0_0_9_0_0 - 2.07999999999999*G0_0_0_9_0_1 + 0.128253968253968*G0_0_0_10_1_0 + 0.128253968253968*G0_0_0_10_1_1 + 0.146031746031746*G0_0_0_11_1_0 - 0.825396825396811*G0_0_0_12_1_1 + 0.639999999999984*G0_0_0_13_1_0 - 0.171428571428553*G0_0_0_14_1_0 + 1.43999999999999*G0_0_0_14_1_1 - 2.10285714285713*G0_0_0_15_1_0 - 1.91999999999999*G0_0_0_15_1_1 + 0.171428571428553*G0_0_0_16_1_0 + 2.61714285714283*G0_0_0_16_1_1 + 0.822857142857136*G0_0_0_17_1_0 + 0.639999999999995*G0_0_0_17_1_1 - 1.09714285714285*G0_0_0_18_1_0 + 1.46285714285714*G0_0_0_19_1_0 - 2.07999999999999*G0_0_0_19_1_1 + 0.0421164021163999*G0_0_1_0_0_0 + 0.0421164021163999*G0_0_1_0_0_1 + 0.0747089947090046*G0_0_1_1_0_0 - 0.311322751322742*G0_0_1_2_0_1 + 0.468571428571424*G0_0_1_3_0_0 + 0.172063492063508*G0_0_1_3_0_1 - 0.112380952380939*G0_0_1_4_0_0 + 0.570158730158724*G0_0_1_4_0_1 - 0.632380952380947*G0_0_1_5_0_0 - 0.612063492063487*G0_0_1_5_0_1 + 0.112380952380939*G0_0_1_6_0_0 + 0.881269841269829*G0_0_1_6_0_1 + 0.261587301587306*G0_0_1_7_0_0 + 0.241269841269845*G0_0_1_7_0_1 - 0.37841269841271*G0_0_1_8_0_0 - 0.172063492063508*G0_0_1_8_0_1 + 0.163809523809523*G0_0_1_9_0_0 - 0.81142857142857*G0_0_1_9_0_1 + 0.0421164021163999*G0_0_1_10_1_0 + 0.0421164021163999*G0_0_1_10_1_1 + 0.0747089947090046*G0_0_1_11_1_0 - 0.311322751322742*G0_0_1_12_1_1 + 0.468571428571424*G0_0_1_13_1_0 + 0.172063492063508*G0_0_1_13_1_1 - 0.112380952380939*G0_0_1_14_1_0 + 0.570158730158724*G0_0_1_14_1_1 - 0.632380952380947*G0_0_1_15_1_0 - 0.612063492063487*G0_0_1_15_1_1 + 0.112380952380939*G0_0_1_16_1_0 + 0.881269841269829*G0_0_1_16_1_1 + 0.261587301587306*G0_0_1_17_1_0 + 0.241269841269845*G0_0_1_17_1_1 - 0.37841269841271*G0_0_1_18_1_0 - 0.172063492063508*G0_0_1_18_1_1 + 0.163809523809523*G0_0_1_19_1_0 - 0.81142857142857*G0_0_1_19_1_1 + 0.204656084656085*G0_1_0_0_0_0 + 0.204656084656085*G0_1_0_0_0_1 + 0.0239153439153459*G0_1_0_1_0_0 - 0.459894179894172*G0_1_0_2_0_1 + 0.556190476190462*G0_1_0_3_0_0 + 0.06095238095238*G0_1_0_3_0_1 - 0.0895238095237983*G0_1_0_4_0_0 + 0.8895238095238*G0_1_0_4_0_1 - 0.841904761904758*G0_1_0_5_0_0 - 1.09523809523809*G0_1_0_5_0_1 + 0.0895238095237985*G0_1_0_6_0_0 + 1.35047619047618*G0_1_0_6_0_1 + 0.205714285714283*G0_1_0_7_0_0 + 0.459047619047617*G0_1_0_7_0_1 - 0.434285714285714*G0_1_0_8_0_0 - 0.0609523809523802*G0_1_0_8_0_1 + 0.285714285714295*G0_1_0_9_0_0 - 1.34857142857142*G0_1_0_9_0_1 + 0.204656084656085*G0_1_0_10_1_0 + 0.204656084656085*G0_1_0_10_1_1 + 0.0239153439153459*G0_1_0_11_1_0 - 0.459894179894172*G0_1_0_12_1_1 + 0.556190476190462*G0_1_0_13_1_0 + 0.06095238095238*G0_1_0_13_1_1 - 0.0895238095237983*G0_1_0_14_1_0 + 0.8895238095238*G0_1_0_14_1_1 - 0.841904761904758*G0_1_0_15_1_0 - 1.09523809523809*G0_1_0_15_1_1 + 0.0895238095237985*G0_1_0_16_1_0 + 1.35047619047618*G0_1_0_16_1_1 + 0.205714285714283*G0_1_0_17_1_0 + 0.459047619047617*G0_1_0_17_1_1 - 0.434285714285714*G0_1_0_18_1_0 - 0.0609523809523802*G0_1_0_18_1_1 + 0.285714285714295*G0_1_0_19_1_0 - 1.34857142857142*G0_1_0_19_1_1 + 0.0761904761904777*G0_1_1_0_0_0 + 0.0761904761904776*G0_1_1_0_0_1 - 0.0558730158730084*G0_1_1_1_0_0 - 0.12698412698412*G0_1_1_2_0_1 + 0.217777777777775*G0_1_1_3_0_0 - 0.0304761904761779*G0_1_1_3_0_1 - 0.0412698412698314*G0_1_1_4_0_0 + 0.278095238095233*G0_1_1_4_0_1 - 0.137777777777771*G0_1_1_5_0_0 - 0.248888888888889*G0_1_1_5_0_1 + 0.0412698412698314*G0_1_1_6_0_0 + 0.299682539682532*G0_1_1_6_0_1 - 0.046349206349207*G0_1_1_7_0_0 + 0.064761904761911*G0_1_1_7_0_1 + 0.0260317460317378*G0_1_1_8_0_0 + 0.0304761904761779*G0_1_1_8_0_1 - 0.0800000000000036*G0_1_1_9_0_0 - 0.342857142857144*G0_1_1_9_0_1 + 0.0761904761904777*G0_1_1_10_1_0 + 0.0761904761904776*G0_1_1_10_1_1 - 0.0558730158730084*G0_1_1_11_1_0 - 0.12698412698412*G0_1_1_12_1_1 + 0.217777777777775*G0_1_1_13_1_0 - 0.0304761904761779*G0_1_1_13_1_1 - 0.0412698412698314*G0_1_1_14_1_0 + 0.278095238095233*G0_1_1_14_1_1 - 0.137777777777771*G0_1_1_15_1_0 - 0.248888888888889*G0_1_1_15_1_1 + 0.0412698412698314*G0_1_1_16_1_0 + 0.299682539682532*G0_1_1_16_1_1 - 0.046349206349207*G0_1_1_17_1_0 + 0.064761904761911*G0_1_1_17_1_1 + 0.0260317460317378*G0_1_1_18_1_0 + 0.0304761904761779*G0_1_1_18_1_1 - 0.0800000000000036*G0_1_1_19_1_0 - 0.342857142857144*G0_1_1_19_1_1; + A[607] = 0.0; + A[716] = -0.04063492063492*G0_0_0_0_0_0 - 0.0406349206349199*G0_0_0_0_0_1 + 0.0203174603174595*G0_0_0_1_0_0 + 0.121904761904761*G0_0_0_3_0_0 + 0.0711111111111095*G0_0_0_3_0_1 + 0.0711111111111114*G0_0_0_4_0_1 + 0.121904761904761*G0_0_0_5_0_0 + 0.111746031746031*G0_0_0_5_0_1 - 0.0711111111111106*G0_0_0_6_0_1 + 0.101587301587299*G0_0_0_7_0_0 + 0.11174603174603*G0_0_0_7_0_1 - 0.0812698412698389*G0_0_0_8_0_0 - 0.0711111111111095*G0_0_0_8_0_1 - 0.243809523809522*G0_0_0_9_0_0 - 0.182857142857141*G0_0_0_9_0_1 - 0.04063492063492*G0_0_0_10_1_0 - 0.0406349206349199*G0_0_0_10_1_1 + 0.0203174603174595*G0_0_0_11_1_0 + 0.121904761904761*G0_0_0_13_1_0 + 0.0711111111111095*G0_0_0_13_1_1 + 0.0711111111111114*G0_0_0_14_1_1 + 0.121904761904761*G0_0_0_15_1_0 + 0.111746031746031*G0_0_0_15_1_1 - 0.0711111111111106*G0_0_0_16_1_1 + 0.101587301587299*G0_0_0_17_1_0 + 0.11174603174603*G0_0_0_17_1_1 - 0.0812698412698389*G0_0_0_18_1_0 - 0.0711111111111095*G0_0_0_18_1_1 - 0.243809523809522*G0_0_0_19_1_0 - 0.182857142857141*G0_0_0_19_1_1 - 0.0304761904761902*G0_0_1_0_0_0 - 0.0304761904761902*G0_0_1_0_0_1 + 0.152380952380949*G0_0_1_1_0_0 + 0.15238095238095*G0_0_1_2_0_1 - 0.0203174603174599*G0_0_1_3_0_0 + 0.253968253968249*G0_0_1_3_0_1 + 0.253968253968251*G0_0_1_4_0_0 - 0.0203174603174581*G0_0_1_4_0_1 + 0.0812698412698405*G0_0_1_5_0_0 + 0.0609523809523806*G0_0_1_5_0_1 - 0.253968253968252*G0_0_1_6_0_0 - 0.182857142857141*G0_0_1_6_0_1 + 0.0609523809523802*G0_0_1_7_0_0 + 0.0812698412698401*G0_0_1_7_0_1 - 0.182857142857139*G0_0_1_8_0_0 - 0.253968253968249*G0_0_1_8_0_1 - 0.0609523809523805*G0_0_1_9_0_0 - 0.0609523809523819*G0_0_1_9_0_1 - 0.0304761904761902*G0_0_1_10_1_0 - 0.0304761904761902*G0_0_1_10_1_1 + 0.152380952380949*G0_0_1_11_1_0 + 0.15238095238095*G0_0_1_12_1_1 - 0.0203174603174599*G0_0_1_13_1_0 + 0.253968253968249*G0_0_1_13_1_1 + 0.253968253968251*G0_0_1_14_1_0 - 0.0203174603174581*G0_0_1_14_1_1 + 0.0812698412698405*G0_0_1_15_1_0 + 0.0609523809523806*G0_0_1_15_1_1 - 0.253968253968252*G0_0_1_16_1_0 - 0.182857142857141*G0_0_1_16_1_1 + 0.0609523809523802*G0_0_1_17_1_0 + 0.0812698412698401*G0_0_1_17_1_1 - 0.182857142857139*G0_0_1_18_1_0 - 0.253968253968249*G0_0_1_18_1_1 - 0.0609523809523805*G0_0_1_19_1_0 - 0.0609523809523819*G0_0_1_19_1_1 - 0.0101587301587313*G0_1_0_0_0_0 - 0.0101587301587313*G0_1_0_0_0_1 + 0.132063492063489*G0_1_0_1_0_0 + 0.132063492063491*G0_1_0_2_0_1 - 0.152380952380952*G0_1_0_3_0_0 + 0.182857142857138*G0_1_0_3_0_1 + 0.182857142857141*G0_1_0_4_0_0 - 0.15238095238095*G0_1_0_4_0_1 - 0.0914285714285721*G0_1_0_5_0_0 - 0.0304761904761883*G0_1_0_5_0_1 - 0.182857142857141*G0_1_0_6_0_0 - 0.0914285714285713*G0_1_0_6_0_1 - 0.0304761904761896*G0_1_0_7_0_0 - 0.0914285714285731*G0_1_0_7_0_1 - 0.0914285714285685*G0_1_0_8_0_0 - 0.182857142857138*G0_1_0_8_0_1 + 0.243809523809524*G0_1_0_9_0_0 + 0.243809523809523*G0_1_0_9_0_1 - 0.0101587301587313*G0_1_0_10_1_0 - 0.0101587301587313*G0_1_0_10_1_1 + 0.132063492063489*G0_1_0_11_1_0 + 0.132063492063491*G0_1_0_12_1_1 - 0.152380952380952*G0_1_0_13_1_0 + 0.182857142857138*G0_1_0_13_1_1 + 0.182857142857141*G0_1_0_14_1_0 - 0.15238095238095*G0_1_0_14_1_1 - 0.0914285714285721*G0_1_0_15_1_0 - 0.0304761904761883*G0_1_0_15_1_1 - 0.182857142857141*G0_1_0_16_1_0 - 0.0914285714285713*G0_1_0_16_1_1 - 0.0304761904761896*G0_1_0_17_1_0 - 0.0914285714285731*G0_1_0_17_1_1 - 0.0914285714285685*G0_1_0_18_1_0 - 0.182857142857138*G0_1_0_18_1_1 + 0.243809523809524*G0_1_0_19_1_0 + 0.243809523809523*G0_1_0_19_1_1 - 0.0406349206349197*G0_1_1_0_0_0 - 0.0406349206349197*G0_1_1_0_0_1 + 0.020317460317459*G0_1_1_2_0_1 + 0.0711111111111111*G0_1_1_3_0_0 + 0.0711111111111105*G0_1_1_4_0_0 + 0.121904761904765*G0_1_1_4_0_1 + 0.111746031746031*G0_1_1_5_0_0 + 0.1015873015873*G0_1_1_5_0_1 - 0.0711111111111105*G0_1_1_6_0_0 - 0.0812698412698398*G0_1_1_6_0_1 + 0.111746031746029*G0_1_1_7_0_0 + 0.12190476190476*G0_1_1_7_0_1 - 0.0711111111111061*G0_1_1_8_0_0 - 0.182857142857142*G0_1_1_9_0_0 - 0.243809523809525*G0_1_1_9_0_1 - 0.0406349206349197*G0_1_1_10_1_0 - 0.0406349206349197*G0_1_1_10_1_1 + 0.020317460317459*G0_1_1_12_1_1 + 0.0711111111111111*G0_1_1_13_1_0 + 0.0711111111111105*G0_1_1_14_1_0 + 0.121904761904765*G0_1_1_14_1_1 + 0.111746031746031*G0_1_1_15_1_0 + 0.1015873015873*G0_1_1_15_1_1 - 0.0711111111111105*G0_1_1_16_1_0 - 0.0812698412698398*G0_1_1_16_1_1 + 0.111746031746029*G0_1_1_17_1_0 + 0.12190476190476*G0_1_1_17_1_1 - 0.0711111111111061*G0_1_1_18_1_0 - 0.182857142857142*G0_1_1_19_1_0 - 0.243809523809525*G0_1_1_19_1_1; + A[636] = 0.0; + A[245] = 0.982010582010579*G0_0_0_0_0_0 + 0.982010582010579*G0_0_0_0_0_1 - 0.982010582010579*G0_0_0_1_0_0 - 6.77248677248673*G0_0_0_2_0_1 + 4.67301587301584*G0_0_0_3_0_0 + 0.406349206349199*G0_0_0_3_0_1 - 12.6984126984126*G0_0_0_4_0_0 - 2.64126984126983*G0_0_0_4_0_1 - 4.67301587301585*G0_0_0_5_0_0 - 4.26666666666665*G0_0_0_5_0_1 + 12.6984126984126*G0_0_0_6_0_0 + 10.0571428571428*G0_0_0_6_0_1 - 0.406349206349208*G0_0_0_7_0_1 - 0.4063492063492*G0_0_0_8_0_1 + 3.04761904761904*G0_0_0_9_0_1 + 0.982010582010579*G0_0_0_10_1_0 + 0.982010582010579*G0_0_0_10_1_1 - 0.982010582010579*G0_0_0_11_1_0 - 6.77248677248673*G0_0_0_12_1_1 + 4.67301587301584*G0_0_0_13_1_0 + 0.406349206349199*G0_0_0_13_1_1 - 12.6984126984126*G0_0_0_14_1_0 - 2.64126984126983*G0_0_0_14_1_1 - 4.67301587301585*G0_0_0_15_1_0 - 4.26666666666665*G0_0_0_15_1_1 + 12.6984126984126*G0_0_0_16_1_0 + 10.0571428571428*G0_0_0_16_1_1 - 0.406349206349208*G0_0_0_17_1_1 - 0.4063492063492*G0_0_0_18_1_1 + 3.04761904761904*G0_0_0_19_1_1 + 0.491005291005289*G0_0_1_0_0_0 + 0.491005291005289*G0_0_1_0_0_1 - 0.0846560846560839*G0_0_1_1_0_0 - 2.42116402116401*G0_0_1_2_0_1 + 0.609523809523806*G0_0_1_3_0_0 + 0.253968253968253*G0_0_1_3_0_1 - 5.0285714285714*G0_0_1_4_0_0 - 2.33650793650793*G0_0_1_4_0_1 - 2.13333333333332*G0_0_1_5_0_0 - 1.93015873015872*G0_0_1_5_0_1 + 5.0285714285714*G0_0_1_6_0_0 + 3.86031746031744*G0_0_1_6_0_1 - 0.203174603174602*G0_0_1_7_0_0 - 0.406349206349205*G0_0_1_7_0_1 - 0.203174603174601*G0_0_1_8_0_0 - 0.253968253968254*G0_0_1_8_0_1 + 1.52380952380951*G0_0_1_9_0_0 + 2.74285714285713*G0_0_1_9_0_1 + 0.491005291005289*G0_0_1_10_1_0 + 0.491005291005289*G0_0_1_10_1_1 - 0.0846560846560839*G0_0_1_11_1_0 - 2.42116402116401*G0_0_1_12_1_1 + 0.609523809523806*G0_0_1_13_1_0 + 0.253968253968253*G0_0_1_13_1_1 - 5.0285714285714*G0_0_1_14_1_0 - 2.33650793650793*G0_0_1_14_1_1 - 2.13333333333332*G0_0_1_15_1_0 - 1.93015873015872*G0_0_1_15_1_1 + 5.0285714285714*G0_0_1_16_1_0 + 3.86031746031744*G0_0_1_16_1_1 - 0.203174603174602*G0_0_1_17_1_0 - 0.406349206349205*G0_0_1_17_1_1 - 0.203174603174601*G0_0_1_18_1_0 - 0.253968253968254*G0_0_1_18_1_1 + 1.52380952380951*G0_0_1_19_1_0 + 2.74285714285713*G0_0_1_19_1_1 + 0.897354497354494*G0_1_0_0_0_0 + 0.897354497354494*G0_1_0_0_0_1 - 0.49100529100529*G0_1_0_1_0_0 - 4.35132275132273*G0_1_0_2_0_1 + 2.53968253968252*G0_1_0_3_0_0 + 0.203174603174599*G0_1_0_3_0_1 - 7.66984126984123*G0_1_0_4_0_0 - 1.47301587301587*G0_1_0_4_0_1 - 4.06349206349204*G0_1_0_5_0_0 - 3.91111111111109*G0_1_0_5_0_1 + 7.66984126984123*G0_1_0_6_0_0 + 7.36507936507933*G0_1_0_6_0_1 - 0.203174603174603*G0_1_0_7_0_0 - 0.355555555555555*G0_1_0_7_0_1 - 0.2031746031746*G0_1_0_8_0_0 - 0.203174603174599*G0_1_0_8_0_1 + 1.52380952380952*G0_1_0_9_0_0 + 1.82857142857142*G0_1_0_9_0_1 + 0.897354497354494*G0_1_0_10_1_0 + 0.897354497354494*G0_1_0_10_1_1 - 0.49100529100529*G0_1_0_11_1_0 - 4.35132275132273*G0_1_0_12_1_1 + 2.53968253968252*G0_1_0_13_1_0 + 0.203174603174599*G0_1_0_13_1_1 - 7.66984126984123*G0_1_0_14_1_0 - 1.47301587301587*G0_1_0_14_1_1 - 4.06349206349204*G0_1_0_15_1_0 - 3.91111111111109*G0_1_0_15_1_1 + 7.66984126984123*G0_1_0_16_1_0 + 7.36507936507933*G0_1_0_16_1_1 - 0.203174603174603*G0_1_0_17_1_0 - 0.355555555555555*G0_1_0_17_1_1 - 0.2031746031746*G0_1_0_18_1_0 - 0.203174603174599*G0_1_0_18_1_1 + 1.52380952380952*G0_1_0_19_1_0 + 1.82857142857142*G0_1_0_19_1_1 + 0.399576719576718*G0_1_1_0_0_0 + 0.399576719576718*G0_1_1_0_0_1 + 0.0067724867724881*G0_1_1_1_0_0 - 1.35449735449735*G0_1_1_2_0_1 + 0.457142857142854*G0_1_1_3_0_0 + 0.345396825396826*G0_1_1_3_0_1 - 2.59047619047617*G0_1_1_4_0_0 - 1.11746031746031*G0_1_1_4_0_1 - 1.98095238095237*G0_1_1_5_0_0 - 1.6863492063492*G0_1_1_5_0_1 + 2.59047619047617*G0_1_1_6_0_0 + 2.64126984126983*G0_1_1_6_0_1 - 0.538412698412696*G0_1_1_7_0_0 - 0.833015873015867*G0_1_1_7_0_1 + 0.13206349206349*G0_1_1_8_0_0 - 0.345396825396826*G0_1_1_8_0_1 + 1.52380952380952*G0_1_1_9_0_0 + 1.95047619047618*G0_1_1_9_0_1 + 0.399576719576718*G0_1_1_10_1_0 + 0.399576719576718*G0_1_1_10_1_1 + 0.0067724867724881*G0_1_1_11_1_0 - 1.35449735449735*G0_1_1_12_1_1 + 0.457142857142854*G0_1_1_13_1_0 + 0.345396825396826*G0_1_1_13_1_1 - 2.59047619047617*G0_1_1_14_1_0 - 1.11746031746031*G0_1_1_14_1_1 - 1.98095238095237*G0_1_1_15_1_0 - 1.6863492063492*G0_1_1_15_1_1 + 2.59047619047617*G0_1_1_16_1_0 + 2.64126984126983*G0_1_1_16_1_1 - 0.538412698412696*G0_1_1_17_1_0 - 0.833015873015867*G0_1_1_17_1_1 + 0.13206349206349*G0_1_1_18_1_0 - 0.345396825396826*G0_1_1_18_1_1 + 1.52380952380952*G0_1_1_19_1_0 + 1.95047619047618*G0_1_1_19_1_1; + A[270] = A[530] + 2.02962962962962*G0_0_0_0_0_0 + 2.02962962962962*G0_0_0_0_0_1 - 0.480423280423278*G0_0_0_1_0_0 - 0.283597883597882*G0_0_0_2_0_1 - 0.158730158730157*G0_0_0_3_0_0 - 0.257142857142857*G0_0_0_3_0_1 + 0.0507936507936524*G0_0_0_4_0_0 - 0.0476190476190454*G0_0_0_4_0_1 + 0.577777777777777*G0_0_0_5_0_0 - 2.98730158730158*G0_0_0_5_0_1 - 0.0507936507936524*G0_0_0_6_0_0 + 1.24126984126984*G0_0_0_6_0_1 - 3.26984126984126*G0_0_0_7_0_0 + 0.295238095238095*G0_0_0_7_0_1 + 1.72063492063491*G0_0_0_8_0_0 + 0.257142857142857*G0_0_0_8_0_1 - 0.41904761904762*G0_0_0_9_0_0 - 0.247619047619051*G0_0_0_9_0_1 + 2.02962962962962*G0_0_0_10_1_0 + 2.02962962962962*G0_0_0_10_1_1 - 0.480423280423278*G0_0_0_11_1_0 - 0.283597883597882*G0_0_0_12_1_1 - 0.158730158730157*G0_0_0_13_1_0 - 0.257142857142857*G0_0_0_13_1_1 + 0.0507936507936524*G0_0_0_14_1_0 - 0.0476190476190454*G0_0_0_14_1_1 + 0.577777777777777*G0_0_0_15_1_0 - 2.98730158730158*G0_0_0_15_1_1 - 0.0507936507936524*G0_0_0_16_1_0 + 1.24126984126984*G0_0_0_16_1_1 - 3.26984126984126*G0_0_0_17_1_0 + 0.295238095238095*G0_0_0_17_1_1 + 1.72063492063491*G0_0_0_18_1_0 + 0.257142857142857*G0_0_0_18_1_1 - 0.41904761904762*G0_0_0_19_1_0 - 0.247619047619051*G0_0_0_19_1_1 + 2.02962962962962*G0_0_1_0_0_0 + 2.02962962962962*G0_0_1_0_0_1 - 0.480423280423278*G0_0_1_1_0_0 - 0.283597883597882*G0_0_1_2_0_1 - 0.158730158730156*G0_0_1_3_0_0 - 0.257142857142856*G0_0_1_3_0_1 + 0.0507936507936518*G0_0_1_4_0_0 - 0.0476190476190456*G0_0_1_4_0_1 + 0.577777777777777*G0_0_1_5_0_0 - 2.98730158730157*G0_0_1_5_0_1 - 0.0507936507936517*G0_0_1_6_0_0 + 1.24126984126984*G0_0_1_6_0_1 - 3.26984126984126*G0_0_1_7_0_0 + 0.295238095238095*G0_0_1_7_0_1 + 1.72063492063491*G0_0_1_8_0_0 + 0.257142857142856*G0_0_1_8_0_1 - 0.41904761904762*G0_0_1_9_0_0 - 0.247619047619051*G0_0_1_9_0_1 + 2.02962962962962*G0_0_1_10_1_0 + 2.02962962962962*G0_0_1_10_1_1 - 0.480423280423278*G0_0_1_11_1_0 - 0.283597883597882*G0_0_1_12_1_1 - 0.158730158730156*G0_0_1_13_1_0 - 0.257142857142856*G0_0_1_13_1_1 + 0.0507936507936518*G0_0_1_14_1_0 - 0.0476190476190456*G0_0_1_14_1_1 + 0.577777777777777*G0_0_1_15_1_0 - 2.98730158730157*G0_0_1_15_1_1 - 0.0507936507936517*G0_0_1_16_1_0 + 1.24126984126984*G0_0_1_16_1_1 - 3.26984126984126*G0_0_1_17_1_0 + 0.295238095238095*G0_0_1_17_1_1 + 1.72063492063491*G0_0_1_18_1_0 + 0.257142857142856*G0_0_1_18_1_1 - 0.41904761904762*G0_0_1_19_1_0 - 0.247619047619051*G0_0_1_19_1_1 - 0.351322751322748*G0_1_0_0_0_0 - 0.351322751322749*G0_1_0_0_0_1 - 0.480423280423279*G0_1_0_1_0_0 - 2.66455026455025*G0_1_0_2_0_1 + 1.71746031746031*G0_1_0_3_0_0 - 0.257142857142858*G0_1_0_3_0_1 - 5.21587301587299*G0_1_0_4_0_0 - 1.05714285714285*G0_1_0_4_0_1 - 2.3079365079365*G0_1_0_5_0_0 - 0.606349206349204*G0_1_0_5_0_1 + 5.21587301587299*G0_1_0_6_0_0 + 3.62222222222221*G0_1_0_6_0_1 + 0.987301587301581*G0_1_0_7_0_0 - 0.714285714285712*G0_1_0_7_0_1 - 0.155555555555552*G0_1_0_8_0_0 + 0.257142857142857*G0_1_0_8_0_1 + 0.590476190476188*G0_1_0_9_0_0 + 1.77142857142856*G0_1_0_9_0_1 - 0.351322751322748*G0_1_0_10_1_0 - 0.351322751322749*G0_1_0_10_1_1 - 0.480423280423279*G0_1_0_11_1_0 - 2.66455026455025*G0_1_0_12_1_1 + 1.71746031746031*G0_1_0_13_1_0 - 0.257142857142858*G0_1_0_13_1_1 - 5.21587301587299*G0_1_0_14_1_0 - 1.05714285714285*G0_1_0_14_1_1 - 2.3079365079365*G0_1_0_15_1_0 - 0.606349206349204*G0_1_0_15_1_1 + 5.21587301587299*G0_1_0_16_1_0 + 3.62222222222221*G0_1_0_16_1_1 + 0.987301587301581*G0_1_0_17_1_0 - 0.714285714285712*G0_1_0_17_1_1 - 0.155555555555552*G0_1_0_18_1_0 + 0.257142857142857*G0_1_0_18_1_1 + 0.590476190476188*G0_1_0_19_1_0 + 1.77142857142856*G0_1_0_19_1_1 - 0.634920634920631*G0_1_1_0_0_0 - 0.634920634920631*G0_1_1_0_0_1 - 0.634920634920631*G0_1_1_2_0_1 + 0.253968253968253*G0_1_1_3_0_0 - 1.65079365079364*G0_1_1_4_0_0 - 0.761904761904759*G0_1_1_4_0_1 - 1.01587301587301*G0_1_1_5_0_0 + 0.634920634920632*G0_1_1_5_0_1 + 1.65079365079364*G0_1_1_6_0_0 + 0.634920634920631*G0_1_1_6_0_1 + 0.888888888888884*G0_1_1_7_0_0 - 0.761904761904757*G0_1_1_7_0_1 - 0.253968253968253*G0_1_1_8_0_0 + 0.761904761904757*G0_1_1_9_0_0 + 1.52380952380952*G0_1_1_9_0_1 - 0.634920634920631*G0_1_1_10_1_0 - 0.634920634920631*G0_1_1_10_1_1 - 0.634920634920631*G0_1_1_12_1_1 + 0.253968253968253*G0_1_1_13_1_0 - 1.65079365079364*G0_1_1_14_1_0 - 0.761904761904759*G0_1_1_14_1_1 - 1.01587301587301*G0_1_1_15_1_0 + 0.634920634920632*G0_1_1_15_1_1 + 1.65079365079364*G0_1_1_16_1_0 + 0.634920634920631*G0_1_1_16_1_1 + 0.888888888888884*G0_1_1_17_1_0 - 0.761904761904757*G0_1_1_17_1_1 - 0.253968253968253*G0_1_1_18_1_0 + 0.761904761904757*G0_1_1_19_1_0 + 1.52380952380952*G0_1_1_19_1_1; + A[307] = A[679] + 0.095238095238097*G0_0_0_0_0_0 + 0.0952380952380971*G0_0_0_0_0_1 - 0.0647619047619072*G0_0_0_1_0_0 + 0.617142857142843*G0_0_0_2_0_1 - 1.08571428571427*G0_0_0_3_0_0 - 0.169523809523808*G0_0_0_3_0_1 + 0.217142857142837*G0_0_0_4_0_0 - 1.38095238095237*G0_0_0_4_0_1 + 0.834285714285707*G0_0_0_5_0_0 + 0.7295238095238*G0_0_0_5_0_1 - 0.217142857142837*G0_0_0_6_0_0 - 1.44190476190474*G0_0_0_6_0_1 - 0.929523809523808*G0_0_0_7_0_0 - 0.824761904761901*G0_0_0_7_0_1 + 0.899047619047618*G0_0_0_8_0_0 + 0.169523809523808*G0_0_0_8_0_1 + 0.251428571428563*G0_0_0_9_0_0 + 2.20571428571428*G0_0_0_9_0_1 + 0.095238095238097*G0_0_0_10_1_0 + 0.0952380952380971*G0_0_0_10_1_1 - 0.0647619047619072*G0_0_0_11_1_0 + 0.617142857142843*G0_0_0_12_1_1 - 1.08571428571427*G0_0_0_13_1_0 - 0.169523809523808*G0_0_0_13_1_1 + 0.217142857142837*G0_0_0_14_1_0 - 1.38095238095237*G0_0_0_14_1_1 + 0.834285714285707*G0_0_0_15_1_0 + 0.7295238095238*G0_0_0_15_1_1 - 0.217142857142837*G0_0_0_16_1_0 - 1.44190476190474*G0_0_0_16_1_1 - 0.929523809523808*G0_0_0_17_1_0 - 0.824761904761901*G0_0_0_17_1_1 + 0.899047619047618*G0_0_0_18_1_0 + 0.169523809523808*G0_0_0_18_1_1 + 0.251428571428563*G0_0_0_19_1_0 + 2.20571428571428*G0_0_0_19_1_1 - 0.297142857142857*G0_0_1_0_0_0 - 0.297142857142857*G0_0_1_0_0_1 - 0.0647619047619104*G0_0_1_1_0_0 + 0.224761904761897*G0_0_1_2_0_1 - 0.0819047619047601*G0_0_1_3_0_0 - 0.169523809523817*G0_0_1_3_0_1 + 0.0438095238095107*G0_0_1_4_0_0 - 0.158095238095239*G0_0_1_4_0_1 + 1.05333333333332*G0_0_1_5_0_0 + 1.12190476190476*G0_0_1_5_0_1 - 0.0438095238095107*G0_0_1_6_0_0 - 1.0495238095238*G0_0_1_6_0_1 + 0.466666666666664*G0_0_1_7_0_0 + 0.398095238095229*G0_0_1_7_0_1 - 0.104761904761896*G0_0_1_8_0_0 + 0.169523809523817*G0_0_1_8_0_1 - 0.971428571428563*G0_0_1_9_0_0 - 0.239999999999989*G0_0_1_9_0_1 - 0.297142857142857*G0_0_1_10_1_0 - 0.297142857142857*G0_0_1_10_1_1 - 0.0647619047619104*G0_0_1_11_1_0 + 0.224761904761897*G0_0_1_12_1_1 - 0.0819047619047601*G0_0_1_13_1_0 - 0.169523809523817*G0_0_1_13_1_1 + 0.0438095238095107*G0_0_1_14_1_0 - 0.158095238095239*G0_0_1_14_1_1 + 1.05333333333332*G0_0_1_15_1_0 + 1.12190476190476*G0_0_1_15_1_1 - 0.0438095238095107*G0_0_1_16_1_0 - 1.0495238095238*G0_0_1_16_1_1 + 0.466666666666664*G0_0_1_17_1_0 + 0.398095238095229*G0_0_1_17_1_1 - 0.104761904761896*G0_0_1_18_1_0 + 0.169523809523817*G0_0_1_18_1_1 - 0.971428571428563*G0_0_1_19_1_0 - 0.239999999999989*G0_0_1_19_1_1 - 0.194285714285716*G0_1_0_0_0_0 - 0.194285714285716*G0_1_0_0_0_1 - 0.0647619047619076*G0_1_0_1_0_0 + 0.327619047619041*G0_1_0_2_0_1 - 0.430476190476177*G0_1_0_3_0_0 - 0.169523809523809*G0_1_0_3_0_1 + 0.00380952380951183*G0_1_0_4_0_0 - 0.649523809523803*G0_1_0_4_0_1 + 0.910476190476188*G0_1_0_5_0_0 + 1.01904761904762*G0_1_0_5_0_1 - 0.00380952380951208*G0_1_0_6_0_0 - 1.15238095238094*G0_1_0_6_0_1 + 0.0152380952380965*G0_1_0_7_0_0 - 0.0933333333333354*G0_1_0_7_0_1 + 0.243809523809527*G0_1_0_8_0_0 + 0.169523809523809*G0_1_0_8_0_1 - 0.48000000000001*G0_1_0_9_0_0 + 0.74285714285714*G0_1_0_9_0_1 - 0.194285714285716*G0_1_0_10_1_0 - 0.194285714285716*G0_1_0_10_1_1 - 0.0647619047619076*G0_1_0_11_1_0 + 0.327619047619041*G0_1_0_12_1_1 - 0.430476190476177*G0_1_0_13_1_0 - 0.169523809523809*G0_1_0_13_1_1 + 0.00380952380951183*G0_1_0_14_1_0 - 0.649523809523803*G0_1_0_14_1_1 + 0.910476190476188*G0_1_0_15_1_0 + 1.01904761904762*G0_1_0_15_1_1 - 0.00380952380951208*G0_1_0_16_1_0 - 1.15238095238094*G0_1_0_16_1_1 + 0.0152380952380965*G0_1_0_17_1_0 - 0.0933333333333354*G0_1_0_17_1_1 + 0.243809523809527*G0_1_0_18_1_0 + 0.169523809523809*G0_1_0_18_1_1 - 0.48000000000001*G0_1_0_19_1_0 + 0.74285714285714*G0_1_0_19_1_1 + 0.0304761904761846*G0_1_1_0_0_0 + 0.0304761904761846*G0_1_1_0_0_1 + 0.0304761904761861*G0_1_1_2_0_1 - 0.156190476190473*G0_1_1_3_0_0 - 0.0647619047619135*G0_1_1_4_0_0 - 0.251428571428569*G0_1_1_4_0_1 - 0.0952380952381012*G0_1_1_5_0_0 - 0.0304761904761823*G0_1_1_5_0_1 + 0.0647619047619136*G0_1_1_6_0_0 - 0.0304761904761883*G0_1_1_6_0_1 - 0.18666666666666*G0_1_1_7_0_0 - 0.251428571428579*G0_1_1_7_0_1 + 0.156190476190479*G0_1_1_8_0_0 + 0.251428571428574*G0_1_1_9_0_0 + 0.502857142857147*G0_1_1_9_0_1 + 0.0304761904761846*G0_1_1_10_1_0 + 0.0304761904761846*G0_1_1_10_1_1 + 0.0304761904761861*G0_1_1_12_1_1 - 0.156190476190473*G0_1_1_13_1_0 - 0.0647619047619135*G0_1_1_14_1_0 - 0.251428571428569*G0_1_1_14_1_1 - 0.0952380952381012*G0_1_1_15_1_0 - 0.0304761904761823*G0_1_1_15_1_1 + 0.0647619047619136*G0_1_1_16_1_0 - 0.0304761904761883*G0_1_1_16_1_1 - 0.18666666666666*G0_1_1_17_1_0 - 0.251428571428579*G0_1_1_17_1_1 + 0.156190476190479*G0_1_1_18_1_0 + 0.251428571428574*G0_1_1_19_1_0 + 0.502857142857147*G0_1_1_19_1_1; + A[352] = 0.0; + A[17] = 0.0; + A[734] = 0.0; + A[421] = -0.0880423280423279*G0_0_0_0_0_0 - 0.0880423280423279*G0_0_0_0_0_1 + 0.169312169312169*G0_0_0_1_0_0 - 0.25227513227513*G0_0_0_2_0_1 + 0.632380952380949*G0_0_0_3_0_0 + 0.6031746031746*G0_0_0_3_0_1 - 0.700952380952376*G0_0_0_4_0_0 - 0.250158730158728*G0_0_0_4_0_1 + 0.297142857142856*G0_0_0_5_0_0 + 0.273015873015872*G0_0_0_5_0_1 + 0.700952380952376*G0_0_0_6_0_0 + 0.0673015873015861*G0_0_0_6_0_1 + 0.233650793650793*G0_0_0_7_0_0 + 0.257777777777776*G0_0_0_7_0_1 - 0.314920634920633*G0_0_0_8_0_0 - 0.6031746031746*G0_0_0_8_0_1 - 0.929523809523805*G0_0_0_9_0_0 - 0.00761904761904806*G0_0_0_9_0_1 - 0.0880423280423279*G0_0_0_10_1_0 - 0.0880423280423279*G0_0_0_10_1_1 + 0.169312169312169*G0_0_0_11_1_0 - 0.25227513227513*G0_0_0_12_1_1 + 0.632380952380949*G0_0_0_13_1_0 + 0.6031746031746*G0_0_0_13_1_1 - 0.700952380952376*G0_0_0_14_1_0 - 0.250158730158728*G0_0_0_14_1_1 + 0.297142857142856*G0_0_0_15_1_0 + 0.273015873015872*G0_0_0_15_1_1 + 0.700952380952376*G0_0_0_16_1_0 + 0.0673015873015861*G0_0_0_16_1_1 + 0.233650793650793*G0_0_0_17_1_0 + 0.257777777777776*G0_0_0_17_1_1 - 0.314920634920633*G0_0_0_18_1_0 - 0.6031746031746*G0_0_0_18_1_1 - 0.929523809523805*G0_0_0_19_1_0 - 0.00761904761904806*G0_0_0_19_1_1 + 0.0101587301587297*G0_1_0_0_0_0 + 0.0101587301587298*G0_1_0_0_0_1 - 0.111746031746031*G0_1_0_2_0_1 + 0.0698412698412694*G0_1_0_3_0_0 - 0.143492063492062*G0_1_0_4_0_0 + 0.0380952380952393*G0_1_0_4_0_1 - 0.153650793650792*G0_1_0_5_0_0 - 0.13206349206349*G0_1_0_5_0_1 + 0.143492063492062*G0_1_0_6_0_0 + 0.233650793650792*G0_1_0_6_0_1 + 0.0596825396825394*G0_1_0_7_0_0 + 0.0380952380952373*G0_1_0_7_0_1 - 0.0698412698412681*G0_1_0_8_0_0 + 0.083809523809523*G0_1_0_9_0_0 - 0.0761904761904766*G0_1_0_9_0_1 + 0.0101587301587297*G0_1_0_10_1_0 + 0.0101587301587298*G0_1_0_10_1_1 - 0.111746031746031*G0_1_0_12_1_1 + 0.0698412698412694*G0_1_0_13_1_0 - 0.143492063492062*G0_1_0_14_1_0 + 0.0380952380952393*G0_1_0_14_1_1 - 0.153650793650792*G0_1_0_15_1_0 - 0.13206349206349*G0_1_0_15_1_1 + 0.143492063492062*G0_1_0_16_1_0 + 0.233650793650792*G0_1_0_16_1_1 + 0.0596825396825394*G0_1_0_17_1_0 + 0.0380952380952373*G0_1_0_17_1_1 - 0.0698412698412681*G0_1_0_18_1_0 + 0.083809523809523*G0_1_0_19_1_0 - 0.0761904761904766*G0_1_0_19_1_1; + A[377] = 0.0; + A[58] = 0.0; + A[454] = 0.0; + A[410] = 0.0; + A[87] = 0.0; + A[792] = 0.0; + A[887] = 0.101587301587302*G0_0_1_0_0_0 + 0.101587301587302*G0_0_1_0_0_1 + 0.1015873015873*G0_0_1_1_0_0 - 0.266666666666662*G0_0_1_3_0_0 + 0.0698412698412699*G0_0_1_3_0_1 - 0.234920634920636*G0_0_1_4_0_1 - 0.266666666666668*G0_0_1_5_0_0 - 0.336507936507937*G0_0_1_5_0_1 + 0.23492063492064*G0_0_1_6_0_1 - 0.101587301587301*G0_0_1_7_0_0 - 0.0317460317460321*G0_0_1_7_0_1 - 0.101587301587301*G0_0_1_8_0_0 - 0.06984126984127*G0_0_1_8_0_1 + 0.53333333333333*G0_0_1_9_0_0 + 0.266666666666669*G0_0_1_9_0_1 + 0.101587301587302*G0_0_1_10_1_0 + 0.101587301587302*G0_0_1_10_1_1 + 0.1015873015873*G0_0_1_11_1_0 - 0.266666666666662*G0_0_1_13_1_0 + 0.0698412698412699*G0_0_1_13_1_1 - 0.234920634920636*G0_0_1_14_1_1 - 0.266666666666668*G0_0_1_15_1_0 - 0.336507936507937*G0_0_1_15_1_1 + 0.23492063492064*G0_0_1_16_1_1 - 0.101587301587301*G0_0_1_17_1_0 - 0.0317460317460321*G0_0_1_17_1_1 - 0.101587301587301*G0_0_1_18_1_0 - 0.06984126984127*G0_0_1_18_1_1 + 0.53333333333333*G0_0_1_19_1_0 + 0.266666666666669*G0_0_1_19_1_1 + 0.125291005291005*G0_1_1_0_0_0 + 0.125291005291005*G0_1_1_0_0_1 - 0.0237037037037035*G0_1_1_1_0_0 - 0.973544973544969*G0_1_1_2_0_1 + 0.755555555555551*G0_1_1_3_0_0 + 0.44190476190476*G0_1_1_3_0_1 - 2.06349206349206*G0_1_1_4_0_0 - 0.799999999999998*G0_1_1_4_0_1 - 1.02222222222222*G0_1_1_5_0_0 - 0.650158730158727*G0_1_1_5_0_1 + 2.06349206349206*G0_1_1_6_0_0 + 1.49841269841269*G0_1_1_6_0_1 - 0.306031746031745*G0_1_1_7_0_0 - 0.678095238095235*G0_1_1_7_0_1 + 0.204444444444444*G0_1_1_8_0_0 - 0.44190476190476*G0_1_1_8_0_1 + 0.266666666666666*G0_1_1_9_0_0 + 1.47809523809523*G0_1_1_9_0_1 + 0.125291005291005*G0_1_1_10_1_0 + 0.125291005291005*G0_1_1_10_1_1 - 0.0237037037037035*G0_1_1_11_1_0 - 0.973544973544969*G0_1_1_12_1_1 + 0.755555555555551*G0_1_1_13_1_0 + 0.44190476190476*G0_1_1_13_1_1 - 2.06349206349206*G0_1_1_14_1_0 - 0.799999999999998*G0_1_1_14_1_1 - 1.02222222222222*G0_1_1_15_1_0 - 0.650158730158727*G0_1_1_15_1_1 + 2.06349206349206*G0_1_1_16_1_0 + 1.49841269841269*G0_1_1_16_1_1 - 0.306031746031745*G0_1_1_17_1_0 - 0.678095238095235*G0_1_1_17_1_1 + 0.204444444444444*G0_1_1_18_1_0 - 0.44190476190476*G0_1_1_18_1_1 + 0.266666666666666*G0_1_1_19_1_0 + 1.47809523809523*G0_1_1_19_1_1; + A[811] = 0.0; + A[850] = 0.0; + A[174] = 0.0; + A[881] = 0.0; + A[480] = 0.0; + A[203] = 0.0; + A[583] = 0.0; + A[523] = 0.0; + A[232] = 0.0; + A[614] = 0.0; + A[550] = 0.0; + A[252] = 0.264126984126983*G0_0_0_0_0_0 + 0.264126984126983*G0_0_0_0_0_1 + 0.142222222222221*G0_0_0_1_0_0 - 0.609523809523804*G0_0_0_3_0_0 + 0.0406349206349207*G0_0_0_3_0_1 - 0.507936507936509*G0_0_0_4_0_1 - 0.60952380952381*G0_0_0_5_0_0 - 0.772063492063491*G0_0_0_5_0_1 + 0.507936507936512*G0_0_0_6_0_1 - 0.386031746031743*G0_0_0_7_0_0 - 0.223492063492062*G0_0_0_7_0_1 - 0.0203174603174608*G0_0_0_8_0_0 - 0.0406349206349207*G0_0_0_8_0_1 + 1.21904761904761*G0_0_0_9_0_0 + 0.731428571428571*G0_0_0_9_0_1 + 0.264126984126983*G0_0_0_10_1_0 + 0.264126984126983*G0_0_0_10_1_1 + 0.142222222222221*G0_0_0_11_1_0 - 0.609523809523804*G0_0_0_13_1_0 + 0.0406349206349207*G0_0_0_13_1_1 - 0.507936507936509*G0_0_0_14_1_1 - 0.60952380952381*G0_0_0_15_1_0 - 0.772063492063491*G0_0_0_15_1_1 + 0.507936507936512*G0_0_0_16_1_1 - 0.386031746031743*G0_0_0_17_1_0 - 0.223492063492062*G0_0_0_17_1_1 - 0.0203174603174608*G0_0_0_18_1_0 - 0.0406349206349207*G0_0_0_18_1_1 + 1.21904761904761*G0_0_0_19_1_0 + 0.731428571428571*G0_0_0_19_1_1 + 0.358941798941798*G0_0_1_0_0_0 + 0.358941798941798*G0_0_1_0_0_1 + 0.0880423280423269*G0_0_1_1_0_0 - 0.744973544973544*G0_0_1_2_0_1 - 0.142222222222222*G0_0_1_3_0_0 + 0.121904761904761*G0_0_1_3_0_1 - 1.42222222222222*G0_0_1_4_0_0 - 0.853333333333333*G0_0_1_4_0_1 - 0.954920634920633*G0_0_1_5_0_0 - 1.17841269841269*G0_0_1_5_0_1 + 1.42222222222222*G0_0_1_6_0_0 + 1.56444444444444*G0_0_1_6_0_1 - 0.223492063492064*G0_0_1_7_0_0 - 0.22349206349206*G0_0_1_8_0_0 - 0.121904761904761*G0_0_1_8_0_1 + 1.09714285714285*G0_0_1_9_0_0 + 0.853333333333336*G0_0_1_9_0_1 + 0.358941798941798*G0_0_1_10_1_0 + 0.358941798941798*G0_0_1_10_1_1 + 0.0880423280423269*G0_0_1_11_1_0 - 0.744973544973544*G0_0_1_12_1_1 - 0.142222222222222*G0_0_1_13_1_0 + 0.121904761904761*G0_0_1_13_1_1 - 1.42222222222222*G0_0_1_14_1_0 - 0.853333333333333*G0_0_1_14_1_1 - 0.954920634920633*G0_0_1_15_1_0 - 1.17841269841269*G0_0_1_15_1_1 + 1.42222222222222*G0_0_1_16_1_0 + 1.56444444444444*G0_0_1_16_1_1 - 0.223492063492064*G0_0_1_17_1_0 - 0.22349206349206*G0_0_1_18_1_0 - 0.121904761904761*G0_0_1_18_1_1 + 1.09714285714285*G0_0_1_19_1_0 + 0.853333333333336*G0_0_1_19_1_1 + 0.480846560846561*G0_1_0_0_0_0 + 0.480846560846561*G0_1_0_0_0_1 - 0.0135449735449735*G0_1_0_1_0_0 - 0.33862433862434*G0_1_0_2_0_1 - 0.0609523809523814*G0_1_0_3_0_0 + 0.223492063492062*G0_1_0_3_0_1 - 0.914285714285716*G0_1_0_4_0_0 - 0.873650793650793*G0_1_0_4_0_1 - 0.0609523809523856*G0_1_0_5_0_0 - 0.711111111111115*G0_1_0_5_0_1 + 0.914285714285716*G0_1_0_6_0_0 + 0.568888888888894*G0_1_0_6_0_1 - 0.873650793650791*G0_1_0_7_0_0 - 0.223492063492063*G0_1_0_7_0_1 + 0.406349206349205*G0_1_0_8_0_0 - 0.223492063492063*G0_1_0_8_0_1 + 0.121904761904767*G0_1_0_9_0_0 + 1.09714285714286*G0_1_0_9_0_1 + 0.480846560846561*G0_1_0_10_1_0 + 0.480846560846561*G0_1_0_10_1_1 - 0.0135449735449735*G0_1_0_11_1_0 - 0.33862433862434*G0_1_0_12_1_1 - 0.0609523809523814*G0_1_0_13_1_0 + 0.223492063492062*G0_1_0_13_1_1 - 0.914285714285716*G0_1_0_14_1_0 - 0.873650793650793*G0_1_0_14_1_1 - 0.0609523809523856*G0_1_0_15_1_0 - 0.711111111111115*G0_1_0_15_1_1 + 0.914285714285716*G0_1_0_16_1_0 + 0.568888888888894*G0_1_0_16_1_1 - 0.873650793650791*G0_1_0_17_1_0 - 0.223492063492063*G0_1_0_17_1_1 + 0.406349206349205*G0_1_0_18_1_0 - 0.223492063492063*G0_1_0_18_1_1 + 0.121904761904767*G0_1_0_19_1_0 + 1.09714285714286*G0_1_0_19_1_1 - 0.846560846560841*G0_1_1_0_0_0 - 0.846560846560842*G0_1_1_0_0_1 - 0.16931216931217*G0_1_1_1_0_0 - 0.331851851851853*G0_1_1_2_0_1 + 0.467301587301585*G0_1_1_3_0_0 + 0.304761904761903*G0_1_1_3_0_1 - 2.09269841269841*G0_1_1_4_0_0 - 1.76761904761904*G0_1_1_4_0_1 - 0.467301587301587*G0_1_1_5_0_0 + 1.86920634920634*G0_1_1_5_0_1 + 2.09269841269841*G0_1_1_6_0_0 - 0.690793650793643*G0_1_1_6_0_1 - 0.0406349206349218*G0_1_1_7_0_0 - 2.37714285714285*G0_1_1_7_0_1 + 1.05650793650793*G0_1_1_8_0_0 - 0.304761904761903*G0_1_1_8_0_1 + 4.14476190476189*G0_1_1_9_0_1 - 0.846560846560841*G0_1_1_10_1_0 - 0.846560846560842*G0_1_1_10_1_1 - 0.16931216931217*G0_1_1_11_1_0 - 0.331851851851853*G0_1_1_12_1_1 + 0.467301587301585*G0_1_1_13_1_0 + 0.304761904761903*G0_1_1_13_1_1 - 2.09269841269841*G0_1_1_14_1_0 - 1.76761904761904*G0_1_1_14_1_1 - 0.467301587301587*G0_1_1_15_1_0 + 1.86920634920634*G0_1_1_15_1_1 + 2.09269841269841*G0_1_1_16_1_0 - 0.690793650793643*G0_1_1_16_1_1 - 0.0406349206349218*G0_1_1_17_1_0 - 2.37714285714285*G0_1_1_17_1_1 + 1.05650793650793*G0_1_1_18_1_0 - 0.304761904761903*G0_1_1_18_1_1 + 4.14476190476189*G0_1_1_19_1_1; + A[672] = 0.0; + A[699] = 0.0; + A[258] = 0.0; + A[345] = 0.0; + A[289] = 0.0; + A[368] = A[252] + 0.121904761904763*G0_0_1_0_0_0 + 0.121904761904763*G0_0_1_0_0_1 - 0.1015873015873*G0_0_1_1_0_0 + 0.406349206349203*G0_0_1_2_0_1 + 0.0812698412698405*G0_0_1_3_0_0 + 0.101587301587302*G0_0_1_3_0_1 + 0.507936507936505*G0_0_1_4_0_0 - 0.0203174603174596*G0_0_1_4_0_1 + 0.893968253968247*G0_0_1_5_0_0 + 0.467301587301579*G0_0_1_5_0_1 - 0.507936507936505*G0_0_1_6_0_0 - 0.995555555555545*G0_0_1_6_0_1 - 0.650158730158728*G0_0_1_7_0_0 - 0.22349206349206*G0_0_1_7_0_1 + 0.629841269841265*G0_0_1_8_0_0 - 0.101587301587302*G0_0_1_8_0_1 - 0.975238095238087*G0_0_1_9_0_0 + 0.243809523809521*G0_0_1_9_0_1 + 0.121904761904763*G0_0_1_10_1_0 + 0.121904761904763*G0_0_1_10_1_1 - 0.1015873015873*G0_0_1_11_1_0 + 0.406349206349203*G0_0_1_12_1_1 + 0.0812698412698405*G0_0_1_13_1_0 + 0.101587301587302*G0_0_1_13_1_1 + 0.507936507936505*G0_0_1_14_1_0 - 0.0203174603174596*G0_0_1_14_1_1 + 0.893968253968247*G0_0_1_15_1_0 + 0.467301587301579*G0_0_1_15_1_1 - 0.507936507936505*G0_0_1_16_1_0 - 0.995555555555545*G0_0_1_16_1_1 - 0.650158730158728*G0_0_1_17_1_0 - 0.22349206349206*G0_0_1_17_1_1 + 0.629841269841265*G0_0_1_18_1_0 - 0.101587301587302*G0_0_1_18_1_1 - 0.975238095238087*G0_0_1_19_1_0 + 0.243809523809521*G0_0_1_19_1_1 - 0.121904761904763*G0_1_0_0_0_0 - 0.121904761904763*G0_1_0_0_0_1 + 0.1015873015873*G0_1_0_1_0_0 - 0.406349206349203*G0_1_0_2_0_1 - 0.0812698412698404*G0_1_0_3_0_0 - 0.101587301587302*G0_1_0_3_0_1 - 0.507936507936505*G0_1_0_4_0_0 + 0.0203174603174595*G0_1_0_4_0_1 - 0.893968253968247*G0_1_0_5_0_0 - 0.467301587301579*G0_1_0_5_0_1 + 0.507936507936505*G0_1_0_6_0_0 + 0.995555555555545*G0_1_0_6_0_1 + 0.650158730158728*G0_1_0_7_0_0 + 0.22349206349206*G0_1_0_7_0_1 - 0.629841269841265*G0_1_0_8_0_0 + 0.101587301587302*G0_1_0_8_0_1 + 0.975238095238088*G0_1_0_9_0_0 - 0.24380952380952*G0_1_0_9_0_1 - 0.121904761904763*G0_1_0_10_1_0 - 0.121904761904763*G0_1_0_10_1_1 + 0.1015873015873*G0_1_0_11_1_0 - 0.406349206349203*G0_1_0_12_1_1 - 0.0812698412698404*G0_1_0_13_1_0 - 0.101587301587302*G0_1_0_13_1_1 - 0.507936507936505*G0_1_0_14_1_0 + 0.0203174603174595*G0_1_0_14_1_1 - 0.893968253968247*G0_1_0_15_1_0 - 0.467301587301579*G0_1_0_15_1_1 + 0.507936507936505*G0_1_0_16_1_0 + 0.995555555555545*G0_1_0_16_1_1 + 0.650158730158728*G0_1_0_17_1_0 + 0.22349206349206*G0_1_0_17_1_1 - 0.629841269841265*G0_1_0_18_1_0 + 0.101587301587302*G0_1_0_18_1_1 + 0.975238095238088*G0_1_0_19_1_0 - 0.24380952380952*G0_1_0_19_1_1; + A[51] = 0.0; + A[766] = -0.540423280423279*G0_0_0_0_0_0 - 0.540423280423278*G0_0_0_0_0_1 + 1.27883597883597*G0_0_0_1_0_0 + 0.122962962962963*G0_0_0_2_0_1 + 0.433333333333331*G0_0_0_3_0_0 + 2.1579365079365*G0_0_0_3_0_1 - 0.106666666666666*G0_0_0_4_0_0 - 0.675396825396823*G0_0_0_4_0_1 - 0.256190476190475*G0_0_0_5_0_0 + 0.336349206349205*G0_0_0_5_0_1 + 0.106666666666667*G0_0_0_6_0_0 + 0.08111111111111*G0_0_0_6_0_1 + 1.53936507936507*G0_0_0_7_0_0 + 0.946825396825392*G0_0_0_7_0_1 - 2.27777777777777*G0_0_0_8_0_0 - 2.1579365079365*G0_0_0_8_0_1 - 0.177142857142856*G0_0_0_9_0_0 - 0.271428571428568*G0_0_0_9_0_1 - 0.540423280423279*G0_0_0_10_1_0 - 0.540423280423278*G0_0_0_10_1_1 + 1.27883597883597*G0_0_0_11_1_0 + 0.122962962962963*G0_0_0_12_1_1 + 0.433333333333331*G0_0_0_13_1_0 + 2.1579365079365*G0_0_0_13_1_1 - 0.106666666666666*G0_0_0_14_1_0 - 0.675396825396823*G0_0_0_14_1_1 - 0.256190476190475*G0_0_0_15_1_0 + 0.336349206349205*G0_0_0_15_1_1 + 0.106666666666667*G0_0_0_16_1_0 + 0.08111111111111*G0_0_0_16_1_1 + 1.53936507936507*G0_0_0_17_1_0 + 0.946825396825392*G0_0_0_17_1_1 - 2.27777777777777*G0_0_0_18_1_0 - 2.1579365079365*G0_0_0_18_1_1 - 0.177142857142856*G0_0_0_19_1_0 - 0.271428571428568*G0_0_0_19_1_1 - 0.276190476190475*G0_1_0_0_0_0 - 0.276190476190474*G0_1_0_0_0_1 + 1.47777777777777*G0_1_0_1_0_0 + 0.174603174603173*G0_1_0_2_0_1 + 0.586507936507933*G0_1_0_3_0_0 + 2.70476190476189*G0_1_0_3_0_1 - 0.103968253968254*G0_1_0_4_0_0 - 0.919047619047614*G0_1_0_4_0_1 + 0.0849206349206333*G0_1_0_5_0_0 + 0.0507936507936502*G0_1_0_5_0_1 + 0.103968253968254*G0_1_0_6_0_0 + 0.0507936507936506*G0_1_0_6_0_1 + 1.15158730158729*G0_1_0_7_0_0 + 1.18571428571428*G0_1_0_7_0_1 - 2.35317460317459*G0_1_0_8_0_0 - 2.70476190476189*G0_1_0_8_0_1 - 0.671428571428566*G0_1_0_9_0_0 - 0.266666666666662*G0_1_0_9_0_1 - 0.276190476190475*G0_1_0_10_1_0 - 0.276190476190474*G0_1_0_10_1_1 + 1.47777777777777*G0_1_0_11_1_0 + 0.174603174603173*G0_1_0_12_1_1 + 0.586507936507933*G0_1_0_13_1_0 + 2.70476190476189*G0_1_0_13_1_1 - 0.103968253968254*G0_1_0_14_1_0 - 0.919047619047614*G0_1_0_14_1_1 + 0.0849206349206333*G0_1_0_15_1_0 + 0.0507936507936502*G0_1_0_15_1_1 + 0.103968253968254*G0_1_0_16_1_0 + 0.0507936507936506*G0_1_0_16_1_1 + 1.15158730158729*G0_1_0_17_1_0 + 1.18571428571428*G0_1_0_17_1_1 - 2.35317460317459*G0_1_0_18_1_0 - 2.70476190476189*G0_1_0_18_1_1 - 0.671428571428566*G0_1_0_19_1_0 - 0.266666666666662*G0_1_0_19_1_1; + A[765] = A[766] - 0.738412698412697*G0_0_0_0_0_0 - 0.738412698412697*G0_0_0_0_0_1 - 0.738412698412696*G0_0_0_1_0_0 - 0.177142857142857*G0_0_0_3_0_0 - 1.56539682539682*G0_0_0_3_0_1 + 0.649841269841266*G0_0_0_4_0_1 - 0.177142857142857*G0_0_0_5_0_0 + 1.38825396825396*G0_0_0_5_0_1 - 0.649841269841268*G0_0_0_6_0_1 + 0.738412698412698*G0_0_0_7_0_0 - 0.826984126984124*G0_0_0_7_0_1 + 0.738412698412696*G0_0_0_8_0_0 + 1.56539682539682*G0_0_0_8_0_1 + 0.354285714285714*G0_0_0_9_0_0 + 0.177142857142858*G0_0_0_9_0_1 - 0.738412698412697*G0_0_0_10_1_0 - 0.738412698412697*G0_0_0_10_1_1 - 0.738412698412696*G0_0_0_11_1_0 - 0.177142857142857*G0_0_0_13_1_0 - 1.56539682539682*G0_0_0_13_1_1 + 0.649841269841266*G0_0_0_14_1_1 - 0.177142857142857*G0_0_0_15_1_0 + 1.38825396825396*G0_0_0_15_1_1 - 0.649841269841268*G0_0_0_16_1_1 + 0.738412698412698*G0_0_0_17_1_0 - 0.826984126984124*G0_0_0_17_1_1 + 0.738412698412696*G0_0_0_18_1_0 + 1.56539682539682*G0_0_0_18_1_1 + 0.354285714285714*G0_0_0_19_1_0 + 0.177142857142858*G0_0_0_19_1_1 - 1.27883597883598*G0_0_1_0_0_0 - 1.27883597883598*G0_0_1_0_0_1 + 0.540423280423277*G0_0_1_1_0_0 + 0.122962962962963*G0_0_1_2_0_1 + 0.256190476190473*G0_0_1_3_0_0 + 0.592539682539679*G0_0_1_3_0_1 - 0.106666666666667*G0_0_1_4_0_0 - 0.0255555555555569*G0_0_1_4_0_1 - 0.433333333333333*G0_0_1_5_0_0 + 1.72460317460317*G0_0_1_5_0_1 + 0.106666666666667*G0_0_1_6_0_0 - 0.568730158730158*G0_0_1_6_0_1 + 2.27777777777777*G0_0_1_7_0_0 + 0.119841269841267*G0_0_1_7_0_1 - 1.53936507936507*G0_0_1_8_0_0 - 0.592539682539679*G0_0_1_8_0_1 + 0.177142857142859*G0_0_1_9_0_0 - 0.0942857142857092*G0_0_1_9_0_1 - 1.27883597883598*G0_0_1_10_1_0 - 1.27883597883598*G0_0_1_10_1_1 + 0.540423280423277*G0_0_1_11_1_0 + 0.122962962962963*G0_0_1_12_1_1 + 0.256190476190473*G0_0_1_13_1_0 + 0.592539682539679*G0_0_1_13_1_1 - 0.106666666666667*G0_0_1_14_1_0 - 0.0255555555555569*G0_0_1_14_1_1 - 0.433333333333333*G0_0_1_15_1_0 + 1.72460317460317*G0_0_1_15_1_1 + 0.106666666666667*G0_0_1_16_1_0 - 0.568730158730158*G0_0_1_16_1_1 + 2.27777777777777*G0_0_1_17_1_0 + 0.119841269841267*G0_0_1_17_1_1 - 1.53936507936507*G0_0_1_18_1_0 - 0.592539682539679*G0_0_1_18_1_1 + 0.177142857142859*G0_0_1_19_1_0 - 0.0942857142857092*G0_0_1_19_1_1 + 0.475132275132272*G0_1_0_0_0_0 + 0.475132275132271*G0_1_0_0_0_1 - 1.21354497354497*G0_1_0_1_0_0 - 0.226243386243385*G0_1_0_2_0_1 - 0.245396825396824*G0_1_0_3_0_0 - 2.07809523809523*G0_1_0_3_0_1 + 0.101269841269841*G0_1_0_4_0_0 + 0.946666666666661*G0_1_0_4_0_1 + 0.0682539682539684*G0_1_0_5_0_0 - 0.44444444444444*G0_1_0_5_0_1 - 0.101269841269842*G0_1_0_6_0_0 + 0.195555555555554*G0_1_0_6_0_1 - 1.22698412698412*G0_1_0_7_0_0 - 0.714285714285709*G0_1_0_7_0_1 + 1.96539682539681*G0_1_0_8_0_0 + 2.07809523809523*G0_1_0_8_0_1 + 0.177142857142856*G0_1_0_9_0_0 - 0.232380952380953*G0_1_0_9_0_1 + 0.475132275132272*G0_1_0_10_1_0 + 0.475132275132271*G0_1_0_10_1_1 - 1.21354497354497*G0_1_0_11_1_0 - 0.226243386243385*G0_1_0_12_1_1 - 0.245396825396824*G0_1_0_13_1_0 - 2.07809523809523*G0_1_0_13_1_1 + 0.101269841269841*G0_1_0_14_1_0 + 0.946666666666661*G0_1_0_14_1_1 + 0.0682539682539684*G0_1_0_15_1_0 - 0.44444444444444*G0_1_0_15_1_1 - 0.101269841269842*G0_1_0_16_1_0 + 0.195555555555554*G0_1_0_16_1_1 - 1.22698412698412*G0_1_0_17_1_0 - 0.714285714285709*G0_1_0_17_1_1 + 1.96539682539681*G0_1_0_18_1_0 + 2.07809523809523*G0_1_0_18_1_1 + 0.177142857142856*G0_1_0_19_1_0 - 0.232380952380953*G0_1_0_19_1_1 + 0.198941798941797*G0_1_1_0_0_0 + 0.198941798941797*G0_1_1_0_0_1 + 0.264232804232803*G0_1_1_1_0_0 - 0.0516402116402111*G0_1_1_2_0_1 + 0.341111111111108*G0_1_1_3_0_0 + 0.626666666666662*G0_1_1_3_0_1 - 0.00269841269841259*G0_1_1_4_0_0 + 0.0276190476190472*G0_1_1_4_0_1 + 0.153174603174602*G0_1_1_5_0_0 - 0.39365079365079*G0_1_1_5_0_1 + 0.0026984126984127*G0_1_1_6_0_0 + 0.246349206349204*G0_1_1_6_0_1 - 0.0753968253968237*G0_1_1_7_0_0 + 0.471428571428567*G0_1_1_7_0_1 - 0.387777777777776*G0_1_1_8_0_0 - 0.626666666666662*G0_1_1_8_0_1 - 0.49428571428571*G0_1_1_9_0_0 - 0.499047619047614*G0_1_1_9_0_1 + 0.198941798941797*G0_1_1_10_1_0 + 0.198941798941797*G0_1_1_10_1_1 + 0.264232804232803*G0_1_1_11_1_0 - 0.0516402116402111*G0_1_1_12_1_1 + 0.341111111111108*G0_1_1_13_1_0 + 0.626666666666662*G0_1_1_13_1_1 - 0.00269841269841259*G0_1_1_14_1_0 + 0.0276190476190472*G0_1_1_14_1_1 + 0.153174603174602*G0_1_1_15_1_0 - 0.39365079365079*G0_1_1_15_1_1 + 0.0026984126984127*G0_1_1_16_1_0 + 0.246349206349204*G0_1_1_16_1_1 - 0.0753968253968237*G0_1_1_17_1_0 + 0.471428571428567*G0_1_1_17_1_1 - 0.387777777777776*G0_1_1_18_1_0 - 0.626666666666662*G0_1_1_18_1_1 - 0.49428571428571*G0_1_1_19_1_0 - 0.499047619047614*G0_1_1_19_1_1; + A[463] = 0.0; + A[78] = 0.0; + A[803] = A[716] + 0.020317460317459*G0_0_1_0_0_0 + 0.0203174603174589*G0_0_1_0_0_1 - 0.02031746031746*G0_0_1_1_0_0 - 0.0203174603174595*G0_0_1_2_0_1 - 0.132063492063492*G0_0_1_3_0_0 - 0.0711111111111104*G0_0_1_3_0_1 - 0.0711111111111103*G0_0_1_4_0_0 - 0.132063492063492*G0_0_1_4_0_1 - 0.172698412698412*G0_0_1_5_0_0 - 0.091428571428569*G0_0_1_5_0_1 + 0.0711111111111102*G0_0_1_6_0_0 + 0.0914285714285695*G0_0_1_6_0_1 - 0.0914285714285699*G0_0_1_7_0_0 - 0.172698412698413*G0_0_1_7_0_1 + 0.091428571428571*G0_0_1_8_0_0 + 0.0711111111111106*G0_0_1_8_0_1 + 0.304761904761904*G0_0_1_9_0_0 + 0.304761904761905*G0_0_1_9_0_1 + 0.020317460317459*G0_0_1_10_1_0 + 0.0203174603174589*G0_0_1_10_1_1 - 0.02031746031746*G0_0_1_11_1_0 - 0.0203174603174595*G0_0_1_12_1_1 - 0.132063492063492*G0_0_1_13_1_0 - 0.0711111111111104*G0_0_1_13_1_1 - 0.0711111111111103*G0_0_1_14_1_0 - 0.132063492063492*G0_0_1_14_1_1 - 0.172698412698412*G0_0_1_15_1_0 - 0.091428571428569*G0_0_1_15_1_1 + 0.0711111111111102*G0_0_1_16_1_0 + 0.0914285714285695*G0_0_1_16_1_1 - 0.0914285714285699*G0_0_1_17_1_0 - 0.172698412698413*G0_0_1_17_1_1 + 0.091428571428571*G0_0_1_18_1_0 + 0.0711111111111106*G0_0_1_18_1_1 + 0.304761904761904*G0_0_1_19_1_0 + 0.304761904761905*G0_0_1_19_1_1 - 0.020317460317459*G0_1_0_0_0_0 - 0.0203174603174589*G0_1_0_0_0_1 + 0.02031746031746*G0_1_0_1_0_0 + 0.0203174603174596*G0_1_0_2_0_1 + 0.132063492063492*G0_1_0_3_0_0 + 0.0711111111111105*G0_1_0_3_0_1 + 0.0711111111111103*G0_1_0_4_0_0 + 0.132063492063492*G0_1_0_4_0_1 + 0.172698412698413*G0_1_0_5_0_0 + 0.091428571428569*G0_1_0_5_0_1 - 0.0711111111111103*G0_1_0_6_0_0 - 0.0914285714285696*G0_1_0_6_0_1 + 0.0914285714285698*G0_1_0_7_0_0 + 0.172698412698413*G0_1_0_7_0_1 - 0.0914285714285709*G0_1_0_8_0_0 - 0.0711111111111105*G0_1_0_8_0_1 - 0.304761904761904*G0_1_0_9_0_0 - 0.304761904761905*G0_1_0_9_0_1 - 0.020317460317459*G0_1_0_10_1_0 - 0.0203174603174589*G0_1_0_10_1_1 + 0.02031746031746*G0_1_0_11_1_0 + 0.0203174603174596*G0_1_0_12_1_1 + 0.132063492063492*G0_1_0_13_1_0 + 0.0711111111111105*G0_1_0_13_1_1 + 0.0711111111111103*G0_1_0_14_1_0 + 0.132063492063492*G0_1_0_14_1_1 + 0.172698412698413*G0_1_0_15_1_0 + 0.091428571428569*G0_1_0_15_1_1 - 0.0711111111111103*G0_1_0_16_1_0 - 0.0914285714285696*G0_1_0_16_1_1 + 0.0914285714285698*G0_1_0_17_1_0 + 0.172698412698413*G0_1_0_17_1_1 - 0.0914285714285709*G0_1_0_18_1_0 - 0.0711111111111105*G0_1_0_18_1_1 - 0.304761904761904*G0_1_0_19_1_0 - 0.304761904761905*G0_1_0_19_1_1; + A[101] = A[245] - 0.582433862433862*G0_0_0_0_0_0 - 0.582433862433863*G0_0_0_0_0_1 - 0.372486772486764*G0_0_0_1_0_0 + 6.77925925925922*G0_0_0_2_0_1 - 5.79047619047615*G0_0_0_3_0_0 - 2.99682539682537*G0_0_0_3_0_1 + 13.0438095238095*G0_0_0_4_0_0 + 3.09841269841268*G0_0_0_4_0_1 + 3.83999999999998*G0_0_0_5_0_0 + 3.72825396825395*G0_0_0_5_0_1 - 13.0438095238095*G0_0_0_6_0_0 - 9.92507936507931*G0_0_0_6_0_1 - 1.68634920634919*G0_0_0_7_0_0 - 1.57460317460316*G0_0_0_7_0_1 + 2.64126984126981*G0_0_0_8_0_0 + 2.99682539682537*G0_0_0_8_0_1 + 1.95047619047617*G0_0_0_9_0_0 - 1.52380952380953*G0_0_0_9_0_1 - 0.582433862433862*G0_0_0_10_1_0 - 0.582433862433863*G0_0_0_10_1_1 - 0.372486772486764*G0_0_0_11_1_0 + 6.77925925925922*G0_0_0_12_1_1 - 5.79047619047615*G0_0_0_13_1_0 - 2.99682539682537*G0_0_0_13_1_1 + 13.0438095238095*G0_0_0_14_1_0 + 3.09841269841268*G0_0_0_14_1_1 + 3.83999999999998*G0_0_0_15_1_0 + 3.72825396825395*G0_0_0_15_1_1 - 13.0438095238095*G0_0_0_16_1_0 - 9.92507936507931*G0_0_0_16_1_1 - 1.68634920634919*G0_0_0_17_1_0 - 1.57460317460316*G0_0_0_17_1_1 + 2.64126984126981*G0_0_0_18_1_0 + 2.99682539682537*G0_0_0_18_1_1 + 1.95047619047617*G0_0_0_19_1_0 - 1.52380952380953*G0_0_0_19_1_1 - 2.33650793650792*G0_0_1_1_0_0 + 2.33650793650793*G0_0_1_2_0_1 - 2.94603174603173*G0_0_1_3_0_0 - 5.28253968253964*G0_0_1_3_0_1 + 5.28253968253965*G0_0_1_4_0_0 + 2.94603174603172*G0_0_1_4_0_1 + 1.72698412698412*G0_0_1_5_0_0 + 1.72698412698412*G0_0_1_5_0_1 - 5.28253968253966*G0_0_1_6_0_0 - 4.06349206349204*G0_0_1_6_0_1 - 1.72698412698411*G0_0_1_7_0_0 - 1.72698412698411*G0_0_1_7_0_1 + 4.06349206349203*G0_0_1_8_0_0 + 5.28253968253965*G0_0_1_8_0_1 + 1.21904761904761*G0_0_1_9_0_0 - 1.21904761904761*G0_0_1_9_0_1 - 2.33650793650792*G0_0_1_11_1_0 + 2.33650793650793*G0_0_1_12_1_1 - 2.94603174603173*G0_0_1_13_1_0 - 5.28253968253964*G0_0_1_13_1_1 + 5.28253968253965*G0_0_1_14_1_0 + 2.94603174603172*G0_0_1_14_1_1 + 1.72698412698412*G0_0_1_15_1_0 + 1.72698412698412*G0_0_1_15_1_1 - 5.28253968253966*G0_0_1_16_1_0 - 4.06349206349204*G0_0_1_16_1_1 - 1.72698412698411*G0_0_1_17_1_0 - 1.72698412698411*G0_0_1_17_1_1 + 4.06349206349203*G0_0_1_18_1_0 + 5.28253968253965*G0_0_1_18_1_1 + 1.21904761904761*G0_0_1_19_1_0 - 1.21904761904761*G0_0_1_19_1_1 - 3.86031746031744*G0_1_0_1_0_0 + 3.86031746031744*G0_1_0_2_0_1 - 4.01269841269839*G0_1_0_3_0_0 - 7.87301587301583*G0_1_0_3_0_1 + 7.87301587301583*G0_1_0_4_0_0 + 4.0126984126984*G0_1_0_4_0_1 + 3.70793650793649*G0_1_0_5_0_0 + 3.70793650793649*G0_1_0_5_0_1 - 7.87301587301584*G0_1_0_6_0_0 - 7.56825396825393*G0_1_0_6_0_1 - 3.70793650793649*G0_1_0_7_0_0 - 3.70793650793648*G0_1_0_7_0_1 + 7.56825396825393*G0_1_0_8_0_0 + 7.87301587301583*G0_1_0_8_0_1 + 0.304761904761894*G0_1_0_9_0_0 - 0.304761904761913*G0_1_0_9_0_1 - 3.86031746031744*G0_1_0_11_1_0 + 3.86031746031744*G0_1_0_12_1_1 - 4.01269841269839*G0_1_0_13_1_0 - 7.87301587301583*G0_1_0_13_1_1 + 7.87301587301583*G0_1_0_14_1_0 + 4.0126984126984*G0_1_0_14_1_1 + 3.70793650793649*G0_1_0_15_1_0 + 3.70793650793649*G0_1_0_15_1_1 - 7.87301587301584*G0_1_0_16_1_0 - 7.56825396825393*G0_1_0_16_1_1 - 3.70793650793649*G0_1_0_17_1_0 - 3.70793650793648*G0_1_0_17_1_1 + 7.56825396825393*G0_1_0_18_1_0 + 7.87301587301583*G0_1_0_18_1_1 + 0.304761904761894*G0_1_0_19_1_0 - 0.304761904761913*G0_1_0_19_1_1 + 0.582433862433861*G0_1_1_0_0_0 + 0.582433862433858*G0_1_1_0_0_1 - 6.77925925925922*G0_1_1_1_0_0 + 0.372486772486771*G0_1_1_2_0_1 - 3.09841269841268*G0_1_1_3_0_0 - 13.0438095238095*G0_1_1_3_0_1 + 2.99682539682538*G0_1_1_4_0_0 + 5.79047619047616*G0_1_1_4_0_1 + 1.57460317460317*G0_1_1_5_0_0 + 1.6863492063492*G0_1_1_5_0_1 - 2.99682539682538*G0_1_1_6_0_0 - 2.64126984126983*G0_1_1_6_0_1 - 3.72825396825395*G0_1_1_7_0_0 - 3.83999999999998*G0_1_1_7_0_1 + 9.92507936507931*G0_1_1_8_0_0 + 13.0438095238095*G0_1_1_8_0_1 + 1.52380952380951*G0_1_1_9_0_0 - 1.95047619047619*G0_1_1_9_0_1 + 0.582433862433861*G0_1_1_10_1_0 + 0.582433862433858*G0_1_1_10_1_1 - 6.77925925925922*G0_1_1_11_1_0 + 0.372486772486771*G0_1_1_12_1_1 - 3.09841269841268*G0_1_1_13_1_0 - 13.0438095238095*G0_1_1_13_1_1 + 2.99682539682538*G0_1_1_14_1_0 + 5.79047619047616*G0_1_1_14_1_1 + 1.57460317460317*G0_1_1_15_1_0 + 1.6863492063492*G0_1_1_15_1_1 - 2.99682539682538*G0_1_1_16_1_0 - 2.64126984126983*G0_1_1_16_1_1 - 3.72825396825395*G0_1_1_17_1_0 - 3.83999999999998*G0_1_1_17_1_1 + 9.92507936507931*G0_1_1_18_1_0 + 13.0438095238095*G0_1_1_18_1_1 + 1.52380952380951*G0_1_1_19_1_0 - 1.95047619047619*G0_1_1_19_1_1; + A[816] = 0.0; + A[45] = 0.0; + A[841] = 0.0; + A[72] = -0.111746031746031*G0_1_0_0_0_0 - 0.111746031746031*G0_1_0_0_0_1 + 0.0101587301587298*G0_1_0_1_0_0 + 0.038095238095238*G0_1_0_3_0_0 - 0.0215873015873018*G0_1_0_3_0_1 + 0.0698412698412714*G0_1_0_4_0_1 + 0.0380952380952402*G0_1_0_5_0_0 + 0.181587301587303*G0_1_0_5_0_1 - 0.0698412698412731*G0_1_0_6_0_1 + 0.233650793650792*G0_1_0_7_0_0 + 0.0901587301587295*G0_1_0_7_0_1 - 0.13206349206349*G0_1_0_8_0_0 + 0.0215873015873019*G0_1_0_8_0_1 - 0.0761904761904782*G0_1_0_9_0_0 - 0.160000000000001*G0_1_0_9_0_1 - 0.111746031746031*G0_1_0_10_1_0 - 0.111746031746031*G0_1_0_10_1_1 + 0.0101587301587298*G0_1_0_11_1_0 + 0.038095238095238*G0_1_0_13_1_0 - 0.0215873015873018*G0_1_0_13_1_1 + 0.0698412698412714*G0_1_0_14_1_1 + 0.0380952380952402*G0_1_0_15_1_0 + 0.181587301587303*G0_1_0_15_1_1 - 0.0698412698412731*G0_1_0_16_1_1 + 0.233650793650792*G0_1_0_17_1_0 + 0.0901587301587295*G0_1_0_17_1_1 - 0.13206349206349*G0_1_0_18_1_0 + 0.0215873015873019*G0_1_0_18_1_1 - 0.0761904761904782*G0_1_0_19_1_0 - 0.160000000000001*G0_1_0_19_1_1 + 0.1405291005291*G0_1_1_0_0_0 + 0.1405291005291*G0_1_1_0_0_1 + 0.0982010582010579*G0_1_1_1_0_0 + 0.16931216931217*G0_1_1_2_0_1 - 0.219682539682538*G0_1_1_3_0_0 - 0.0457142857142854*G0_1_1_3_0_1 + 0.603174603174603*G0_1_1_4_0_0 + 0.358095238095239*G0_1_1_4_0_1 + 0.288253968253968*G0_1_1_5_0_0 - 0.269206349206347*G0_1_1_5_0_1 - 0.603174603174603*G0_1_1_6_0_0 - 0.0406349206349219*G0_1_1_6_0_1 + 0.166349206349206*G0_1_1_7_0_0 + 0.723809523809521*G0_1_1_7_0_1 - 0.405079365079364*G0_1_1_8_0_0 + 0.0457142857142854*G0_1_1_8_0_1 - 0.0685714285714295*G0_1_1_9_0_0 - 1.08190476190476*G0_1_1_9_0_1 + 0.1405291005291*G0_1_1_10_1_0 + 0.1405291005291*G0_1_1_10_1_1 + 0.0982010582010579*G0_1_1_11_1_0 + 0.16931216931217*G0_1_1_12_1_1 - 0.219682539682538*G0_1_1_13_1_0 - 0.0457142857142854*G0_1_1_13_1_1 + 0.603174603174603*G0_1_1_14_1_0 + 0.358095238095239*G0_1_1_14_1_1 + 0.288253968253968*G0_1_1_15_1_0 - 0.269206349206347*G0_1_1_15_1_1 - 0.603174603174603*G0_1_1_16_1_0 - 0.0406349206349219*G0_1_1_16_1_1 + 0.166349206349206*G0_1_1_17_1_0 + 0.723809523809521*G0_1_1_17_1_1 - 0.405079365079364*G0_1_1_18_1_0 + 0.0457142857142854*G0_1_1_18_1_1 - 0.0685714285714295*G0_1_1_19_1_0 - 1.08190476190476*G0_1_1_19_1_1; + A[14] = A[72] - 0.169312169312171*G0_0_0_0_0_0 - 0.169312169312171*G0_0_0_0_0_1 + 0.0880423280423276*G0_0_0_1_0_0 - 0.252275132275131*G0_0_0_2_0_1 - 0.297142857142855*G0_0_0_3_0_0 - 0.0241269841269839*G0_0_0_3_0_1 - 0.700952380952378*G0_0_0_4_0_0 - 0.63365079365079*G0_0_0_4_0_1 - 0.632380952380949*G0_0_0_5_0_0 - 0.0292063492063452*G0_0_0_5_0_1 + 0.700952380952378*G0_0_0_6_0_0 + 0.450793650793647*G0_0_0_6_0_1 + 0.314920634920637*G0_0_0_7_0_0 - 0.288253968253967*G0_0_0_7_0_1 - 0.233650793650793*G0_0_0_8_0_0 + 0.0241269841269839*G0_0_0_8_0_1 + 0.929523809523804*G0_0_0_9_0_0 + 0.921904761904757*G0_0_0_9_0_1 - 0.169312169312171*G0_0_0_10_1_0 - 0.169312169312171*G0_0_0_10_1_1 + 0.0880423280423276*G0_0_0_11_1_0 - 0.252275132275131*G0_0_0_12_1_1 - 0.297142857142855*G0_0_0_13_1_0 - 0.0241269841269839*G0_0_0_13_1_1 - 0.700952380952378*G0_0_0_14_1_0 - 0.63365079365079*G0_0_0_14_1_1 - 0.632380952380949*G0_0_0_15_1_0 - 0.0292063492063452*G0_0_0_15_1_1 + 0.700952380952378*G0_0_0_16_1_0 + 0.450793650793647*G0_0_0_16_1_1 + 0.314920634920637*G0_0_0_17_1_0 - 0.288253968253967*G0_0_0_17_1_1 - 0.233650793650793*G0_0_0_18_1_0 + 0.0241269841269839*G0_0_0_18_1_1 + 0.929523809523804*G0_0_0_19_1_0 + 0.921904761904757*G0_0_0_19_1_1 - 0.169312169312171*G0_0_1_0_0_0 - 0.169312169312171*G0_0_1_0_0_1 + 0.0982010582010576*G0_0_1_1_0_0 - 0.140529100529099*G0_0_1_2_0_1 - 0.450793650793647*G0_0_1_3_0_0 - 0.0457142857142857*G0_0_1_3_0_1 - 0.557460317460315*G0_0_1_4_0_0 - 0.723809523809519*G0_0_1_4_0_1 - 0.562539682539679*G0_0_1_5_0_0 + 0.0406349206349257*G0_0_1_5_0_1 + 0.557460317460314*G0_0_1_6_0_0 + 0.269206349206345*G0_0_1_6_0_1 + 0.245079365079368*G0_0_1_7_0_0 - 0.358095238095237*G0_0_1_7_0_1 - 0.173968253968254*G0_0_1_8_0_0 + 0.0457142857142857*G0_0_1_8_0_1 + 1.01333333333333*G0_0_1_9_0_0 + 1.08190476190476*G0_0_1_9_0_1 - 0.169312169312171*G0_0_1_10_1_0 - 0.169312169312171*G0_0_1_10_1_1 + 0.0982010582010576*G0_0_1_11_1_0 - 0.140529100529099*G0_0_1_12_1_1 - 0.450793650793647*G0_0_1_13_1_0 - 0.0457142857142857*G0_0_1_13_1_1 - 0.557460317460315*G0_0_1_14_1_0 - 0.723809523809519*G0_0_1_14_1_1 - 0.562539682539679*G0_0_1_15_1_0 + 0.0406349206349257*G0_0_1_15_1_1 + 0.557460317460314*G0_0_1_16_1_0 + 0.269206349206345*G0_0_1_16_1_1 + 0.245079365079368*G0_0_1_17_1_0 - 0.358095238095237*G0_0_1_17_1_1 - 0.173968253968254*G0_0_1_18_1_0 + 0.0457142857142857*G0_0_1_18_1_1 + 1.01333333333333*G0_0_1_19_1_0 + 1.08190476190476*G0_0_1_19_1_1 - 0.0575661375661397*G0_1_0_0_0_0 - 0.0575661375661396*G0_1_0_0_0_1 + 0.0778835978835978*G0_1_0_1_0_0 - 0.252275132275133*G0_1_0_2_0_1 - 0.335238095238092*G0_1_0_3_0_0 - 0.00253968253968187*G0_1_0_3_0_1 - 0.700952380952382*G0_1_0_4_0_0 - 0.703492063492061*G0_1_0_4_0_1 - 0.67047619047619*G0_1_0_5_0_0 - 0.210793650793648*G0_1_0_5_0_1 + 0.700952380952382*G0_1_0_6_0_0 + 0.52063492063492*G0_1_0_6_0_1 + 0.0812698412698454*G0_1_0_7_0_0 - 0.378412698412696*G0_1_0_7_0_1 - 0.101587301587303*G0_1_0_8_0_0 + 0.0025396825396818*G0_1_0_8_0_1 + 1.00571428571428*G0_1_0_9_0_0 + 1.08190476190476*G0_1_0_9_0_1 - 0.0575661375661397*G0_1_0_10_1_0 - 0.0575661375661396*G0_1_0_10_1_1 + 0.0778835978835978*G0_1_0_11_1_0 - 0.252275132275133*G0_1_0_12_1_1 - 0.335238095238092*G0_1_0_13_1_0 - 0.00253968253968187*G0_1_0_13_1_1 - 0.700952380952382*G0_1_0_14_1_0 - 0.703492063492061*G0_1_0_14_1_1 - 0.67047619047619*G0_1_0_15_1_0 - 0.210793650793648*G0_1_0_15_1_1 + 0.700952380952382*G0_1_0_16_1_0 + 0.52063492063492*G0_1_0_16_1_1 + 0.0812698412698454*G0_1_0_17_1_0 - 0.378412698412696*G0_1_0_17_1_1 - 0.101587301587303*G0_1_0_18_1_0 + 0.0025396825396818*G0_1_0_18_1_1 + 1.00571428571428*G0_1_0_19_1_0 + 1.08190476190476*G0_1_0_19_1_1 - 0.309841269841271*G0_1_1_0_0_0 - 0.309841269841271*G0_1_1_0_0_1 - 0.30984126984127*G0_1_1_2_0_1 - 0.231111111111108*G0_1_1_3_0_0 - 1.16063492063492*G0_1_1_4_0_0 - 1.08190476190476*G0_1_1_4_0_1 - 0.850793650793648*G0_1_1_5_0_0 + 0.309841269841273*G0_1_1_5_0_1 + 1.16063492063492*G0_1_1_6_0_0 + 0.309841269841268*G0_1_1_6_0_1 + 0.0787301587301624*G0_1_1_7_0_0 - 1.08190476190476*G0_1_1_7_0_1 + 0.23111111111111*G0_1_1_8_0_0 + 1.08190476190476*G0_1_1_9_0_0 + 2.16380952380952*G0_1_1_9_0_1 - 0.309841269841271*G0_1_1_10_1_0 - 0.309841269841271*G0_1_1_10_1_1 - 0.30984126984127*G0_1_1_12_1_1 - 0.231111111111108*G0_1_1_13_1_0 - 1.16063492063492*G0_1_1_14_1_0 - 1.08190476190476*G0_1_1_14_1_1 - 0.850793650793648*G0_1_1_15_1_0 + 0.309841269841273*G0_1_1_15_1_1 + 1.16063492063492*G0_1_1_16_1_0 + 0.309841269841268*G0_1_1_16_1_1 + 0.0787301587301624*G0_1_1_17_1_0 - 1.08190476190476*G0_1_1_17_1_1 + 0.23111111111111*G0_1_1_18_1_0 + 1.08190476190476*G0_1_1_19_1_0 + 2.16380952380952*G0_1_1_19_1_1; + A[874] = 0.0; + A[107] = 0.0; + A[487] = 0.0; + A[194] = A[252] - 1.01587301587301*G0_0_0_0_0_0 - 1.01587301587301*G0_0_0_0_0_1 - 0.243809523809521*G0_0_0_1_0_0 + 1.42222222222223*G0_0_0_2_0_1 + 1.46285714285713*G0_0_0_3_0_0 - 0.0406349206349206*G0_0_0_3_0_1 + 3.04761904761905*G0_0_0_4_0_0 + 2.88507936507936*G0_0_0_4_0_1 + 2.68190476190475*G0_0_0_5_0_0 + 3.08825396825396*G0_0_0_5_0_1 - 3.04761904761905*G0_0_0_6_0_0 - 3.49460317460317*G0_0_0_6_0_1 + 1.17841269841269*G0_0_0_7_0_0 + 0.772063492063487*G0_0_0_7_0_1 + 0.0812698412698417*G0_0_0_8_0_0 + 0.0406349206349207*G0_0_0_8_0_1 - 4.14476190476188*G0_0_0_9_0_0 - 3.65714285714284*G0_0_0_9_0_1 - 1.01587301587301*G0_0_0_10_1_0 - 1.01587301587301*G0_0_0_10_1_1 - 0.243809523809521*G0_0_0_11_1_0 + 1.42222222222223*G0_0_0_12_1_1 + 1.46285714285713*G0_0_0_13_1_0 - 0.0406349206349206*G0_0_0_13_1_1 + 3.04761904761905*G0_0_0_14_1_0 + 2.88507936507936*G0_0_0_14_1_1 + 2.68190476190475*G0_0_0_15_1_0 + 3.08825396825396*G0_0_0_15_1_1 - 3.04761904761905*G0_0_0_16_1_0 - 3.49460317460317*G0_0_0_16_1_1 + 1.17841269841269*G0_0_0_17_1_0 + 0.772063492063487*G0_0_0_17_1_1 + 0.0812698412698417*G0_0_0_18_1_0 + 0.0406349206349207*G0_0_0_18_1_1 - 4.14476190476188*G0_0_0_19_1_0 - 3.65714285714284*G0_0_0_19_1_1 - 0.772063492063487*G0_0_1_0_0_0 - 0.772063492063488*G0_0_1_0_0_1 - 0.345396825396824*G0_0_1_1_0_0 + 1.95047619047618*G0_0_1_2_0_1 + 1.60507936507936*G0_0_1_3_0_0 + 0.0609523809523792*G0_0_1_3_0_1 + 3.98222222222221*G0_0_1_4_0_0 + 3.23047619047618*G0_0_1_4_0_1 + 3.8806349206349*G0_0_1_5_0_0 + 3.43365079365077*G0_0_1_5_0_1 - 3.98222222222221*G0_0_1_6_0_0 - 4.61206349206347*G0_0_1_6_0_1 + 0.467301587301586*G0_0_1_7_0_0 + 0.914285714285714*G0_0_1_7_0_1 + 0.650158730158724*G0_0_1_8_0_0 - 0.0609523809523791*G0_0_1_8_0_1 - 5.48571428571426*G0_0_1_9_0_0 - 4.14476190476189*G0_0_1_9_0_1 - 0.772063492063487*G0_0_1_10_1_0 - 0.772063492063488*G0_0_1_10_1_1 - 0.345396825396824*G0_0_1_11_1_0 + 1.95047619047618*G0_0_1_12_1_1 + 1.60507936507936*G0_0_1_13_1_0 + 0.0609523809523792*G0_0_1_13_1_1 + 3.98222222222221*G0_0_1_14_1_0 + 3.23047619047618*G0_0_1_14_1_1 + 3.8806349206349*G0_0_1_15_1_0 + 3.43365079365077*G0_0_1_15_1_1 - 3.98222222222221*G0_0_1_16_1_0 - 4.61206349206347*G0_0_1_16_1_1 + 0.467301587301586*G0_0_1_17_1_0 + 0.914285714285714*G0_0_1_17_1_1 + 0.650158730158724*G0_0_1_18_1_0 - 0.0609523809523791*G0_0_1_18_1_1 - 5.48571428571426*G0_0_1_19_1_0 - 4.14476190476189*G0_0_1_19_1_1 - 0.487619047619042*G0_1_0_0_0_0 - 0.487619047619042*G0_1_0_0_0_1 - 0.142222222222221*G0_1_0_1_0_0 + 1.66603174603174*G0_1_0_2_0_1 + 0.792380952380944*G0_1_0_3_0_0 - 0.142222222222221*G0_1_0_3_0_1 + 3.90095238095237*G0_1_0_4_0_0 + 3.02730158730157*G0_1_0_4_0_1 + 2.49904761904761*G0_1_0_5_0_0 + 1.97079365079364*G0_1_0_5_0_1 - 3.90095238095237*G0_1_0_6_0_0 - 3.14920634920634*G0_1_0_6_0_1 + 0.58920634920634*G0_1_0_7_0_0 + 1.11746031746031*G0_1_0_7_0_1 + 0.0406349206349215*G0_1_0_8_0_0 + 0.142222222222222*G0_1_0_8_0_1 - 3.29142857142856*G0_1_0_9_0_0 - 4.14476190476189*G0_1_0_9_0_1 - 0.487619047619042*G0_1_0_10_1_0 - 0.487619047619042*G0_1_0_10_1_1 - 0.142222222222221*G0_1_0_11_1_0 + 1.66603174603174*G0_1_0_12_1_1 + 0.792380952380944*G0_1_0_13_1_0 - 0.142222222222221*G0_1_0_13_1_1 + 3.90095238095237*G0_1_0_14_1_0 + 3.02730158730157*G0_1_0_14_1_1 + 2.49904761904761*G0_1_0_15_1_0 + 1.97079365079364*G0_1_0_15_1_1 - 3.90095238095237*G0_1_0_16_1_0 - 3.14920634920634*G0_1_0_16_1_1 + 0.58920634920634*G0_1_0_17_1_0 + 1.11746031746031*G0_1_0_17_1_1 + 0.0406349206349215*G0_1_0_18_1_0 + 0.142222222222222*G0_1_0_18_1_1 - 3.29142857142856*G0_1_0_19_1_0 - 4.14476190476189*G0_1_0_19_1_1 + 1.1784126984127*G0_1_1_0_0_0 + 1.1784126984127*G0_1_1_0_0_1 + 1.1784126984127*G0_1_1_2_0_1 + 0.893968253968246*G0_1_1_3_0_0 + 4.42920634920634*G0_1_1_4_0_0 + 4.14476190476189*G0_1_1_4_0_1 + 3.25079365079364*G0_1_1_5_0_0 - 1.1784126984127*G0_1_1_5_0_1 - 4.42920634920634*G0_1_1_6_0_0 - 1.17841269841269*G0_1_1_6_0_1 - 0.28444444444445*G0_1_1_7_0_0 + 4.14476190476189*G0_1_1_7_0_1 - 0.893968253968251*G0_1_1_8_0_0 - 4.14476190476188*G0_1_1_9_0_0 - 8.28952380952378*G0_1_1_9_0_1 + 1.1784126984127*G0_1_1_10_1_0 + 1.1784126984127*G0_1_1_10_1_1 + 1.1784126984127*G0_1_1_12_1_1 + 0.893968253968246*G0_1_1_13_1_0 + 4.42920634920634*G0_1_1_14_1_0 + 4.14476190476189*G0_1_1_14_1_1 + 3.25079365079364*G0_1_1_15_1_0 - 1.1784126984127*G0_1_1_15_1_1 - 4.42920634920634*G0_1_1_16_1_0 - 1.17841269841269*G0_1_1_16_1_1 - 0.28444444444445*G0_1_1_17_1_0 + 4.14476190476189*G0_1_1_17_1_1 - 0.893968253968251*G0_1_1_18_1_0 - 4.14476190476188*G0_1_1_19_1_0 - 8.28952380952378*G0_1_1_19_1_1; + A[516] = 0.0; + A[225] = 0.0; + A[545] = 0.0; + A[509] = A[421] + 0.0101587301587299*G0_0_1_0_0_0 + 0.0101587301587299*G0_0_1_0_0_1 - 0.111746031746031*G0_0_1_2_0_1 + 0.069841269841269*G0_0_1_3_0_0 - 0.143492063492062*G0_0_1_4_0_0 + 0.0380952380952391*G0_0_1_4_0_1 - 0.153650793650793*G0_0_1_5_0_0 - 0.132063492063491*G0_0_1_5_0_1 + 0.143492063492062*G0_0_1_6_0_0 + 0.233650793650792*G0_0_1_6_0_1 + 0.0596825396825392*G0_0_1_7_0_0 + 0.0380952380952373*G0_0_1_7_0_1 - 0.0698412698412683*G0_0_1_8_0_0 + 0.0838095238095238*G0_0_1_9_0_0 - 0.0761904761904764*G0_0_1_9_0_1 + 0.0101587301587299*G0_0_1_10_1_0 + 0.0101587301587299*G0_0_1_10_1_1 - 0.111746031746031*G0_0_1_12_1_1 + 0.069841269841269*G0_0_1_13_1_0 - 0.143492063492062*G0_0_1_14_1_0 + 0.0380952380952391*G0_0_1_14_1_1 - 0.153650793650793*G0_0_1_15_1_0 - 0.132063492063491*G0_0_1_15_1_1 + 0.143492063492062*G0_0_1_16_1_0 + 0.233650793650792*G0_0_1_16_1_1 + 0.0596825396825392*G0_0_1_17_1_0 + 0.0380952380952373*G0_0_1_17_1_1 - 0.0698412698412683*G0_0_1_18_1_0 + 0.0838095238095238*G0_0_1_19_1_0 - 0.0761904761904764*G0_0_1_19_1_1 - 0.0101587301587299*G0_1_0_0_0_0 - 0.0101587301587299*G0_1_0_0_0_1 + 0.111746031746031*G0_1_0_2_0_1 - 0.0698412698412689*G0_1_0_3_0_0 + 0.143492063492062*G0_1_0_4_0_0 - 0.0380952380952391*G0_1_0_4_0_1 + 0.153650793650793*G0_1_0_5_0_0 + 0.132063492063491*G0_1_0_5_0_1 - 0.143492063492062*G0_1_0_6_0_0 - 0.233650793650792*G0_1_0_6_0_1 - 0.0596825396825392*G0_1_0_7_0_0 - 0.0380952380952373*G0_1_0_7_0_1 + 0.0698412698412682*G0_1_0_8_0_0 - 0.0838095238095238*G0_1_0_9_0_0 + 0.0761904761904764*G0_1_0_9_0_1 - 0.0101587301587299*G0_1_0_10_1_0 - 0.0101587301587299*G0_1_0_10_1_1 + 0.111746031746031*G0_1_0_12_1_1 - 0.0698412698412689*G0_1_0_13_1_0 + 0.143492063492062*G0_1_0_14_1_0 - 0.0380952380952391*G0_1_0_14_1_1 + 0.153650793650793*G0_1_0_15_1_0 + 0.132063492063491*G0_1_0_15_1_1 - 0.143492063492062*G0_1_0_16_1_0 - 0.233650793650792*G0_1_0_16_1_1 - 0.0596825396825392*G0_1_0_17_1_0 - 0.0380952380952373*G0_1_0_17_1_1 + 0.0698412698412682*G0_1_0_18_1_0 - 0.0838095238095238*G0_1_0_19_1_0 + 0.0761904761904764*G0_1_0_19_1_1; + A[638] = 0.0; + A[534] = 0.113015873015873*G0_1_0_0_0_0 + 0.113015873015873*G0_1_0_0_0_1 - 0.0165079365079361*G0_1_0_1_0_0 - 0.0266666666666675*G0_1_0_3_0_0 + 0.0184126984126984*G0_1_0_3_0_1 - 0.0615873015873013*G0_1_0_4_0_1 - 0.0266666666666657*G0_1_0_5_0_0 - 0.174603174603174*G0_1_0_5_0_1 + 0.0615873015873*G0_1_0_6_0_1 - 0.242539682539681*G0_1_0_7_0_0 - 0.0946031746031739*G0_1_0_7_0_1 + 0.146031746031745*G0_1_0_8_0_0 - 0.0184126984126983*G0_1_0_8_0_1 + 0.0533333333333333*G0_1_0_9_0_0 + 0.156190476190475*G0_1_0_9_0_1 + 0.113015873015873*G0_1_0_10_1_0 + 0.113015873015873*G0_1_0_10_1_1 - 0.0165079365079361*G0_1_0_11_1_0 - 0.0266666666666675*G0_1_0_13_1_0 + 0.0184126984126984*G0_1_0_13_1_1 - 0.0615873015873013*G0_1_0_14_1_1 - 0.0266666666666657*G0_1_0_15_1_0 - 0.174603174603174*G0_1_0_15_1_1 + 0.0615873015873*G0_1_0_16_1_1 - 0.242539682539681*G0_1_0_17_1_0 - 0.0946031746031739*G0_1_0_17_1_1 + 0.146031746031745*G0_1_0_18_1_0 - 0.0184126984126983*G0_1_0_18_1_1 + 0.0533333333333333*G0_1_0_19_1_0 + 0.156190476190475*G0_1_0_19_1_1 - 0.126137566137566*G0_1_1_0_0_0 - 0.126137566137566*G0_1_1_0_0_1 - 0.0173544973544971*G0_1_1_1_0_0 + 0.02962962962963*G0_1_1_2_0_1 + 0.0260317460317451*G0_1_1_3_0_0 + 0.0101587301587302*G0_1_1_3_0_1 - 0.0920634920634909*G0_1_1_4_0_0 - 0.123174603174603*G0_1_1_4_0_1 + 0.00063492063492075*G0_1_1_5_0_0 + 0.284444444444443*G0_1_1_5_0_1 + 0.092063492063491*G0_1_1_6_0_0 - 0.187936507936508*G0_1_1_6_0_1 + 0.041269841269841*G0_1_1_7_0_0 - 0.242539682539682*G0_1_1_7_0_1 + 0.102222222222222*G0_1_1_8_0_0 - 0.0101587301587302*G0_1_1_8_0_1 - 0.0266666666666658*G0_1_1_9_0_0 + 0.365714285714285*G0_1_1_9_0_1 - 0.126137566137566*G0_1_1_10_1_0 - 0.126137566137566*G0_1_1_10_1_1 - 0.0173544973544971*G0_1_1_11_1_0 + 0.02962962962963*G0_1_1_12_1_1 + 0.0260317460317451*G0_1_1_13_1_0 + 0.0101587301587302*G0_1_1_13_1_1 - 0.0920634920634909*G0_1_1_14_1_0 - 0.123174603174603*G0_1_1_14_1_1 + 0.00063492063492075*G0_1_1_15_1_0 + 0.284444444444443*G0_1_1_15_1_1 + 0.092063492063491*G0_1_1_16_1_0 - 0.187936507936508*G0_1_1_16_1_1 + 0.041269841269841*G0_1_1_17_1_0 - 0.242539682539682*G0_1_1_17_1_1 + 0.102222222222222*G0_1_1_18_1_0 - 0.0101587301587302*G0_1_1_18_1_1 - 0.0266666666666658*G0_1_1_19_1_0 + 0.365714285714285*G0_1_1_19_1_1; + A[667] = 0.0; + A[696] = 0.0; + A[265] = 0.0; + A[290] = 0.0; + A[439] = 0.0; + A[319] = 0.0; + A[460] = 0.0; + A[356] = 0.0; + A[722] = 0.0; + A[389] = 0.0; + A[753] = 0.0; + A[67] = -0.276190476190475*G0_1_0_0_0_0 - 0.276190476190475*G0_1_0_0_0_1 + 0.174603174603174*G0_1_0_1_0_0 + 1.47777777777777*G0_1_0_2_0_1 - 0.919047619047612*G0_1_0_3_0_0 - 0.103968253968252*G0_1_0_3_0_1 + 2.70476190476189*G0_1_0_4_0_0 + 0.586507936507934*G0_1_0_4_0_1 + 1.18571428571428*G0_1_0_5_0_0 + 1.15158730158729*G0_1_0_5_0_1 - 2.70476190476189*G0_1_0_6_0_0 - 2.35317460317459*G0_1_0_6_0_1 + 0.0507936507936509*G0_1_0_7_0_0 + 0.0849206349206351*G0_1_0_7_0_1 + 0.0507936507936487*G0_1_0_8_0_0 + 0.103968253968252*G0_1_0_8_0_1 - 0.266666666666665*G0_1_0_9_0_0 - 0.671428571428569*G0_1_0_9_0_1 - 0.276190476190475*G0_1_0_10_1_0 - 0.276190476190475*G0_1_0_10_1_1 + 0.174603174603174*G0_1_0_11_1_0 + 1.47777777777777*G0_1_0_12_1_1 - 0.919047619047612*G0_1_0_13_1_0 - 0.103968253968252*G0_1_0_13_1_1 + 2.70476190476189*G0_1_0_14_1_0 + 0.586507936507934*G0_1_0_14_1_1 + 1.18571428571428*G0_1_0_15_1_0 + 1.15158730158729*G0_1_0_15_1_1 - 2.70476190476189*G0_1_0_16_1_0 - 2.35317460317459*G0_1_0_16_1_1 + 0.0507936507936509*G0_1_0_17_1_0 + 0.0849206349206351*G0_1_0_17_1_1 + 0.0507936507936487*G0_1_0_18_1_0 + 0.103968253968252*G0_1_0_18_1_1 - 0.266666666666665*G0_1_0_19_1_0 - 0.671428571428569*G0_1_0_19_1_1 - 0.540423280423278*G0_1_1_0_0_0 - 0.540423280423278*G0_1_1_0_0_1 + 0.122962962962963*G0_1_1_1_0_0 + 1.27883597883597*G0_1_1_2_0_1 - 0.675396825396821*G0_1_1_3_0_0 - 0.106666666666665*G0_1_1_3_0_1 + 2.1579365079365*G0_1_1_4_0_0 + 0.433333333333331*G0_1_1_4_0_1 + 0.946825396825391*G0_1_1_5_0_0 + 1.53936507936507*G0_1_1_5_0_1 - 2.1579365079365*G0_1_1_6_0_0 - 2.27777777777777*G0_1_1_6_0_1 + 0.336349206349204*G0_1_1_7_0_0 - 0.256190476190475*G0_1_1_7_0_1 + 0.0811111111111098*G0_1_1_8_0_0 + 0.106666666666665*G0_1_1_8_0_1 - 0.27142857142857*G0_1_1_9_0_0 - 0.177142857142857*G0_1_1_9_0_1 - 0.540423280423278*G0_1_1_10_1_0 - 0.540423280423278*G0_1_1_10_1_1 + 0.122962962962963*G0_1_1_11_1_0 + 1.27883597883597*G0_1_1_12_1_1 - 0.675396825396821*G0_1_1_13_1_0 - 0.106666666666665*G0_1_1_13_1_1 + 2.1579365079365*G0_1_1_14_1_0 + 0.433333333333331*G0_1_1_14_1_1 + 0.946825396825391*G0_1_1_15_1_0 + 1.53936507936507*G0_1_1_15_1_1 - 2.1579365079365*G0_1_1_16_1_0 - 2.27777777777777*G0_1_1_16_1_1 + 0.336349206349204*G0_1_1_17_1_0 - 0.256190476190475*G0_1_1_17_1_1 + 0.0811111111111098*G0_1_1_18_1_0 + 0.106666666666665*G0_1_1_18_1_1 - 0.27142857142857*G0_1_1_19_1_0 - 0.177142857142857*G0_1_1_19_1_1; + A[112] = 0.0; + A[181] = -0.126137566137565*G0_0_0_0_0_0 - 0.126137566137565*G0_0_0_0_0_1 + 0.0296296296296296*G0_0_0_1_0_0 - 0.0173544973544971*G0_0_0_2_0_1 - 0.123174603174602*G0_0_0_3_0_0 - 0.0920634920634909*G0_0_0_3_0_1 + 0.01015873015873*G0_0_0_4_0_0 + 0.0260317460317454*G0_0_0_4_0_1 - 0.24253968253968*G0_0_0_5_0_0 + 0.0412698412698415*G0_0_0_5_0_1 - 0.01015873015873*G0_0_0_6_0_0 + 0.102222222222221*G0_0_0_6_0_1 + 0.284444444444443*G0_0_0_7_0_0 + 0.000634920634920791*G0_0_0_7_0_1 - 0.187936507936507*G0_0_0_8_0_0 + 0.0920634920634911*G0_0_0_8_0_1 + 0.365714285714282*G0_0_0_9_0_0 - 0.0266666666666663*G0_0_0_9_0_1 - 0.126137566137565*G0_0_0_10_1_0 - 0.126137566137565*G0_0_0_10_1_1 + 0.0296296296296296*G0_0_0_11_1_0 - 0.0173544973544971*G0_0_0_12_1_1 - 0.123174603174602*G0_0_0_13_1_0 - 0.0920634920634909*G0_0_0_13_1_1 + 0.01015873015873*G0_0_0_14_1_0 + 0.0260317460317454*G0_0_0_14_1_1 - 0.24253968253968*G0_0_0_15_1_0 + 0.0412698412698415*G0_0_0_15_1_1 - 0.01015873015873*G0_0_0_16_1_0 + 0.102222222222221*G0_0_0_16_1_1 + 0.284444444444443*G0_0_0_17_1_0 + 0.000634920634920791*G0_0_0_17_1_1 - 0.187936507936507*G0_0_0_18_1_0 + 0.0920634920634911*G0_0_0_18_1_1 + 0.365714285714282*G0_0_0_19_1_0 - 0.0266666666666663*G0_0_0_19_1_1 + 0.113015873015873*G0_1_0_0_0_0 + 0.113015873015873*G0_1_0_0_0_1 - 0.0165079365079362*G0_1_0_2_0_1 - 0.061587301587301*G0_1_0_3_0_0 + 0.0184126984126987*G0_1_0_4_0_0 - 0.0266666666666667*G0_1_0_4_0_1 - 0.0946031746031731*G0_1_0_5_0_0 - 0.242539682539682*G0_1_0_5_0_1 - 0.0184126984126988*G0_1_0_6_0_0 + 0.146031746031745*G0_1_0_6_0_1 - 0.174603174603175*G0_1_0_7_0_0 - 0.0266666666666658*G0_1_0_7_0_1 + 0.0615873015873014*G0_1_0_8_0_0 + 0.156190476190474*G0_1_0_9_0_0 + 0.0533333333333323*G0_1_0_9_0_1 + 0.113015873015873*G0_1_0_10_1_0 + 0.113015873015873*G0_1_0_10_1_1 - 0.0165079365079362*G0_1_0_12_1_1 - 0.061587301587301*G0_1_0_13_1_0 + 0.0184126984126987*G0_1_0_14_1_0 - 0.0266666666666667*G0_1_0_14_1_1 - 0.0946031746031731*G0_1_0_15_1_0 - 0.242539682539682*G0_1_0_15_1_1 - 0.0184126984126988*G0_1_0_16_1_0 + 0.146031746031745*G0_1_0_16_1_1 - 0.174603174603175*G0_1_0_17_1_0 - 0.0266666666666658*G0_1_0_17_1_1 + 0.0615873015873014*G0_1_0_18_1_0 + 0.156190476190474*G0_1_0_19_1_0 + 0.0533333333333323*G0_1_0_19_1_1; + A[137] = 0.0; + A[214] = A[679]; + A[170] = 0.0; + A[628] = -A[252] + 0.121904761904763*G0_0_0_0_0_0 + 0.121904761904763*G0_0_0_0_0_1 - 0.121904761904762*G0_0_0_1_0_0 - 0.121904761904762*G0_0_0_3_0_1 - 0.121904761904769*G0_0_0_5_0_1 - 0.365714285714283*G0_0_0_7_0_0 - 0.243809523809523*G0_0_0_7_0_1 + 0.365714285714283*G0_0_0_8_0_0 + 0.121904761904762*G0_0_0_8_0_1 + 0.24380952380953*G0_0_0_9_0_1 + 0.121904761904763*G0_0_0_10_1_0 + 0.121904761904763*G0_0_0_10_1_1 - 0.121904761904762*G0_0_0_11_1_0 - 0.121904761904762*G0_0_0_13_1_1 - 0.121904761904769*G0_0_0_15_1_1 - 0.365714285714283*G0_0_0_17_1_0 - 0.243809523809523*G0_0_0_17_1_1 + 0.365714285714283*G0_0_0_18_1_0 + 0.121904761904762*G0_0_0_18_1_1 + 0.24380952380953*G0_0_0_19_1_1 + 0.304761904761904*G0_0_1_0_0_0 + 0.304761904761904*G0_0_1_0_0_1 + 0.182857142857139*G0_0_1_1_0_0 - 0.487619047619042*G0_0_1_3_0_0 + 0.182857142857138*G0_0_1_3_0_1 - 0.487619047619051*G0_0_1_4_0_1 - 0.487619047619053*G0_0_1_5_0_0 - 0.792380952380954*G0_0_1_5_0_1 + 0.48761904761906*G0_0_1_6_0_1 - 0.426666666666664*G0_0_1_7_0_0 - 0.121904761904763*G0_0_1_7_0_1 - 0.0609523809523788*G0_0_1_8_0_0 - 0.182857142857138*G0_0_1_8_0_1 + 0.975238095238095*G0_0_1_9_0_0 + 0.609523809523814*G0_0_1_9_0_1 + 0.304761904761904*G0_0_1_10_1_0 + 0.304761904761904*G0_0_1_10_1_1 + 0.182857142857139*G0_0_1_11_1_0 - 0.487619047619042*G0_0_1_13_1_0 + 0.182857142857138*G0_0_1_13_1_1 - 0.487619047619051*G0_0_1_14_1_1 - 0.487619047619053*G0_0_1_15_1_0 - 0.792380952380954*G0_0_1_15_1_1 + 0.48761904761906*G0_0_1_16_1_1 - 0.426666666666664*G0_0_1_17_1_0 - 0.121904761904763*G0_0_1_17_1_1 - 0.0609523809523788*G0_0_1_18_1_0 - 0.182857142857138*G0_0_1_18_1_1 + 0.975238095238095*G0_0_1_19_1_0 + 0.609523809523814*G0_0_1_19_1_1 + 0.325079365079366*G0_1_0_0_0_0 + 0.325079365079366*G0_1_0_0_0_1 + 0.203174603174601*G0_1_0_1_0_0 + 0.487619047619048*G0_1_0_3_0_0 + 0.711111111111107*G0_1_0_3_0_1 - 0.0203174603174613*G0_1_0_4_0_1 + 0.487619047619041*G0_1_0_5_0_0 - 0.345396825396831*G0_1_0_5_0_1 + 0.0203174603174706*G0_1_0_6_0_1 - 0.446984126984126*G0_1_0_7_0_0 + 0.386031746031746*G0_1_0_7_0_1 - 0.0812698412698407*G0_1_0_8_0_0 - 0.711111111111109*G0_1_0_8_0_1 - 0.97523809523809*G0_1_0_9_0_0 - 0.365714285714283*G0_1_0_9_0_1 + 0.325079365079366*G0_1_0_10_1_0 + 0.325079365079366*G0_1_0_10_1_1 + 0.203174603174601*G0_1_0_11_1_0 + 0.487619047619048*G0_1_0_13_1_0 + 0.711111111111107*G0_1_0_13_1_1 - 0.0203174603174613*G0_1_0_14_1_1 + 0.487619047619041*G0_1_0_15_1_0 - 0.345396825396831*G0_1_0_15_1_1 + 0.0203174603174706*G0_1_0_16_1_1 - 0.446984126984126*G0_1_0_17_1_0 + 0.386031746031746*G0_1_0_17_1_1 - 0.0812698412698407*G0_1_0_18_1_0 - 0.711111111111109*G0_1_0_18_1_1 - 0.97523809523809*G0_1_0_19_1_0 - 0.365714285714283*G0_1_0_19_1_1 - 0.74497354497354*G0_1_1_0_0_0 - 0.744973544973541*G0_1_1_0_0_1 + 1.25291005291005*G0_1_1_1_0_0 + 0.419894179894171*G0_1_1_2_0_1 + 0.528253968253967*G0_1_1_3_0_0 + 3.35238095238094*G0_1_1_3_0_1 - 1.8488888888889*G0_1_1_4_0_0 - 3.83999999999999*G0_1_1_4_0_1 - 0.52825396825397*G0_1_1_5_0_0 + 1.80825396825396*G0_1_1_5_0_1 + 1.8488888888889*G0_1_1_6_0_0 - 1.48317460317459*G0_1_1_6_0_1 - 0.89396825396825*G0_1_1_7_0_0 - 3.23047619047618*G0_1_1_7_0_1 + 0.386031746031746*G0_1_1_8_0_0 - 3.35238095238094*G0_1_1_8_0_1 + 7.07047619047617*G0_1_1_9_0_1 - 0.74497354497354*G0_1_1_10_1_0 - 0.744973544973541*G0_1_1_10_1_1 + 1.25291005291005*G0_1_1_11_1_0 + 0.419894179894171*G0_1_1_12_1_1 + 0.528253968253967*G0_1_1_13_1_0 + 3.35238095238094*G0_1_1_13_1_1 - 1.8488888888889*G0_1_1_14_1_0 - 3.83999999999999*G0_1_1_14_1_1 - 0.52825396825397*G0_1_1_15_1_0 + 1.80825396825396*G0_1_1_15_1_1 + 1.8488888888889*G0_1_1_16_1_0 - 1.48317460317459*G0_1_1_16_1_1 - 0.89396825396825*G0_1_1_17_1_0 - 3.23047619047618*G0_1_1_17_1_1 + 0.386031746031746*G0_1_1_18_1_0 - 3.35238095238094*G0_1_1_18_1_1 + 7.07047619047617*G0_1_1_19_1_1; + A[207] = 0.0; + A[571] = 0.0; + A[527] = -0.213888888888888*G0_1_1_0_0_0 - 0.213888888888888*G0_1_1_0_0_1 + 0.213888888888889*G0_1_1_1_0_0 + 1.2329365079365*G0_1_1_2_0_1 - 0.85992063492063*G0_1_1_3_0_0 + 0.0115079365079379*G0_1_1_3_0_1 + 2.19722222222221*G0_1_1_4_0_0 + 0.306746031746031*G0_1_1_4_0_1 + 0.859920634920631*G0_1_1_5_0_0 + 0.871428571428567*G0_1_1_5_0_1 - 2.19722222222221*G0_1_1_6_0_0 - 1.89047619047618*G0_1_1_6_0_1 - 0.0115079365079359*G0_1_1_7_0_1 - 0.0115079365079377*G0_1_1_8_0_1 - 0.295238095238094*G0_1_1_9_0_1 - 0.213888888888888*G0_1_1_10_1_0 - 0.213888888888888*G0_1_1_10_1_1 + 0.213888888888889*G0_1_1_11_1_0 + 1.2329365079365*G0_1_1_12_1_1 - 0.85992063492063*G0_1_1_13_1_0 + 0.0115079365079379*G0_1_1_13_1_1 + 2.19722222222221*G0_1_1_14_1_0 + 0.306746031746031*G0_1_1_14_1_1 + 0.859920634920631*G0_1_1_15_1_0 + 0.871428571428567*G0_1_1_15_1_1 - 2.19722222222221*G0_1_1_16_1_0 - 1.89047619047618*G0_1_1_16_1_1 - 0.0115079365079359*G0_1_1_17_1_1 - 0.0115079365079377*G0_1_1_18_1_1 - 0.295238095238094*G0_1_1_19_1_1; + A[562] = A[213] - 0.132063492063491*G0_0_1_0_0_0 - 0.132063492063491*G0_0_1_0_0_1 + 0.0203174603174643*G0_0_1_1_0_0 + 0.0152380952380973*G0_0_1_2_0_1 + 0.0457142857142872*G0_0_1_3_0_0 + 0.033015873015881*G0_0_1_3_0_1 - 0.060952380952378*G0_0_1_4_0_0 - 0.0431746031746046*G0_0_1_4_0_1 + 0.0761904761904789*G0_0_1_5_0_0 + 0.271746031746031*G0_0_1_5_0_1 + 0.0609523809523781*G0_0_1_6_0_0 - 0.154920634920637*G0_0_1_6_0_1 + 0.193015873015873*G0_0_1_7_0_0 - 0.00253968253967896*G0_0_1_7_0_1 - 0.0812698412698458*G0_0_1_8_0_0 - 0.0330158730158808*G0_0_1_8_0_1 - 0.121904761904766*G0_0_1_9_0_0 + 0.0457142857142835*G0_0_1_9_0_1 - 0.132063492063491*G0_0_1_10_1_0 - 0.132063492063491*G0_0_1_10_1_1 + 0.0203174603174643*G0_0_1_11_1_0 + 0.0152380952380973*G0_0_1_12_1_1 + 0.0457142857142872*G0_0_1_13_1_0 + 0.033015873015881*G0_0_1_13_1_1 - 0.060952380952378*G0_0_1_14_1_0 - 0.0431746031746046*G0_0_1_14_1_1 + 0.0761904761904789*G0_0_1_15_1_0 + 0.271746031746031*G0_0_1_15_1_1 + 0.0609523809523781*G0_0_1_16_1_0 - 0.154920634920637*G0_0_1_16_1_1 + 0.193015873015873*G0_0_1_17_1_0 - 0.00253968253967896*G0_0_1_17_1_1 - 0.0812698412698458*G0_0_1_18_1_0 - 0.0330158730158808*G0_0_1_18_1_1 - 0.121904761904766*G0_0_1_19_1_0 + 0.0457142857142835*G0_0_1_19_1_1 + 0.132063492063491*G0_1_0_0_0_0 + 0.132063492063491*G0_1_0_0_0_1 - 0.0203174603174643*G0_1_0_1_0_0 - 0.0152380952380973*G0_1_0_2_0_1 - 0.045714285714287*G0_1_0_3_0_0 - 0.0330158730158809*G0_1_0_3_0_1 + 0.060952380952378*G0_1_0_4_0_0 + 0.0431746031746045*G0_1_0_4_0_1 - 0.0761904761904789*G0_1_0_5_0_0 - 0.271746031746031*G0_1_0_5_0_1 - 0.0609523809523781*G0_1_0_6_0_0 + 0.154920634920637*G0_1_0_6_0_1 - 0.193015873015873*G0_1_0_7_0_0 + 0.00253968253967897*G0_1_0_7_0_1 + 0.0812698412698458*G0_1_0_8_0_0 + 0.0330158730158808*G0_1_0_8_0_1 + 0.121904761904766*G0_1_0_9_0_0 - 0.0457142857142834*G0_1_0_9_0_1 + 0.132063492063491*G0_1_0_10_1_0 + 0.132063492063491*G0_1_0_10_1_1 - 0.0203174603174643*G0_1_0_11_1_0 - 0.0152380952380973*G0_1_0_12_1_1 - 0.045714285714287*G0_1_0_13_1_0 - 0.0330158730158809*G0_1_0_13_1_1 + 0.060952380952378*G0_1_0_14_1_0 + 0.0431746031746045*G0_1_0_14_1_1 - 0.0761904761904789*G0_1_0_15_1_0 - 0.271746031746031*G0_1_0_15_1_1 - 0.0609523809523781*G0_1_0_16_1_0 + 0.154920634920637*G0_1_0_16_1_1 - 0.193015873015873*G0_1_0_17_1_0 + 0.00253968253967897*G0_1_0_17_1_1 + 0.0812698412698458*G0_1_0_18_1_0 + 0.0330158730158808*G0_1_0_18_1_1 + 0.121904761904766*G0_1_0_19_1_0 - 0.0457142857142834*G0_1_0_19_1_1; + A[299] = 0.0; + A[446] = 0.0; + A[326] = 0.0; + A[349] = 0.0; + A[28] = 0.0; + A[729] = 0.0; + A[380] = 0.0; + A[830] = -A[368] + 0.142222222222224*G0_0_1_0_0_0 + 0.142222222222224*G0_0_1_0_0_1 - 0.345396825396822*G0_0_1_1_0_0 + 1.21904761904761*G0_0_1_3_0_0 + 0.162539682539682*G0_0_1_3_0_1 + 0.711111111111104*G0_0_1_4_0_1 + 1.21904761904761*G0_0_1_5_0_0 + 0.568888888888877*G0_0_1_5_0_1 - 0.7111111111111*G0_0_1_6_0_1 - 0.629841269841269*G0_0_1_7_0_0 + 0.0203174603174586*G0_0_1_7_0_1 + 0.833015873015868*G0_0_1_8_0_0 - 0.162539682539683*G0_0_1_8_0_1 - 2.43809523809522*G0_0_1_9_0_0 - 0.731428571428562*G0_0_1_9_0_1 + 0.142222222222224*G0_0_1_10_1_0 + 0.142222222222224*G0_0_1_10_1_1 - 0.345396825396822*G0_0_1_11_1_0 + 1.21904761904761*G0_0_1_13_1_0 + 0.162539682539682*G0_0_1_13_1_1 + 0.711111111111104*G0_0_1_14_1_1 + 1.21904761904761*G0_0_1_15_1_0 + 0.568888888888877*G0_0_1_15_1_1 - 0.7111111111111*G0_0_1_16_1_1 - 0.629841269841269*G0_0_1_17_1_0 + 0.0203174603174586*G0_0_1_17_1_1 + 0.833015873015868*G0_0_1_18_1_0 - 0.162539682539683*G0_0_1_18_1_1 - 2.43809523809522*G0_0_1_19_1_0 - 0.731428571428562*G0_0_1_19_1_1 - 1.47640211640211*G0_1_1_0_0_0 - 1.47640211640211*G0_1_1_0_0_1 - 0.697566137566135*G0_1_1_1_0_0 + 0.541798941798937*G0_1_1_2_0_1 + 1.86920634920634*G0_1_1_3_0_0 + 0.182857142857142*G0_1_1_3_0_1 - 0.507936507936509*G0_1_1_4_0_0 - 0.060952380952384*G0_1_1_4_0_1 + 1.05650793650793*G0_1_1_5_0_0 + 4.12444444444442*G0_1_1_5_0_1 + 0.50793650793651*G0_1_1_6_0_0 - 3.18984126984125*G0_1_1_6_0_1 - 0.284444444444446*G0_1_1_7_0_0 - 3.35238095238094*G0_1_1_7_0_1 + 2.45841269841269*G0_1_1_8_0_0 - 0.182857142857141*G0_1_1_8_0_1 - 2.92571428571427*G0_1_1_9_0_0 + 3.41333333333332*G0_1_1_9_0_1 - 1.47640211640211*G0_1_1_10_1_0 - 1.47640211640211*G0_1_1_10_1_1 - 0.697566137566135*G0_1_1_11_1_0 + 0.541798941798937*G0_1_1_12_1_1 + 1.86920634920634*G0_1_1_13_1_0 + 0.182857142857142*G0_1_1_13_1_1 - 0.507936507936509*G0_1_1_14_1_0 - 0.060952380952384*G0_1_1_14_1_1 + 1.05650793650793*G0_1_1_15_1_0 + 4.12444444444442*G0_1_1_15_1_1 + 0.50793650793651*G0_1_1_16_1_0 - 3.18984126984125*G0_1_1_16_1_1 - 0.284444444444446*G0_1_1_17_1_0 - 3.35238095238094*G0_1_1_17_1_1 + 2.45841269841269*G0_1_1_18_1_0 - 0.182857142857141*G0_1_1_18_1_1 - 2.92571428571427*G0_1_1_19_1_0 + 3.41333333333332*G0_1_1_19_1_1; + A[55] = 0.0; + A[754] = 0.0; + A[415] = 0.0; + A[783] = 0.0; + A[820] = 0.0; + A[144] = 0.0; + A[853] = 0.0; + A[179] = 0.0; + A[627] = -A[252] + 0.142222222222224*G0_1_0_0_0_0 + 0.142222222222224*G0_1_0_0_0_1 - 0.345396825396822*G0_1_0_1_0_0 + 1.21904761904761*G0_1_0_3_0_0 + 0.162539682539682*G0_1_0_3_0_1 + 0.711111111111104*G0_1_0_4_0_1 + 1.21904761904761*G0_1_0_5_0_0 + 0.568888888888877*G0_1_0_5_0_1 - 0.7111111111111*G0_1_0_6_0_1 - 0.629841269841269*G0_1_0_7_0_0 + 0.0203174603174586*G0_1_0_7_0_1 + 0.833015873015868*G0_1_0_8_0_0 - 0.162539682539683*G0_1_0_8_0_1 - 2.43809523809522*G0_1_0_9_0_0 - 0.731428571428562*G0_1_0_9_0_1 + 0.142222222222224*G0_1_0_10_1_0 + 0.142222222222224*G0_1_0_10_1_1 - 0.345396825396822*G0_1_0_11_1_0 + 1.21904761904761*G0_1_0_13_1_0 + 0.162539682539682*G0_1_0_13_1_1 + 0.711111111111104*G0_1_0_14_1_1 + 1.21904761904761*G0_1_0_15_1_0 + 0.568888888888877*G0_1_0_15_1_1 - 0.7111111111111*G0_1_0_16_1_1 - 0.629841269841269*G0_1_0_17_1_0 + 0.0203174603174586*G0_1_0_17_1_1 + 0.833015873015868*G0_1_0_18_1_0 - 0.162539682539683*G0_1_0_18_1_1 - 2.43809523809522*G0_1_0_19_1_0 - 0.731428571428562*G0_1_0_19_1_1 - 1.47640211640211*G0_1_1_0_0_0 - 1.47640211640211*G0_1_1_0_0_1 - 0.697566137566135*G0_1_1_1_0_0 + 0.541798941798937*G0_1_1_2_0_1 + 1.86920634920634*G0_1_1_3_0_0 + 0.182857142857142*G0_1_1_3_0_1 - 0.507936507936509*G0_1_1_4_0_0 - 0.060952380952384*G0_1_1_4_0_1 + 1.05650793650793*G0_1_1_5_0_0 + 4.12444444444442*G0_1_1_5_0_1 + 0.50793650793651*G0_1_1_6_0_0 - 3.18984126984125*G0_1_1_6_0_1 - 0.284444444444446*G0_1_1_7_0_0 - 3.35238095238094*G0_1_1_7_0_1 + 2.45841269841269*G0_1_1_8_0_0 - 0.182857142857141*G0_1_1_8_0_1 - 2.92571428571427*G0_1_1_9_0_0 + 3.41333333333332*G0_1_1_9_0_1 - 1.47640211640211*G0_1_1_10_1_0 - 1.47640211640211*G0_1_1_10_1_1 - 0.697566137566135*G0_1_1_11_1_0 + 0.541798941798937*G0_1_1_12_1_1 + 1.86920634920634*G0_1_1_13_1_0 + 0.182857142857142*G0_1_1_13_1_1 - 0.507936507936509*G0_1_1_14_1_0 - 0.060952380952384*G0_1_1_14_1_1 + 1.05650793650793*G0_1_1_15_1_0 + 4.12444444444442*G0_1_1_15_1_1 + 0.50793650793651*G0_1_1_16_1_0 - 3.18984126984125*G0_1_1_16_1_1 - 0.284444444444446*G0_1_1_17_1_0 - 3.35238095238094*G0_1_1_17_1_1 + 2.45841269841269*G0_1_1_18_1_0 - 0.182857142857141*G0_1_1_18_1_1 - 2.92571428571427*G0_1_1_19_1_0 + 3.41333333333332*G0_1_1_19_1_1; + A[491] = 0.0; + A[198] = 0.0; + A[656] = A[716] + 0.602751322751319*G0_0_0_0_0_0 + 0.602751322751319*G0_0_0_0_0_1 - 0.196402116402113*G0_0_0_1_0_0 + 0.0880423280423269*G0_0_0_2_0_1 + 0.386031746031744*G0_0_0_3_0_0 + 0.243809523809525*G0_0_0_3_0_1 + 0.020317460317459*G0_0_0_4_0_0 - 0.121904761904762*G0_0_0_4_0_1 + 0.833015873015867*G0_0_0_5_0_0 - 0.345396825396824*G0_0_0_5_0_1 - 0.0203174603174588*G0_0_0_6_0_0 - 0.345396825396822*G0_0_0_6_0_1 - 1.42222222222221*G0_0_0_7_0_0 - 0.243809523809522*G0_0_0_7_0_1 + 1.01587301587301*G0_0_0_8_0_0 - 0.243809523809525*G0_0_0_8_0_1 - 1.21904761904761*G0_0_0_9_0_0 + 0.365714285714284*G0_0_0_9_0_1 + 0.602751322751319*G0_0_0_10_1_0 + 0.602751322751319*G0_0_0_10_1_1 - 0.196402116402113*G0_0_0_11_1_0 + 0.0880423280423269*G0_0_0_12_1_1 + 0.386031746031744*G0_0_0_13_1_0 + 0.243809523809525*G0_0_0_13_1_1 + 0.020317460317459*G0_0_0_14_1_0 - 0.121904761904762*G0_0_0_14_1_1 + 0.833015873015867*G0_0_0_15_1_0 - 0.345396825396824*G0_0_0_15_1_1 - 0.0203174603174588*G0_0_0_16_1_0 - 0.345396825396822*G0_0_0_16_1_1 - 1.42222222222221*G0_0_0_17_1_0 - 0.243809523809522*G0_0_0_17_1_1 + 1.01587301587301*G0_0_0_18_1_0 - 0.243809523809525*G0_0_0_18_1_1 - 1.21904761904761*G0_0_0_19_1_0 + 0.365714285714284*G0_0_0_19_1_1 - 0.101587301587302*G0_0_1_0_0_0 - 0.101587301587302*G0_0_1_0_0_1 - 0.162539682539681*G0_0_1_2_0_1 + 0.162539682539683*G0_0_1_3_0_0 - 0.264126984126982*G0_0_1_4_0_0 + 0.060952380952381*G0_0_1_4_0_1 - 0.162539682539681*G0_0_1_5_0_0 + 0.0406349206349213*G0_0_1_5_0_1 + 0.264126984126982*G0_0_1_6_0_0 + 0.223492063492062*G0_0_1_6_0_1 + 0.264126984126985*G0_0_1_7_0_0 + 0.0609523809523825*G0_0_1_7_0_1 - 0.162539682539685*G0_0_1_8_0_0 - 0.121904761904763*G0_0_1_9_0_1 - 0.101587301587302*G0_0_1_10_1_0 - 0.101587301587302*G0_0_1_10_1_1 - 0.162539682539681*G0_0_1_12_1_1 + 0.162539682539683*G0_0_1_13_1_0 - 0.264126984126982*G0_0_1_14_1_0 + 0.060952380952381*G0_0_1_14_1_1 - 0.162539682539681*G0_0_1_15_1_0 + 0.0406349206349213*G0_0_1_15_1_1 + 0.264126984126982*G0_0_1_16_1_0 + 0.223492063492062*G0_0_1_16_1_1 + 0.264126984126985*G0_0_1_17_1_0 + 0.0609523809523825*G0_0_1_17_1_1 - 0.162539682539685*G0_0_1_18_1_0 - 0.121904761904763*G0_0_1_19_1_1 - 0.62984126984127*G0_1_0_0_0_0 - 0.629841269841269*G0_1_0_0_0_1 - 0.0203174603174596*G0_1_0_2_0_1 + 0.446984126984124*G0_1_0_3_0_0 - 0.223492063492063*G0_1_0_4_0_0 + 0.24380952380952*G0_1_0_4_0_1 + 0.406349206349203*G0_1_0_5_0_0 + 1.23936507936508*G0_1_0_5_0_1 + 0.223492063492063*G0_1_0_6_0_0 - 0.589206349206348*G0_1_0_6_0_1 + 1.0768253968254*G0_1_0_7_0_0 + 0.243809523809522*G0_1_0_7_0_1 - 0.446984126984128*G0_1_0_8_0_0 - 0.853333333333327*G0_1_0_9_0_0 - 0.487619047619042*G0_1_0_9_0_1 - 0.62984126984127*G0_1_0_10_1_0 - 0.629841269841269*G0_1_0_10_1_1 - 0.0203174603174596*G0_1_0_12_1_1 + 0.446984126984124*G0_1_0_13_1_0 - 0.223492063492063*G0_1_0_14_1_0 + 0.24380952380952*G0_1_0_14_1_1 + 0.406349206349203*G0_1_0_15_1_0 + 1.23936507936508*G0_1_0_15_1_1 + 0.223492063492063*G0_1_0_16_1_0 - 0.589206349206348*G0_1_0_16_1_1 + 1.0768253968254*G0_1_0_17_1_0 + 0.243809523809522*G0_1_0_17_1_1 - 0.446984126984128*G0_1_0_18_1_0 - 0.853333333333327*G0_1_0_19_1_0 - 0.487619047619042*G0_1_0_19_1_1 + 0.0609523809523815*G0_1_1_0_0_0 + 0.0609523809523815*G0_1_1_0_0_1 - 0.06095238095238*G0_1_1_2_0_1 - 0.0609523809523801*G0_1_1_4_0_0 - 0.121904761904761*G0_1_1_5_0_0 - 0.182857142857143*G0_1_1_5_0_1 + 0.0609523809523801*G0_1_1_6_0_0 + 0.182857142857142*G0_1_1_6_0_1 - 0.0609523809523815*G0_1_1_7_0_0 + 0.121904761904761*G0_1_1_9_0_0 + 0.0609523809523815*G0_1_1_10_1_0 + 0.0609523809523815*G0_1_1_10_1_1 - 0.06095238095238*G0_1_1_12_1_1 - 0.0609523809523801*G0_1_1_14_1_0 - 0.121904761904761*G0_1_1_15_1_0 - 0.182857142857143*G0_1_1_15_1_1 + 0.0609523809523801*G0_1_1_16_1_0 + 0.182857142857142*G0_1_1_16_1_1 - 0.0609523809523815*G0_1_1_17_1_0 + 0.121904761904761*G0_1_1_19_1_0; + A[576] = 0.0; + A[520] = 0.0; + A[237] = 0.0; + A[677] = -0.276190476190475*G0_0_1_0_0_0 - 0.276190476190475*G0_0_1_0_0_1 + 0.174603174603174*G0_0_1_1_0_0 + 1.47777777777777*G0_0_1_2_0_1 - 0.919047619047612*G0_0_1_3_0_0 - 0.103968253968252*G0_0_1_3_0_1 + 2.70476190476189*G0_0_1_4_0_0 + 0.586507936507934*G0_0_1_4_0_1 + 1.18571428571428*G0_0_1_5_0_0 + 1.15158730158729*G0_0_1_5_0_1 - 2.70476190476189*G0_0_1_6_0_0 - 2.35317460317459*G0_0_1_6_0_1 + 0.0507936507936509*G0_0_1_7_0_0 + 0.0849206349206351*G0_0_1_7_0_1 + 0.0507936507936487*G0_0_1_8_0_0 + 0.103968253968252*G0_0_1_8_0_1 - 0.266666666666665*G0_0_1_9_0_0 - 0.671428571428569*G0_0_1_9_0_1 - 0.276190476190475*G0_0_1_10_1_0 - 0.276190476190475*G0_0_1_10_1_1 + 0.174603174603174*G0_0_1_11_1_0 + 1.47777777777777*G0_0_1_12_1_1 - 0.919047619047612*G0_0_1_13_1_0 - 0.103968253968252*G0_0_1_13_1_1 + 2.70476190476189*G0_0_1_14_1_0 + 0.586507936507934*G0_0_1_14_1_1 + 1.18571428571428*G0_0_1_15_1_0 + 1.15158730158729*G0_0_1_15_1_1 - 2.70476190476189*G0_0_1_16_1_0 - 2.35317460317459*G0_0_1_16_1_1 + 0.0507936507936509*G0_0_1_17_1_0 + 0.0849206349206351*G0_0_1_17_1_1 + 0.0507936507936487*G0_0_1_18_1_0 + 0.103968253968252*G0_0_1_18_1_1 - 0.266666666666665*G0_0_1_19_1_0 - 0.671428571428569*G0_0_1_19_1_1 - 0.540423280423278*G0_1_1_0_0_0 - 0.540423280423278*G0_1_1_0_0_1 + 0.122962962962963*G0_1_1_1_0_0 + 1.27883597883597*G0_1_1_2_0_1 - 0.675396825396821*G0_1_1_3_0_0 - 0.106666666666665*G0_1_1_3_0_1 + 2.1579365079365*G0_1_1_4_0_0 + 0.433333333333331*G0_1_1_4_0_1 + 0.946825396825391*G0_1_1_5_0_0 + 1.53936507936507*G0_1_1_5_0_1 - 2.1579365079365*G0_1_1_6_0_0 - 2.27777777777777*G0_1_1_6_0_1 + 0.336349206349204*G0_1_1_7_0_0 - 0.256190476190475*G0_1_1_7_0_1 + 0.0811111111111098*G0_1_1_8_0_0 + 0.106666666666665*G0_1_1_8_0_1 - 0.27142857142857*G0_1_1_9_0_0 - 0.177142857142857*G0_1_1_9_0_1 - 0.540423280423278*G0_1_1_10_1_0 - 0.540423280423278*G0_1_1_10_1_1 + 0.122962962962963*G0_1_1_11_1_0 + 1.27883597883597*G0_1_1_12_1_1 - 0.675396825396821*G0_1_1_13_1_0 - 0.106666666666665*G0_1_1_13_1_1 + 2.1579365079365*G0_1_1_14_1_0 + 0.433333333333331*G0_1_1_14_1_1 + 0.946825396825391*G0_1_1_15_1_0 + 1.53936507936507*G0_1_1_15_1_1 - 2.1579365079365*G0_1_1_16_1_0 - 2.27777777777777*G0_1_1_16_1_1 + 0.336349206349204*G0_1_1_17_1_0 - 0.256190476190475*G0_1_1_17_1_1 + 0.0811111111111098*G0_1_1_18_1_0 + 0.106666666666665*G0_1_1_18_1_1 - 0.27142857142857*G0_1_1_19_1_0 - 0.177142857142857*G0_1_1_19_1_1; + A[601] = 0.0; + A[710] = A[245]; + A[634] = 0.0; + A[671] = 0.0; + A[449] = 0.0; + A[474] = A[270] - 2.80423280423279*G0_0_1_0_0_0 - 2.80423280423279*G0_0_1_0_0_1 + 0.423280423280421*G0_0_1_1_0_0 + 0.423280423280421*G0_0_1_2_0_1 - 0.14920634920635*G0_0_1_3_0_0 - 0.149206349206347*G0_0_1_3_0_1 - 0.14920634920635*G0_0_1_4_0_0 - 0.149206349206351*G0_0_1_4_0_1 - 0.860317460317457*G0_0_1_5_0_0 + 4.25714285714284*G0_0_1_5_0_1 + 0.14920634920635*G0_0_1_6_0_0 - 1.87619047619047*G0_0_1_6_0_1 + 4.25714285714284*G0_0_1_7_0_0 - 0.860317460317457*G0_0_1_7_0_1 - 1.87619047619047*G0_0_1_8_0_0 + 0.149206349206347*G0_0_1_8_0_1 + 1.00952380952381*G0_0_1_9_0_0 + 1.00952380952381*G0_0_1_9_0_1 - 2.80423280423279*G0_0_1_10_1_0 - 2.80423280423279*G0_0_1_10_1_1 + 0.423280423280421*G0_0_1_11_1_0 + 0.423280423280421*G0_0_1_12_1_1 - 0.14920634920635*G0_0_1_13_1_0 - 0.149206349206347*G0_0_1_13_1_1 - 0.14920634920635*G0_0_1_14_1_0 - 0.149206349206351*G0_0_1_14_1_1 - 0.860317460317457*G0_0_1_15_1_0 + 4.25714285714284*G0_0_1_15_1_1 + 0.14920634920635*G0_0_1_16_1_0 - 1.87619047619047*G0_0_1_16_1_1 + 4.25714285714284*G0_0_1_17_1_0 - 0.860317460317457*G0_0_1_17_1_1 - 1.87619047619047*G0_0_1_18_1_0 + 0.149206349206347*G0_0_1_18_1_1 + 1.00952380952381*G0_0_1_19_1_0 + 1.00952380952381*G0_0_1_19_1_1 + 2.80423280423279*G0_1_0_0_0_0 + 2.80423280423279*G0_1_0_0_0_1 - 0.423280423280421*G0_1_0_1_0_0 - 0.423280423280421*G0_1_0_2_0_1 + 0.14920634920635*G0_1_0_3_0_0 + 0.149206349206347*G0_1_0_3_0_1 + 0.14920634920635*G0_1_0_4_0_0 + 0.149206349206351*G0_1_0_4_0_1 + 0.860317460317457*G0_1_0_5_0_0 - 4.25714285714284*G0_1_0_5_0_1 - 0.14920634920635*G0_1_0_6_0_0 + 1.87619047619047*G0_1_0_6_0_1 - 4.25714285714284*G0_1_0_7_0_0 + 0.860317460317457*G0_1_0_7_0_1 + 1.87619047619047*G0_1_0_8_0_0 - 0.149206349206347*G0_1_0_8_0_1 - 1.00952380952381*G0_1_0_9_0_0 - 1.00952380952381*G0_1_0_9_0_1 + 2.80423280423279*G0_1_0_10_1_0 + 2.80423280423279*G0_1_0_10_1_1 - 0.423280423280421*G0_1_0_11_1_0 - 0.423280423280421*G0_1_0_12_1_1 + 0.14920634920635*G0_1_0_13_1_0 + 0.149206349206347*G0_1_0_13_1_1 + 0.14920634920635*G0_1_0_14_1_0 + 0.149206349206351*G0_1_0_14_1_1 + 0.860317460317457*G0_1_0_15_1_0 - 4.25714285714284*G0_1_0_15_1_1 - 0.14920634920635*G0_1_0_16_1_0 + 1.87619047619047*G0_1_0_16_1_1 - 4.25714285714284*G0_1_0_17_1_0 + 0.860317460317457*G0_1_0_17_1_1 + 1.87619047619047*G0_1_0_18_1_0 - 0.149206349206347*G0_1_0_18_1_1 - 1.00952380952381*G0_1_0_19_1_0 - 1.00952380952381*G0_1_0_19_1_1; + A[645] = A[474] - 2.80423280423279*G0_0_0_0_0_0 - 2.80423280423279*G0_0_0_0_0_1 + 0.620105820105817*G0_0_0_1_0_0 + 0.226455026455025*G0_0_0_2_0_1 - 0.0380952380952395*G0_0_0_3_0_0 + 0.158730158730159*G0_0_0_3_0_1 - 0.457142857142856*G0_0_0_4_0_0 - 0.260317460317461*G0_0_0_4_0_1 - 1.14285714285714*G0_0_0_5_0_0 + 3.97460317460316*G0_0_0_5_0_1 + 0.457142857142856*G0_0_0_6_0_0 - 1.39682539682539*G0_0_0_6_0_1 + 4.53968253968252*G0_0_0_7_0_0 - 0.577777777777776*G0_0_0_7_0_1 - 2.35555555555554*G0_0_0_8_0_0 - 0.158730158730159*G0_0_0_8_0_1 + 1.18095238095238*G0_0_0_9_0_0 + 0.838095238095238*G0_0_0_9_0_1 - 2.80423280423279*G0_0_0_10_1_0 - 2.80423280423279*G0_0_0_10_1_1 + 0.620105820105817*G0_0_0_11_1_0 + 0.226455026455025*G0_0_0_12_1_1 - 0.0380952380952395*G0_0_0_13_1_0 + 0.158730158730159*G0_0_0_13_1_1 - 0.457142857142856*G0_0_0_14_1_0 - 0.260317460317461*G0_0_0_14_1_1 - 1.14285714285714*G0_0_0_15_1_0 + 3.97460317460316*G0_0_0_15_1_1 + 0.457142857142856*G0_0_0_16_1_0 - 1.39682539682539*G0_0_0_16_1_1 + 4.53968253968252*G0_0_0_17_1_0 - 0.577777777777776*G0_0_0_17_1_1 - 2.35555555555554*G0_0_0_18_1_0 - 0.158730158730159*G0_0_0_18_1_1 + 1.18095238095238*G0_0_0_19_1_0 + 0.838095238095238*G0_0_0_19_1_1 + 0.196825396825395*G0_0_1_1_0_0 - 0.196825396825396*G0_0_1_2_0_1 + 0.111111111111111*G0_0_1_3_0_0 + 0.307936507936506*G0_0_1_3_0_1 - 0.307936507936507*G0_0_1_4_0_0 - 0.11111111111111*G0_0_1_4_0_1 - 0.28253968253968*G0_0_1_5_0_0 - 0.282539682539683*G0_0_1_5_0_1 + 0.307936507936507*G0_0_1_6_0_0 + 0.479365079365077*G0_0_1_6_0_1 + 0.282539682539679*G0_0_1_7_0_0 + 0.282539682539682*G0_0_1_7_0_1 - 0.479365079365076*G0_0_1_8_0_0 - 0.307936507936506*G0_0_1_8_0_1 + 0.171428571428569*G0_0_1_9_0_0 - 0.171428571428572*G0_0_1_9_0_1 + 0.196825396825395*G0_0_1_11_1_0 - 0.196825396825396*G0_0_1_12_1_1 + 0.111111111111111*G0_0_1_13_1_0 + 0.307936507936506*G0_0_1_13_1_1 - 0.307936507936507*G0_0_1_14_1_0 - 0.11111111111111*G0_0_1_14_1_1 - 0.28253968253968*G0_0_1_15_1_0 - 0.282539682539683*G0_0_1_15_1_1 + 0.307936507936507*G0_0_1_16_1_0 + 0.479365079365077*G0_0_1_16_1_1 + 0.282539682539679*G0_0_1_17_1_0 + 0.282539682539682*G0_0_1_17_1_1 - 0.479365079365076*G0_0_1_18_1_0 - 0.307936507936506*G0_0_1_18_1_1 + 0.171428571428569*G0_0_1_19_1_0 - 0.171428571428572*G0_0_1_19_1_1 + 0.196825396825396*G0_1_0_1_0_0 - 0.196825396825395*G0_1_0_2_0_1 + 0.11111111111111*G0_1_0_3_0_0 + 0.307936507936506*G0_1_0_3_0_1 - 0.307936507936506*G0_1_0_4_0_0 - 0.11111111111111*G0_1_0_4_0_1 - 0.282539682539681*G0_1_0_5_0_0 - 0.282539682539681*G0_1_0_5_0_1 + 0.307936507936506*G0_1_0_6_0_0 + 0.479365079365076*G0_1_0_6_0_1 + 0.282539682539685*G0_1_0_7_0_0 + 0.28253968253968*G0_1_0_7_0_1 - 0.479365079365077*G0_1_0_8_0_0 - 0.307936507936506*G0_1_0_8_0_1 + 0.171428571428571*G0_1_0_9_0_0 - 0.17142857142857*G0_1_0_9_0_1 + 0.196825396825396*G0_1_0_11_1_0 - 0.196825396825395*G0_1_0_12_1_1 + 0.11111111111111*G0_1_0_13_1_0 + 0.307936507936506*G0_1_0_13_1_1 - 0.307936507936506*G0_1_0_14_1_0 - 0.11111111111111*G0_1_0_14_1_1 - 0.282539682539681*G0_1_0_15_1_0 - 0.282539682539681*G0_1_0_15_1_1 + 0.307936507936506*G0_1_0_16_1_0 + 0.479365079365076*G0_1_0_16_1_1 + 0.282539682539685*G0_1_0_17_1_0 + 0.28253968253968*G0_1_0_17_1_1 - 0.479365079365077*G0_1_0_18_1_0 - 0.307936507936506*G0_1_0_18_1_1 + 0.171428571428571*G0_1_0_19_1_0 - 0.17142857142857*G0_1_0_19_1_1 + 2.80423280423279*G0_1_1_0_0_0 + 2.80423280423279*G0_1_1_0_0_1 - 0.226455026455026*G0_1_1_1_0_0 - 0.620105820105817*G0_1_1_2_0_1 + 0.260317460317461*G0_1_1_3_0_0 + 0.457142857142852*G0_1_1_3_0_1 - 0.158730158730157*G0_1_1_4_0_0 + 0.0380952380952406*G0_1_1_4_0_1 + 0.577777777777776*G0_1_1_5_0_0 - 4.53968253968252*G0_1_1_5_0_1 + 0.158730158730157*G0_1_1_6_0_0 + 2.35555555555554*G0_1_1_6_0_1 - 3.97460317460315*G0_1_1_7_0_0 + 1.14285714285714*G0_1_1_7_0_1 + 1.39682539682539*G0_1_1_8_0_0 - 0.457142857142853*G0_1_1_8_0_1 - 0.838095238095236*G0_1_1_9_0_0 - 1.18095238095238*G0_1_1_9_0_1 + 2.80423280423279*G0_1_1_10_1_0 + 2.80423280423279*G0_1_1_10_1_1 - 0.226455026455026*G0_1_1_11_1_0 - 0.620105820105817*G0_1_1_12_1_1 + 0.260317460317461*G0_1_1_13_1_0 + 0.457142857142852*G0_1_1_13_1_1 - 0.158730158730157*G0_1_1_14_1_0 + 0.0380952380952406*G0_1_1_14_1_1 + 0.577777777777776*G0_1_1_15_1_0 - 4.53968253968252*G0_1_1_15_1_1 + 0.158730158730157*G0_1_1_16_1_0 + 2.35555555555554*G0_1_1_16_1_1 - 3.97460317460315*G0_1_1_17_1_0 + 1.14285714285714*G0_1_1_17_1_1 + 1.39682539682539*G0_1_1_18_1_0 - 0.457142857142853*G0_1_1_18_1_1 - 0.838095238095236*G0_1_1_19_1_0 - 1.18095238095238*G0_1_1_19_1_1; + A[338] = A[803]; + A[19] = 0.0; + A[379] = 0.0; + A[48] = 0.0; + A[763] = 0.0; + A[456] = 0.0; + A[408] = 0.0; + A[85] = 0.0; + A[790] = 0.0; + A[9] = A[474]; + A[813] = 0.0; + A[127] = A[679] + 0.0304761904761941*G0_0_1_0_0_0 + 0.0304761904761939*G0_0_1_0_0_1 - 0.0304761904761943*G0_0_1_1_0_0 - 0.133333333333332*G0_0_1_2_0_1 + 0.133333333333325*G0_0_1_3_0_0 - 0.0780952380952467*G0_0_1_3_0_1 - 0.0380952380952372*G0_0_1_4_0_0 + 0.276190476190472*G0_0_1_4_0_1 - 0.133333333333331*G0_0_1_5_0_0 - 0.211428571428574*G0_0_1_5_0_1 + 0.0380952380952371*G0_0_1_6_0_0 + 0.314285714285713*G0_0_1_6_0_1 + 0.13714285714285*G0_0_1_7_0_0 + 0.215238095238093*G0_0_1_7_0_1 - 0.13714285714285*G0_0_1_8_0_0 + 0.0780952380952466*G0_0_1_8_0_1 - 0.491428571428565*G0_0_1_9_0_1 + 0.0304761904761941*G0_0_1_10_1_0 + 0.0304761904761939*G0_0_1_10_1_1 - 0.0304761904761943*G0_0_1_11_1_0 - 0.133333333333332*G0_0_1_12_1_1 + 0.133333333333325*G0_0_1_13_1_0 - 0.0780952380952467*G0_0_1_13_1_1 - 0.0380952380952372*G0_0_1_14_1_0 + 0.276190476190472*G0_0_1_14_1_1 - 0.133333333333331*G0_0_1_15_1_0 - 0.211428571428574*G0_0_1_15_1_1 + 0.0380952380952371*G0_0_1_16_1_0 + 0.314285714285713*G0_0_1_16_1_1 + 0.13714285714285*G0_0_1_17_1_0 + 0.215238095238093*G0_0_1_17_1_1 - 0.13714285714285*G0_0_1_18_1_0 + 0.0780952380952466*G0_0_1_18_1_1 - 0.491428571428565*G0_0_1_19_1_1 - 0.0304761904761942*G0_1_0_0_0_0 - 0.030476190476194*G0_1_0_0_0_1 + 0.0304761904761943*G0_1_0_1_0_0 + 0.133333333333333*G0_1_0_2_0_1 - 0.133333333333325*G0_1_0_3_0_0 + 0.0780952380952467*G0_1_0_3_0_1 + 0.0380952380952373*G0_1_0_4_0_0 - 0.276190476190472*G0_1_0_4_0_1 + 0.133333333333331*G0_1_0_5_0_0 + 0.211428571428574*G0_1_0_5_0_1 - 0.0380952380952374*G0_1_0_6_0_0 - 0.314285714285713*G0_1_0_6_0_1 - 0.13714285714285*G0_1_0_7_0_0 - 0.215238095238093*G0_1_0_7_0_1 + 0.13714285714285*G0_1_0_8_0_0 - 0.0780952380952465*G0_1_0_8_0_1 + 0.491428571428565*G0_1_0_9_0_1 - 0.0304761904761942*G0_1_0_10_1_0 - 0.030476190476194*G0_1_0_10_1_1 + 0.0304761904761943*G0_1_0_11_1_0 + 0.133333333333333*G0_1_0_12_1_1 - 0.133333333333325*G0_1_0_13_1_0 + 0.0780952380952467*G0_1_0_13_1_1 + 0.0380952380952373*G0_1_0_14_1_0 - 0.276190476190472*G0_1_0_14_1_1 + 0.133333333333331*G0_1_0_15_1_0 + 0.211428571428574*G0_1_0_15_1_1 - 0.0380952380952374*G0_1_0_16_1_0 - 0.314285714285713*G0_1_0_16_1_1 - 0.13714285714285*G0_1_0_17_1_0 - 0.215238095238093*G0_1_0_17_1_1 + 0.13714285714285*G0_1_0_18_1_0 - 0.0780952380952465*G0_1_0_18_1_1 + 0.491428571428565*G0_1_0_19_1_1; + A[844] = 0.0; + A[879] = 0.0; + A[482] = 0.0; + A[201] = 0.0; + A[513] = 0.0; + A[226] = 0.0; + A[608] = 0.0; + A[548] = 0.0; + A[643] = 0.0; + A[662] = 0.0; + A[285] = 0.0; + A[701] = 0.0; + A[260] = 0.0; + A[331] = 0.480423280423279*G0_0_0_0_0_0 + 0.480423280423278*G0_0_0_0_0_1 - 2.02962962962962*G0_0_0_1_0_0 - 0.283597883597882*G0_0_0_2_0_1 - 0.577777777777774*G0_0_0_3_0_0 - 3.56507936507935*G0_0_0_3_0_1 + 0.0507936507936514*G0_0_0_4_0_0 + 1.29206349206349*G0_0_0_4_0_1 + 0.158730158730159*G0_0_0_5_0_0 - 0.098412698412698*G0_0_0_5_0_1 - 0.0507936507936515*G0_0_0_6_0_0 - 0.0984126984126976*G0_0_0_6_0_1 - 1.72063492063491*G0_0_0_7_0_0 - 1.46349206349205*G0_0_0_7_0_1 + 3.26984126984125*G0_0_0_8_0_0 + 3.56507936507935*G0_0_0_8_0_1 + 0.419047619047615*G0_0_0_9_0_0 + 0.171428571428567*G0_0_0_9_0_1 + 0.480423280423279*G0_0_0_10_1_0 + 0.480423280423278*G0_0_0_10_1_1 - 2.02962962962962*G0_0_0_11_1_0 - 0.283597883597882*G0_0_0_12_1_1 - 0.577777777777774*G0_0_0_13_1_0 - 3.56507936507935*G0_0_0_13_1_1 + 0.0507936507936514*G0_0_0_14_1_0 + 1.29206349206349*G0_0_0_14_1_1 + 0.158730158730159*G0_0_0_15_1_0 - 0.098412698412698*G0_0_0_15_1_1 - 0.0507936507936515*G0_0_0_16_1_0 - 0.0984126984126976*G0_0_0_16_1_1 - 1.72063492063491*G0_0_0_17_1_0 - 1.46349206349205*G0_0_0_17_1_1 + 3.26984126984125*G0_0_0_18_1_0 + 3.56507936507935*G0_0_0_18_1_1 + 0.419047619047615*G0_0_0_19_1_0 + 0.171428571428567*G0_0_0_19_1_1 + 0.423280423280422*G0_1_0_0_0_0 + 0.423280423280421*G0_1_0_0_0_1 - 2.80423280423279*G0_1_0_1_0_0 - 0.423280423280421*G0_1_0_2_0_1 - 0.860317460317454*G0_1_0_3_0_0 - 5.11746031746029*G0_1_0_3_0_1 + 0.149206349206349*G0_1_0_4_0_0 + 2.02539682539681*G0_1_0_4_0_1 - 0.149206349206346*G0_1_0_5_0_0 - 0.14920634920635*G0_1_0_6_0_0 - 1.87619047619047*G0_1_0_7_0_0 - 2.02539682539681*G0_1_0_7_0_1 + 4.25714285714283*G0_1_0_8_0_0 + 5.11746031746029*G0_1_0_8_0_1 + 1.0095238095238*G0_1_0_9_0_0 + 0.423280423280422*G0_1_0_10_1_0 + 0.423280423280421*G0_1_0_10_1_1 - 2.80423280423279*G0_1_0_11_1_0 - 0.423280423280421*G0_1_0_12_1_1 - 0.860317460317454*G0_1_0_13_1_0 - 5.11746031746029*G0_1_0_13_1_1 + 0.149206349206349*G0_1_0_14_1_0 + 2.02539682539681*G0_1_0_14_1_1 - 0.149206349206346*G0_1_0_15_1_0 - 0.14920634920635*G0_1_0_16_1_0 - 1.87619047619047*G0_1_0_17_1_0 - 2.02539682539681*G0_1_0_17_1_1 + 4.25714285714283*G0_1_0_18_1_0 + 5.11746031746029*G0_1_0_18_1_1 + 1.0095238095238*G0_1_0_19_1_0; + A[287] = 0.0; + A[743] = A[803] + 0.0609523809523808*G0_0_0_0_0_0 + 0.0609523809523807*G0_0_0_0_0_1 - 0.0609523809523802*G0_0_0_1_0_0 - 0.0609523809523791*G0_0_0_3_0_1 - 0.0609523809523822*G0_0_0_5_0_1 - 0.18285714285714*G0_0_0_7_0_0 - 0.121904761904759*G0_0_0_7_0_1 + 0.18285714285714*G0_0_0_8_0_0 + 0.0609523809523792*G0_0_0_8_0_1 + 0.12190476190476*G0_0_0_9_0_1 + 0.0609523809523808*G0_0_0_10_1_0 + 0.0609523809523807*G0_0_0_10_1_1 - 0.0609523809523802*G0_0_0_11_1_0 - 0.0609523809523791*G0_0_0_13_1_1 - 0.0609523809523822*G0_0_0_15_1_1 - 0.18285714285714*G0_0_0_17_1_0 - 0.121904761904759*G0_0_0_17_1_1 + 0.18285714285714*G0_0_0_18_1_0 + 0.0609523809523792*G0_0_0_18_1_1 + 0.12190476190476*G0_0_0_19_1_1 - 0.629841269841267*G0_0_1_0_0_0 - 0.629841269841267*G0_0_1_0_0_1 - 0.0203174603174587*G0_0_1_1_0_0 + 0.243809523809524*G0_0_1_3_0_0 - 0.223492063492059*G0_0_1_3_0_1 + 0.446984126984123*G0_0_1_4_0_1 + 0.243809523809522*G0_0_1_5_0_0 + 1.07682539682539*G0_0_1_5_0_1 - 0.446984126984123*G0_0_1_6_0_1 + 1.23936507936507*G0_0_1_7_0_0 + 0.406349206349205*G0_0_1_7_0_1 - 0.589206349206348*G0_0_1_8_0_0 + 0.223492063492058*G0_0_1_8_0_1 - 0.487619047619046*G0_0_1_9_0_0 - 0.853333333333328*G0_0_1_9_0_1 - 0.629841269841267*G0_0_1_10_1_0 - 0.629841269841267*G0_0_1_10_1_1 - 0.0203174603174587*G0_0_1_11_1_0 + 0.243809523809524*G0_0_1_13_1_0 - 0.223492063492059*G0_0_1_13_1_1 + 0.446984126984123*G0_0_1_14_1_1 + 0.243809523809522*G0_0_1_15_1_0 + 1.07682539682539*G0_0_1_15_1_1 - 0.446984126984123*G0_0_1_16_1_1 + 1.23936507936507*G0_0_1_17_1_0 + 0.406349206349205*G0_0_1_17_1_1 - 0.589206349206348*G0_0_1_18_1_0 + 0.223492063492058*G0_0_1_18_1_1 - 0.487619047619046*G0_0_1_19_1_0 - 0.853333333333328*G0_0_1_19_1_1 - 0.101587301587301*G0_1_0_0_0_0 - 0.101587301587301*G0_1_0_0_0_1 - 0.16253968253968*G0_1_0_1_0_0 + 0.0609523809523822*G0_1_0_3_0_0 - 0.264126984126979*G0_1_0_3_0_1 + 0.162539682539681*G0_1_0_4_0_1 + 0.0609523809523807*G0_1_0_5_0_0 + 0.264126984126982*G0_1_0_5_0_1 - 0.162539682539681*G0_1_0_6_0_1 + 0.040634920634921*G0_1_0_7_0_0 - 0.16253968253968*G0_1_0_7_0_1 + 0.22349206349206*G0_1_0_8_0_0 + 0.264126984126979*G0_1_0_8_0_1 - 0.121904761904763*G0_1_0_9_0_0 - 0.101587301587301*G0_1_0_10_1_0 - 0.101587301587301*G0_1_0_10_1_1 - 0.16253968253968*G0_1_0_11_1_0 + 0.0609523809523822*G0_1_0_13_1_0 - 0.264126984126979*G0_1_0_13_1_1 + 0.162539682539681*G0_1_0_14_1_1 + 0.0609523809523807*G0_1_0_15_1_0 + 0.264126984126982*G0_1_0_15_1_1 - 0.162539682539681*G0_1_0_16_1_1 + 0.040634920634921*G0_1_0_17_1_0 - 0.16253968253968*G0_1_0_17_1_1 + 0.22349206349206*G0_1_0_18_1_0 + 0.264126984126979*G0_1_0_18_1_1 - 0.121904761904763*G0_1_0_19_1_0 + 0.602751322751318*G0_1_1_0_0_0 + 0.602751322751319*G0_1_1_0_0_1 + 0.0880423280423308*G0_1_1_1_0_0 - 0.196402116402115*G0_1_1_2_0_1 - 0.12190476190476*G0_1_1_3_0_0 + 0.020317460317465*G0_1_1_3_0_1 + 0.243809523809523*G0_1_1_4_0_0 + 0.386031746031743*G0_1_1_4_0_1 - 0.243809523809524*G0_1_1_5_0_0 - 1.42222222222221*G0_1_1_5_0_1 - 0.243809523809523*G0_1_1_6_0_0 + 1.01587301587301*G0_1_1_6_0_1 - 0.345396825396821*G0_1_1_7_0_0 + 0.83301587301587*G0_1_1_7_0_1 - 0.345396825396829*G0_1_1_8_0_0 - 0.020317460317465*G0_1_1_8_0_1 + 0.365714285714284*G0_1_1_9_0_0 - 1.21904761904761*G0_1_1_9_0_1 + 0.602751322751318*G0_1_1_10_1_0 + 0.602751322751319*G0_1_1_10_1_1 + 0.0880423280423308*G0_1_1_11_1_0 - 0.196402116402115*G0_1_1_12_1_1 - 0.12190476190476*G0_1_1_13_1_0 + 0.020317460317465*G0_1_1_13_1_1 + 0.243809523809523*G0_1_1_14_1_0 + 0.386031746031743*G0_1_1_14_1_1 - 0.243809523809524*G0_1_1_15_1_0 - 1.42222222222221*G0_1_1_15_1_1 - 0.243809523809523*G0_1_1_16_1_0 + 1.01587301587301*G0_1_1_16_1_1 - 0.345396825396821*G0_1_1_17_1_0 + 0.83301587301587*G0_1_1_17_1_1 - 0.345396825396829*G0_1_1_18_1_0 - 0.020317460317465*G0_1_1_18_1_1 + 0.365714285714284*G0_1_1_19_1_0 - 1.21904761904761*G0_1_1_19_1_1; + A[322] = 0.0; + A[772] = A[307]; + A[465] = A[527] - 1.2329365079365*G0_0_0_0_0_0 - 1.2329365079365*G0_0_0_0_0_1 + 0.213888888888888*G0_0_0_1_0_0 + 0.213888888888888*G0_0_0_2_0_1 + 0.0115079365079355*G0_0_0_3_0_0 + 0.0115079365079371*G0_0_0_3_0_1 + 0.0115079365079357*G0_0_0_4_0_0 + 0.0115079365079352*G0_0_0_4_0_1 - 0.306746031746031*G0_0_0_5_0_0 + 1.89047619047618*G0_0_0_5_0_1 - 0.0115079365079358*G0_0_0_6_0_0 - 0.871428571428568*G0_0_0_6_0_1 + 1.89047619047618*G0_0_0_7_0_0 - 0.306746031746031*G0_0_0_7_0_1 - 0.871428571428567*G0_0_0_8_0_0 - 0.011507936507937*G0_0_0_8_0_1 + 0.295238095238095*G0_0_0_9_0_0 + 0.295238095238096*G0_0_0_9_0_1 - 1.2329365079365*G0_0_0_10_1_0 - 1.2329365079365*G0_0_0_10_1_1 + 0.213888888888888*G0_0_0_11_1_0 + 0.213888888888888*G0_0_0_12_1_1 + 0.0115079365079355*G0_0_0_13_1_0 + 0.0115079365079371*G0_0_0_13_1_1 + 0.0115079365079357*G0_0_0_14_1_0 + 0.0115079365079352*G0_0_0_14_1_1 - 0.306746031746031*G0_0_0_15_1_0 + 1.89047619047618*G0_0_0_15_1_1 - 0.0115079365079358*G0_0_0_16_1_0 - 0.871428571428568*G0_0_0_16_1_1 + 1.89047619047618*G0_0_0_17_1_0 - 0.306746031746031*G0_0_0_17_1_1 - 0.871428571428567*G0_0_0_18_1_0 - 0.011507936507937*G0_0_0_18_1_1 + 0.295238095238095*G0_0_0_19_1_0 + 0.295238095238096*G0_0_0_19_1_1 - 1.2329365079365*G0_0_1_0_0_0 - 1.2329365079365*G0_0_1_0_0_1 + 0.213888888888888*G0_0_1_1_0_0 + 0.213888888888888*G0_0_1_2_0_1 + 0.0115079365079353*G0_0_1_3_0_0 + 0.0115079365079369*G0_0_1_3_0_1 + 0.0115079365079362*G0_0_1_4_0_0 + 0.0115079365079353*G0_0_1_4_0_1 - 0.306746031746031*G0_0_1_5_0_0 + 1.89047619047618*G0_0_1_5_0_1 - 0.0115079365079362*G0_0_1_6_0_0 - 0.871428571428568*G0_0_1_6_0_1 + 1.89047619047618*G0_0_1_7_0_0 - 0.306746031746031*G0_0_1_7_0_1 - 0.871428571428567*G0_0_1_8_0_0 - 0.0115079365079369*G0_0_1_8_0_1 + 0.295238095238095*G0_0_1_9_0_0 + 0.295238095238096*G0_0_1_9_0_1 - 1.2329365079365*G0_0_1_10_1_0 - 1.2329365079365*G0_0_1_10_1_1 + 0.213888888888888*G0_0_1_11_1_0 + 0.213888888888888*G0_0_1_12_1_1 + 0.0115079365079353*G0_0_1_13_1_0 + 0.0115079365079369*G0_0_1_13_1_1 + 0.0115079365079362*G0_0_1_14_1_0 + 0.0115079365079353*G0_0_1_14_1_1 - 0.306746031746031*G0_0_1_15_1_0 + 1.89047619047618*G0_0_1_15_1_1 - 0.0115079365079362*G0_0_1_16_1_0 - 0.871428571428568*G0_0_1_16_1_1 + 1.89047619047618*G0_0_1_17_1_0 - 0.306746031746031*G0_0_1_17_1_1 - 0.871428571428567*G0_0_1_18_1_0 - 0.0115079365079369*G0_0_1_18_1_1 + 0.295238095238095*G0_0_1_19_1_0 + 0.295238095238096*G0_0_1_19_1_1 - 1.2329365079365*G0_1_0_0_0_0 - 1.2329365079365*G0_1_0_0_0_1 + 0.213888888888888*G0_1_0_1_0_0 + 0.213888888888888*G0_1_0_2_0_1 + 0.0115079365079353*G0_1_0_3_0_0 + 0.0115079365079369*G0_1_0_3_0_1 + 0.0115079365079362*G0_1_0_4_0_0 + 0.0115079365079353*G0_1_0_4_0_1 - 0.306746031746031*G0_1_0_5_0_0 + 1.89047619047618*G0_1_0_5_0_1 - 0.0115079365079362*G0_1_0_6_0_0 - 0.871428571428568*G0_1_0_6_0_1 + 1.89047619047618*G0_1_0_7_0_0 - 0.306746031746031*G0_1_0_7_0_1 - 0.871428571428567*G0_1_0_8_0_0 - 0.0115079365079369*G0_1_0_8_0_1 + 0.295238095238095*G0_1_0_9_0_0 + 0.295238095238096*G0_1_0_9_0_1 - 1.2329365079365*G0_1_0_10_1_0 - 1.2329365079365*G0_1_0_10_1_1 + 0.213888888888888*G0_1_0_11_1_0 + 0.213888888888888*G0_1_0_12_1_1 + 0.0115079365079353*G0_1_0_13_1_0 + 0.0115079365079369*G0_1_0_13_1_1 + 0.0115079365079362*G0_1_0_14_1_0 + 0.0115079365079353*G0_1_0_14_1_1 - 0.306746031746031*G0_1_0_15_1_0 + 1.89047619047618*G0_1_0_15_1_1 - 0.0115079365079362*G0_1_0_16_1_0 - 0.871428571428568*G0_1_0_16_1_1 + 1.89047619047618*G0_1_0_17_1_0 - 0.306746031746031*G0_1_0_17_1_1 - 0.871428571428567*G0_1_0_18_1_0 - 0.0115079365079369*G0_1_0_18_1_1 + 0.295238095238095*G0_1_0_19_1_0 + 0.295238095238096*G0_1_0_19_1_1 - 1.01904761904761*G0_1_1_0_0_0 - 1.01904761904762*G0_1_1_0_0_1 - 1.01904761904761*G0_1_1_2_0_1 + 0.871428571428565*G0_1_1_3_0_0 - 2.18571428571428*G0_1_1_4_0_0 - 0.295238095238095*G0_1_1_4_0_1 - 1.16666666666666*G0_1_1_5_0_0 + 1.01904761904762*G0_1_1_5_0_1 + 2.18571428571428*G0_1_1_6_0_0 + 1.01904761904761*G0_1_1_6_0_1 + 1.89047619047618*G0_1_1_7_0_0 - 0.295238095238095*G0_1_1_7_0_1 - 0.871428571428566*G0_1_1_8_0_0 + 0.295238095238096*G0_1_1_9_0_0 + 0.590476190476191*G0_1_1_9_0_1 - 1.01904761904761*G0_1_1_10_1_0 - 1.01904761904762*G0_1_1_10_1_1 - 1.01904761904761*G0_1_1_12_1_1 + 0.871428571428565*G0_1_1_13_1_0 - 2.18571428571428*G0_1_1_14_1_0 - 0.295238095238095*G0_1_1_14_1_1 - 1.16666666666666*G0_1_1_15_1_0 + 1.01904761904762*G0_1_1_15_1_1 + 2.18571428571428*G0_1_1_16_1_0 + 1.01904761904761*G0_1_1_16_1_1 + 1.89047619047618*G0_1_1_17_1_0 - 0.295238095238095*G0_1_1_17_1_1 - 0.871428571428566*G0_1_1_18_1_0 + 0.295238095238096*G0_1_1_19_1_0 + 0.590476190476191*G0_1_1_19_1_1; + A[76] = 0.0; + A[0] = A[465]; + A[43] = 0.125291005291005*G0_0_0_0_0_0 + 0.125291005291004*G0_0_0_0_0_1 - 0.973544973544968*G0_0_0_1_0_0 - 0.0237037037037031*G0_0_0_2_0_1 - 0.799999999999995*G0_0_0_3_0_0 - 2.06349206349205*G0_0_0_3_0_1 + 0.44190476190476*G0_0_0_4_0_0 + 0.755555555555551*G0_0_0_4_0_1 - 0.678095238095234*G0_0_0_5_0_0 - 0.306031746031744*G0_0_0_5_0_1 - 0.441904761904761*G0_0_0_6_0_0 + 0.204444444444443*G0_0_0_6_0_1 - 0.650158730158726*G0_0_0_7_0_0 - 1.02222222222222*G0_0_0_7_0_1 + 1.49841269841269*G0_0_0_8_0_0 + 2.06349206349205*G0_0_0_8_0_1 + 1.47809523809523*G0_0_0_9_0_0 + 0.266666666666663*G0_0_0_9_0_1 + 0.125291005291005*G0_0_0_10_1_0 + 0.125291005291004*G0_0_0_10_1_1 - 0.973544973544968*G0_0_0_11_1_0 - 0.0237037037037031*G0_0_0_12_1_1 - 0.799999999999995*G0_0_0_13_1_0 - 2.06349206349205*G0_0_0_13_1_1 + 0.44190476190476*G0_0_0_14_1_0 + 0.755555555555551*G0_0_0_14_1_1 - 0.678095238095234*G0_0_0_15_1_0 - 0.306031746031744*G0_0_0_15_1_1 - 0.441904761904761*G0_0_0_16_1_0 + 0.204444444444443*G0_0_0_16_1_1 - 0.650158730158726*G0_0_0_17_1_0 - 1.02222222222222*G0_0_0_17_1_1 + 1.49841269841269*G0_0_0_18_1_0 + 2.06349206349205*G0_0_0_18_1_1 + 1.47809523809523*G0_0_0_19_1_0 + 0.266666666666663*G0_0_0_19_1_1 + 0.101587301587301*G0_0_1_0_0_0 + 0.101587301587301*G0_0_1_0_0_1 + 0.101587301587301*G0_0_1_2_0_1 - 0.234920634920634*G0_0_1_3_0_0 + 0.0698412698412699*G0_0_1_4_0_0 - 0.266666666666664*G0_0_1_4_0_1 - 0.0317460317460319*G0_0_1_5_0_0 - 0.101587301587301*G0_0_1_5_0_1 - 0.0698412698412701*G0_0_1_6_0_0 - 0.101587301587301*G0_0_1_6_0_1 - 0.336507936507934*G0_0_1_7_0_0 - 0.266666666666665*G0_0_1_7_0_1 + 0.234920634920634*G0_0_1_8_0_0 + 0.266666666666666*G0_0_1_9_0_0 + 0.533333333333328*G0_0_1_9_0_1 + 0.101587301587301*G0_0_1_10_1_0 + 0.101587301587301*G0_0_1_10_1_1 + 0.101587301587301*G0_0_1_12_1_1 - 0.234920634920634*G0_0_1_13_1_0 + 0.0698412698412699*G0_0_1_14_1_0 - 0.266666666666664*G0_0_1_14_1_1 - 0.0317460317460319*G0_0_1_15_1_0 - 0.101587301587301*G0_0_1_15_1_1 - 0.0698412698412701*G0_0_1_16_1_0 - 0.101587301587301*G0_0_1_16_1_1 - 0.336507936507934*G0_0_1_17_1_0 - 0.266666666666665*G0_0_1_17_1_1 + 0.234920634920634*G0_0_1_18_1_0 + 0.266666666666666*G0_0_1_19_1_0 + 0.533333333333328*G0_0_1_19_1_1; + A[843] = 0.0; + A[70] = A[534] - 0.0885714285714282*G0_1_0_0_0_0 - 0.0885714285714282*G0_1_0_0_0_1 + 0.0409523809523797*G0_1_0_1_0_0 + 0.023809523809526*G0_1_0_3_0_0 + 0.0290476190476185*G0_1_0_3_0_1 + 0.0357142857142856*G0_1_0_4_0_1 + 0.0238095238095217*G0_1_0_5_0_0 + 0.124285714285713*G0_1_0_5_0_1 - 0.0357142857142824*G0_1_0_6_0_1 + 0.218095238095237*G0_1_0_7_0_0 + 0.117619047619046*G0_1_0_7_0_1 - 0.170476190476188*G0_1_0_8_0_0 - 0.0290476190476185*G0_1_0_8_0_1 - 0.0476190476190476*G0_1_0_9_0_0 - 0.153333333333331*G0_1_0_9_0_1 - 0.0885714285714282*G0_1_0_10_1_0 - 0.0885714285714282*G0_1_0_10_1_1 + 0.0409523809523797*G0_1_0_11_1_0 + 0.023809523809526*G0_1_0_13_1_0 + 0.0290476190476185*G0_1_0_13_1_1 + 0.0357142857142856*G0_1_0_14_1_1 + 0.0238095238095217*G0_1_0_15_1_0 + 0.124285714285713*G0_1_0_15_1_1 - 0.0357142857142824*G0_1_0_16_1_1 + 0.218095238095237*G0_1_0_17_1_0 + 0.117619047619046*G0_1_0_17_1_1 - 0.170476190476188*G0_1_0_18_1_0 - 0.0290476190476185*G0_1_0_18_1_1 - 0.0476190476190476*G0_1_0_19_1_0 - 0.153333333333331*G0_1_0_19_1_1 + 0.162539682539682*G0_1_1_0_0_0 + 0.162539682539682*G0_1_1_0_0_1 + 0.00539682539682466*G0_1_1_1_0_0 - 0.0147619047619037*G0_1_1_3_0_0 + 0.0641269841269832*G0_1_1_3_0_1 + 0.0357142857142854*G0_1_1_4_0_0 - 0.0377777777777767*G0_1_1_4_0_1 - 0.0147619047619046*G0_1_1_5_0_0 - 0.27174603174603*G0_1_1_5_0_1 - 0.0357142857142854*G0_1_1_6_0_0 + 0.109206349206349*G0_1_1_6_0_1 - 0.283968253968253*G0_1_1_7_0_0 - 0.0269841269841277*G0_1_1_7_0_1 + 0.116031746031747*G0_1_1_8_0_0 - 0.0641269841269832*G0_1_1_8_0_1 + 0.0295238095238083*G0_1_1_9_0_0 + 0.0647619047619042*G0_1_1_9_0_1 + 0.162539682539682*G0_1_1_10_1_0 + 0.162539682539682*G0_1_1_10_1_1 + 0.00539682539682466*G0_1_1_11_1_0 - 0.0147619047619037*G0_1_1_13_1_0 + 0.0641269841269832*G0_1_1_13_1_1 + 0.0357142857142854*G0_1_1_14_1_0 - 0.0377777777777767*G0_1_1_14_1_1 - 0.0147619047619046*G0_1_1_15_1_0 - 0.27174603174603*G0_1_1_15_1_1 - 0.0357142857142854*G0_1_1_16_1_0 + 0.109206349206349*G0_1_1_16_1_1 - 0.283968253968253*G0_1_1_17_1_0 - 0.0269841269841277*G0_1_1_17_1_1 + 0.116031746031747*G0_1_1_18_1_0 - 0.0641269841269832*G0_1_1_18_1_1 + 0.0295238095238083*G0_1_1_19_1_0 + 0.0647619047619042*G0_1_1_19_1_1; + A[165] = 0.0; + A[872] = 0.0; + A[109] = 0.0; + A[140] = 0.0; + A[514] = 0.0; + A[623] = A[245] + 0.406349206349206*G0_0_1_0_0_0 + 0.406349206349206*G0_0_1_0_0_1 - 0.406349206349206*G0_0_1_1_0_0 - 1.93015873015872*G0_0_1_2_0_1 + 1.93015873015872*G0_0_1_3_0_0 - 0.0507936507936546*G0_0_1_3_0_1 - 2.64126984126983*G0_0_1_4_0_0 + 0.86349206349206*G0_0_1_4_0_1 - 1.93015873015872*G0_0_1_5_0_0 - 1.98095238095238*G0_0_1_5_0_1 + 2.64126984126983*G0_0_1_6_0_0 + 3.50476190476189*G0_0_1_6_0_1 + 0.05079365079365*G0_0_1_7_0_1 + 0.0507936507936544*G0_0_1_8_0_1 - 0.91428571428571*G0_0_1_9_0_1 + 0.406349206349206*G0_0_1_10_1_0 + 0.406349206349206*G0_0_1_10_1_1 - 0.406349206349206*G0_0_1_11_1_0 - 1.93015873015872*G0_0_1_12_1_1 + 1.93015873015872*G0_0_1_13_1_0 - 0.0507936507936546*G0_0_1_13_1_1 - 2.64126984126983*G0_0_1_14_1_0 + 0.86349206349206*G0_0_1_14_1_1 - 1.93015873015872*G0_0_1_15_1_0 - 1.98095238095238*G0_0_1_15_1_1 + 2.64126984126983*G0_0_1_16_1_0 + 3.50476190476189*G0_0_1_16_1_1 + 0.05079365079365*G0_0_1_17_1_1 + 0.0507936507936544*G0_0_1_18_1_1 - 0.91428571428571*G0_0_1_19_1_1 - 0.406349206349206*G0_1_0_0_0_0 - 0.406349206349206*G0_1_0_0_0_1 + 0.406349206349206*G0_1_0_1_0_0 + 1.93015873015872*G0_1_0_2_0_1 - 1.93015873015872*G0_1_0_3_0_0 + 0.0507936507936546*G0_1_0_3_0_1 + 2.64126984126983*G0_1_0_4_0_0 - 0.86349206349206*G0_1_0_4_0_1 + 1.93015873015872*G0_1_0_5_0_0 + 1.98095238095238*G0_1_0_5_0_1 - 2.64126984126983*G0_1_0_6_0_0 - 3.50476190476189*G0_1_0_6_0_1 - 0.0507936507936499*G0_1_0_7_0_1 - 0.0507936507936544*G0_1_0_8_0_1 + 0.91428571428571*G0_1_0_9_0_1 - 0.406349206349206*G0_1_0_10_1_0 - 0.406349206349206*G0_1_0_10_1_1 + 0.406349206349206*G0_1_0_11_1_0 + 1.93015873015872*G0_1_0_12_1_1 - 1.93015873015872*G0_1_0_13_1_0 + 0.0507936507936546*G0_1_0_13_1_1 + 2.64126984126983*G0_1_0_14_1_0 - 0.86349206349206*G0_1_0_14_1_1 + 1.93015873015872*G0_1_0_15_1_0 + 1.98095238095238*G0_1_0_15_1_1 - 2.64126984126983*G0_1_0_16_1_0 - 3.50476190476189*G0_1_0_16_1_1 - 0.0507936507936499*G0_1_0_17_1_1 - 0.0507936507936544*G0_1_0_18_1_1 + 0.91428571428571*G0_1_0_19_1_1; + A[741] = A[623] + 0.372486772486767*G0_0_0_0_0_0 + 0.372486772486768*G0_0_0_0_0_1 + 0.582433862433863*G0_0_0_1_0_0 + 6.77925925925922*G0_0_0_2_0_1 - 3.83999999999997*G0_0_0_3_0_0 - 0.111746031746025*G0_0_0_3_0_1 + 13.0438095238095*G0_0_0_4_0_0 + 3.11873015873015*G0_0_0_4_0_1 + 5.79047619047616*G0_0_0_5_0_0 + 2.79365079365078*G0_0_0_5_0_1 - 13.0438095238095*G0_0_0_6_0_0 - 9.94539682539677*G0_0_0_6_0_1 - 2.64126984126982*G0_0_0_7_0_0 + 0.355555555555557*G0_0_0_7_0_1 + 1.68634920634919*G0_0_0_8_0_0 + 0.111746031746025*G0_0_0_8_0_1 - 1.95047619047618*G0_0_0_9_0_0 - 3.4742857142857*G0_0_0_9_0_1 + 0.372486772486767*G0_0_0_10_1_0 + 0.372486772486768*G0_0_0_10_1_1 + 0.582433862433863*G0_0_0_11_1_0 + 6.77925925925922*G0_0_0_12_1_1 - 3.83999999999997*G0_0_0_13_1_0 - 0.111746031746025*G0_0_0_13_1_1 + 13.0438095238095*G0_0_0_14_1_0 + 3.11873015873015*G0_0_0_14_1_1 + 5.79047619047616*G0_0_0_15_1_0 + 2.79365079365078*G0_0_0_15_1_1 - 13.0438095238095*G0_0_0_16_1_0 - 9.94539682539677*G0_0_0_16_1_1 - 2.64126984126982*G0_0_0_17_1_0 + 0.355555555555557*G0_0_0_17_1_1 + 1.68634920634919*G0_0_0_18_1_0 + 0.111746031746025*G0_0_0_18_1_1 - 1.95047619047618*G0_0_0_19_1_0 - 3.4742857142857*G0_0_0_19_1_1 - 3.89417989417988*G0_0_1_0_0_0 - 3.89417989417988*G0_0_1_0_0_1 + 0.988783068783065*G0_0_1_1_0_0 + 4.8491005291005*G0_0_1_2_0_1 - 2.06222222222221*G0_0_1_3_0_0 - 0.0609523809523755*G0_0_1_3_0_1 + 7.81206349206345*G0_0_1_4_0_0 + 1.95047619047618*G0_0_1_4_0_1 + 3.70793650793649*G0_0_1_5_0_0 + 8.6349206349206*G0_0_1_5_0_1 - 7.81206349206345*G0_0_1_6_0_0 - 9.58984126984122*G0_0_1_6_0_1 + 4.92698412698411*G0_0_1_7_0_0 - 2.02158730158729*G0_0_1_8_0_0 + 0.060952380952376*G0_0_1_8_0_1 - 1.64571428571428*G0_0_1_9_0_0 - 1.95047619047617*G0_0_1_9_0_1 - 3.89417989417988*G0_0_1_10_1_0 - 3.89417989417988*G0_0_1_10_1_1 + 0.988783068783065*G0_0_1_11_1_0 + 4.8491005291005*G0_0_1_12_1_1 - 2.06222222222221*G0_0_1_13_1_0 - 0.0609523809523755*G0_0_1_13_1_1 + 7.81206349206345*G0_0_1_14_1_0 + 1.95047619047618*G0_0_1_14_1_1 + 3.70793650793649*G0_0_1_15_1_0 + 8.6349206349206*G0_0_1_15_1_1 - 7.81206349206345*G0_0_1_16_1_0 - 9.58984126984122*G0_0_1_16_1_1 + 4.92698412698411*G0_0_1_17_1_0 - 2.02158730158729*G0_0_1_18_1_0 + 0.060952380952376*G0_0_1_18_1_1 - 1.64571428571428*G0_0_1_19_1_0 - 1.95047619047617*G0_0_1_19_1_1 - 1.55767195767195*G0_1_0_0_0_0 - 1.55767195767195*G0_1_0_0_0_1 + 0.176084656084656*G0_1_0_1_0_0 + 2.51259259259258*G0_1_0_2_0_1 - 0.182857142857141*G0_1_0_3_0_0 - 0.16253968253968*G0_1_0_3_0_1 + 5.11999999999997*G0_1_0_4_0_0 + 2.76317460317459*G0_1_0_4_0_1 + 0.914285714285705*G0_1_0_5_0_0 + 3.14920634920633*G0_1_0_5_0_1 - 5.11999999999997*G0_1_0_6_0_0 - 4.10412698412696*G0_1_0_6_0_1 + 1.42222222222221*G0_1_0_7_0_0 - 0.812698412698407*G0_1_0_7_0_1 - 0.0406349206349228*G0_1_0_8_0_0 + 0.162539682539681*G0_1_0_8_0_1 - 0.731428571428563*G0_1_0_9_0_0 - 1.95047619047619*G0_1_0_9_0_1 - 1.55767195767195*G0_1_0_10_1_0 - 1.55767195767195*G0_1_0_10_1_1 + 0.176084656084656*G0_1_0_11_1_0 + 2.51259259259258*G0_1_0_12_1_1 - 0.182857142857141*G0_1_0_13_1_0 - 0.16253968253968*G0_1_0_13_1_1 + 5.11999999999997*G0_1_0_14_1_0 + 2.76317460317459*G0_1_0_14_1_1 + 0.914285714285705*G0_1_0_15_1_0 + 3.14920634920633*G0_1_0_15_1_1 - 5.11999999999997*G0_1_0_16_1_0 - 4.10412698412696*G0_1_0_16_1_1 + 1.42222222222221*G0_1_0_17_1_0 - 0.812698412698407*G0_1_0_17_1_1 - 0.0406349206349228*G0_1_0_18_1_0 + 0.162539682539681*G0_1_0_18_1_1 - 0.731428571428563*G0_1_0_19_1_0 - 1.95047619047619*G0_1_0_19_1_1 + 0.954920634920628*G0_1_1_0_0_0 + 0.954920634920628*G0_1_1_0_0_1 + 0.954920634920629*G0_1_1_2_0_1 + 0.0203174603174615*G0_1_1_3_0_0 + 2.88507936507935*G0_1_1_4_0_0 + 1.95047619047618*G0_1_1_4_0_1 + 1.93015873015872*G0_1_1_5_0_0 - 0.954920634920627*G0_1_1_5_0_1 - 2.88507936507935*G0_1_1_6_0_0 - 0.954920634920629*G0_1_1_6_0_1 - 0.934603174603167*G0_1_1_7_0_0 + 1.95047619047618*G0_1_1_7_0_1 - 0.0203174603174613*G0_1_1_8_0_0 - 1.95047619047618*G0_1_1_9_0_0 - 3.90095238095236*G0_1_1_9_0_1 + 0.954920634920628*G0_1_1_10_1_0 + 0.954920634920628*G0_1_1_10_1_1 + 0.954920634920629*G0_1_1_12_1_1 + 0.0203174603174615*G0_1_1_13_1_0 + 2.88507936507935*G0_1_1_14_1_0 + 1.95047619047618*G0_1_1_14_1_1 + 1.93015873015872*G0_1_1_15_1_0 - 0.954920634920627*G0_1_1_15_1_1 - 2.88507936507935*G0_1_1_16_1_0 - 0.954920634920629*G0_1_1_16_1_1 - 0.934603174603167*G0_1_1_17_1_0 + 1.95047619047618*G0_1_1_17_1_1 - 0.0203174603174613*G0_1_1_18_1_0 - 1.95047619047618*G0_1_1_19_1_0 - 3.90095238095236*G0_1_1_19_1_1; + A[276] = A[741]; + A[543] = 0.0; + A[665] = 0.0; + A[690] = 0.0; + A[267] = 0.0; + A[296] = 0.0; + A[437] = 0.0; + A[361] = A[421] + 0.228571428571427*G0_0_0_0_0_0 + 0.228571428571427*G0_0_0_0_0_1 + 0.350476190476188*G0_0_0_2_0_1 - 0.274285714285712*G0_0_0_3_0_0 + 0.65523809523809*G0_0_0_4_0_0 + 0.0304761904761884*G0_0_0_4_0_1 + 0.426666666666663*G0_0_0_5_0_0 - 0.106666666666667*G0_0_0_5_0_1 - 0.65523809523809*G0_0_0_6_0_0 - 0.472380952380948*G0_0_0_6_0_1 - 0.50285714285714*G0_0_0_7_0_0 + 0.0304761904761907*G0_0_0_7_0_1 + 0.274285714285711*G0_0_0_8_0_0 - 0.15238095238095*G0_0_0_9_0_0 - 0.0609523809523787*G0_0_0_9_0_1 + 0.228571428571427*G0_0_0_10_1_0 + 0.228571428571427*G0_0_0_10_1_1 + 0.350476190476188*G0_0_0_12_1_1 - 0.274285714285712*G0_0_0_13_1_0 + 0.65523809523809*G0_0_0_14_1_0 + 0.0304761904761884*G0_0_0_14_1_1 + 0.426666666666663*G0_0_0_15_1_0 - 0.106666666666667*G0_0_0_15_1_1 - 0.65523809523809*G0_0_0_16_1_0 - 0.472380952380948*G0_0_0_16_1_1 - 0.50285714285714*G0_0_0_17_1_0 + 0.0304761904761907*G0_0_0_17_1_1 + 0.274285714285711*G0_0_0_18_1_0 - 0.15238095238095*G0_0_0_19_1_0 - 0.0609523809523787*G0_0_0_19_1_1 - 0.12190476190476*G0_1_0_0_0_0 - 0.121904761904761*G0_1_0_0_0_1 + 0.121904761904761*G0_1_0_2_0_1 + 0.12190476190476*G0_1_0_4_0_0 + 0.243809523809522*G0_1_0_5_0_0 + 0.365714285714282*G0_1_0_5_0_1 - 0.12190476190476*G0_1_0_6_0_0 - 0.365714285714282*G0_1_0_6_0_1 + 0.121904761904761*G0_1_0_7_0_0 - 0.243809523809523*G0_1_0_9_0_0 - 0.12190476190476*G0_1_0_10_1_0 - 0.121904761904761*G0_1_0_10_1_1 + 0.121904761904761*G0_1_0_12_1_1 + 0.12190476190476*G0_1_0_14_1_0 + 0.243809523809522*G0_1_0_15_1_0 + 0.365714285714282*G0_1_0_15_1_1 - 0.12190476190476*G0_1_0_16_1_0 - 0.365714285714282*G0_1_0_16_1_1 + 0.121904761904761*G0_1_0_17_1_0 - 0.243809523809523*G0_1_0_19_1_0; + A[317] = 0.0; + A[358] = 0.0; + A[7] = A[765] + 1.47777777777777*G0_0_0_0_0_0 + 1.47777777777777*G0_0_0_0_0_1 - 0.592063492063489*G0_0_0_1_0_0 + 0.14126984126984*G0_0_0_2_0_1 - 0.228571428571426*G0_0_0_3_0_0 - 0.595238095238092*G0_0_0_3_0_1 + 0.733333333333331*G0_0_0_4_0_0 + 0.366666666666666*G0_0_0_4_0_1 + 0.904761904761902*G0_0_0_5_0_0 - 1.8*G0_0_0_5_0_1 - 0.733333333333331*G0_0_0_6_0_0 + 0.180952380952383*G0_0_0_6_0_1 - 2.67142857142856*G0_0_0_7_0_0 + 0.0333333333333346*G0_0_0_7_0_1 + 1.78571428571428*G0_0_0_8_0_0 + 0.595238095238093*G0_0_0_8_0_1 - 0.676190476190476*G0_0_0_9_0_0 - 0.400000000000002*G0_0_0_9_0_1 + 1.47777777777777*G0_0_0_10_1_0 + 1.47777777777777*G0_0_0_10_1_1 - 0.592063492063489*G0_0_0_11_1_0 + 0.14126984126984*G0_0_0_12_1_1 - 0.228571428571426*G0_0_0_13_1_0 - 0.595238095238092*G0_0_0_13_1_1 + 0.733333333333331*G0_0_0_14_1_0 + 0.366666666666666*G0_0_0_14_1_1 + 0.904761904761902*G0_0_0_15_1_0 - 1.8*G0_0_0_15_1_1 - 0.733333333333331*G0_0_0_16_1_0 + 0.180952380952383*G0_0_0_16_1_1 - 2.67142857142856*G0_0_0_17_1_0 + 0.0333333333333346*G0_0_0_17_1_1 + 1.78571428571428*G0_0_0_18_1_0 + 0.595238095238093*G0_0_0_18_1_1 - 0.676190476190476*G0_0_0_19_1_0 - 0.400000000000002*G0_0_0_19_1_1 - 0.417460317460315*G0_0_1_1_0_0 + 0.417460317460315*G0_0_1_2_0_1 - 0.281746031746029*G0_0_1_3_0_0 - 0.699206349206344*G0_0_1_3_0_1 + 0.699206349206346*G0_0_1_4_0_0 + 0.28174603174603*G0_0_1_4_0_1 + 0.553174603174601*G0_0_1_5_0_0 + 0.553174603174595*G0_0_1_5_0_1 - 0.699206349206346*G0_0_1_6_0_0 - 0.970634920634914*G0_0_1_6_0_1 - 0.553174603174605*G0_0_1_7_0_0 - 0.553174603174599*G0_0_1_7_0_1 + 0.970634920634917*G0_0_1_8_0_0 + 0.699206349206344*G0_0_1_8_0_1 - 0.271428571428571*G0_0_1_9_0_0 + 0.271428571428569*G0_0_1_9_0_1 - 0.417460317460315*G0_0_1_11_1_0 + 0.417460317460315*G0_0_1_12_1_1 - 0.281746031746029*G0_0_1_13_1_0 - 0.699206349206344*G0_0_1_13_1_1 + 0.699206349206346*G0_0_1_14_1_0 + 0.28174603174603*G0_0_1_14_1_1 + 0.553174603174601*G0_0_1_15_1_0 + 0.553174603174595*G0_0_1_15_1_1 - 0.699206349206346*G0_0_1_16_1_0 - 0.970634920634914*G0_0_1_16_1_1 - 0.553174603174605*G0_0_1_17_1_0 - 0.553174603174599*G0_0_1_17_1_1 + 0.970634920634917*G0_0_1_18_1_0 + 0.699206349206344*G0_0_1_18_1_1 - 0.271428571428571*G0_0_1_19_1_0 + 0.271428571428569*G0_0_1_19_1_1 - 0.315873015873015*G0_1_0_1_0_0 + 0.315873015873015*G0_1_0_2_0_1 - 0.313492063492062*G0_1_0_3_0_0 - 0.629365079365075*G0_1_0_3_0_1 + 0.629365079365078*G0_1_0_4_0_0 + 0.313492063492063*G0_1_0_4_0_1 + 0.318253968253969*G0_1_0_5_0_0 + 0.318253968253963*G0_1_0_5_0_1 - 0.629365079365078*G0_1_0_6_0_0 - 0.634126984126981*G0_1_0_6_0_1 - 0.318253968253971*G0_1_0_7_0_0 - 0.318253968253966*G0_1_0_7_0_1 + 0.634126984126982*G0_1_0_8_0_0 + 0.629365079365076*G0_1_0_8_0_1 - 0.00476190476190663*G0_1_0_9_0_0 + 0.00476190476190258*G0_1_0_9_0_1 - 0.315873015873015*G0_1_0_11_1_0 + 0.315873015873015*G0_1_0_12_1_1 - 0.313492063492062*G0_1_0_13_1_0 - 0.629365079365075*G0_1_0_13_1_1 + 0.629365079365078*G0_1_0_14_1_0 + 0.313492063492063*G0_1_0_14_1_1 + 0.318253968253969*G0_1_0_15_1_0 + 0.318253968253963*G0_1_0_15_1_1 - 0.629365079365078*G0_1_0_16_1_0 - 0.634126984126981*G0_1_0_16_1_1 - 0.318253968253971*G0_1_0_17_1_0 - 0.318253968253966*G0_1_0_17_1_1 + 0.634126984126982*G0_1_0_18_1_0 + 0.629365079365076*G0_1_0_18_1_1 - 0.00476190476190663*G0_1_0_19_1_0 + 0.00476190476190258*G0_1_0_19_1_1 - 1.47777777777777*G0_1_1_0_0_0 - 1.47777777777777*G0_1_1_0_0_1 - 0.14126984126984*G0_1_1_1_0_0 + 0.592063492063489*G0_1_1_2_0_1 - 0.366666666666665*G0_1_1_3_0_0 - 0.733333333333327*G0_1_1_3_0_1 + 0.595238095238093*G0_1_1_4_0_0 + 0.228571428571426*G0_1_1_4_0_1 - 0.0333333333333333*G0_1_1_5_0_0 + 2.67142857142856*G0_1_1_5_0_1 - 0.595238095238093*G0_1_1_6_0_0 - 1.78571428571428*G0_1_1_6_0_1 + 1.79999999999999*G0_1_1_7_0_0 - 0.9047619047619*G0_1_1_7_0_1 - 0.180952380952379*G0_1_1_8_0_0 + 0.733333333333327*G0_1_1_8_0_1 + 0.399999999999998*G0_1_1_9_0_0 + 0.676190476190474*G0_1_1_9_0_1 - 1.47777777777777*G0_1_1_10_1_0 - 1.47777777777777*G0_1_1_10_1_1 - 0.14126984126984*G0_1_1_11_1_0 + 0.592063492063489*G0_1_1_12_1_1 - 0.366666666666665*G0_1_1_13_1_0 - 0.733333333333327*G0_1_1_13_1_1 + 0.595238095238093*G0_1_1_14_1_0 + 0.228571428571426*G0_1_1_14_1_1 - 0.0333333333333333*G0_1_1_15_1_0 + 2.67142857142856*G0_1_1_15_1_1 - 0.595238095238093*G0_1_1_16_1_0 - 1.78571428571428*G0_1_1_16_1_1 + 1.79999999999999*G0_1_1_17_1_0 - 0.9047619047619*G0_1_1_17_1_1 - 0.180952380952379*G0_1_1_18_1_0 + 0.733333333333327*G0_1_1_18_1_1 + 0.399999999999998*G0_1_1_19_1_0 + 0.676190476190474*G0_1_1_19_1_1; + A[724] = 0.0; + A[827] = A[72] - 0.111746031746031*G0_0_1_0_0_0 - 0.111746031746031*G0_0_1_0_0_1 + 0.0101587301587299*G0_0_1_1_0_0 + 0.0380952380952376*G0_0_1_3_0_0 - 0.0215873015873019*G0_0_1_3_0_1 + 0.0698412698412711*G0_0_1_4_0_1 + 0.0380952380952401*G0_0_1_5_0_0 + 0.181587301587302*G0_0_1_5_0_1 - 0.069841269841273*G0_0_1_6_0_1 + 0.233650793650792*G0_0_1_7_0_0 + 0.0901587301587295*G0_0_1_7_0_1 - 0.13206349206349*G0_0_1_8_0_0 + 0.021587301587302*G0_0_1_8_0_1 - 0.0761904761904778*G0_0_1_9_0_0 - 0.160000000000001*G0_0_1_9_0_1 - 0.111746031746031*G0_0_1_10_1_0 - 0.111746031746031*G0_0_1_10_1_1 + 0.0101587301587299*G0_0_1_11_1_0 + 0.0380952380952376*G0_0_1_13_1_0 - 0.0215873015873019*G0_0_1_13_1_1 + 0.0698412698412711*G0_0_1_14_1_1 + 0.0380952380952401*G0_0_1_15_1_0 + 0.181587301587302*G0_0_1_15_1_1 - 0.069841269841273*G0_0_1_16_1_1 + 0.233650793650792*G0_0_1_17_1_0 + 0.0901587301587295*G0_0_1_17_1_1 - 0.13206349206349*G0_0_1_18_1_0 + 0.021587301587302*G0_0_1_18_1_1 - 0.0761904761904778*G0_0_1_19_1_0 - 0.160000000000001*G0_0_1_19_1_1 + 0.111746031746031*G0_1_0_0_0_0 + 0.111746031746031*G0_1_0_0_0_1 - 0.0101587301587298*G0_1_0_1_0_0 - 0.0380952380952376*G0_1_0_3_0_0 + 0.0215873015873019*G0_1_0_3_0_1 - 0.0698412698412711*G0_1_0_4_0_1 - 0.0380952380952401*G0_1_0_5_0_0 - 0.181587301587302*G0_1_0_5_0_1 + 0.069841269841273*G0_1_0_6_0_1 - 0.233650793650792*G0_1_0_7_0_0 - 0.0901587301587294*G0_1_0_7_0_1 + 0.13206349206349*G0_1_0_8_0_0 - 0.021587301587302*G0_1_0_8_0_1 + 0.0761904761904777*G0_1_0_9_0_0 + 0.160000000000001*G0_1_0_9_0_1 + 0.111746031746031*G0_1_0_10_1_0 + 0.111746031746031*G0_1_0_10_1_1 - 0.0101587301587298*G0_1_0_11_1_0 - 0.0380952380952376*G0_1_0_13_1_0 + 0.0215873015873019*G0_1_0_13_1_1 - 0.0698412698412711*G0_1_0_14_1_1 - 0.0380952380952401*G0_1_0_15_1_0 - 0.181587301587302*G0_1_0_15_1_1 + 0.069841269841273*G0_1_0_16_1_1 - 0.233650793650792*G0_1_0_17_1_0 - 0.0901587301587294*G0_1_0_17_1_1 + 0.13206349206349*G0_1_0_18_1_0 - 0.021587301587302*G0_1_0_18_1_1 + 0.0761904761904777*G0_1_0_19_1_0 + 0.160000000000001*G0_1_0_19_1_1; + A[36] = A[181] + 0.113015873015873*G0_0_1_0_0_0 + 0.113015873015874*G0_0_1_0_0_1 - 0.016507936507936*G0_0_1_2_0_1 - 0.0615873015873012*G0_0_1_3_0_0 + 0.0184126984126991*G0_0_1_4_0_0 - 0.0266666666666666*G0_0_1_4_0_1 - 0.0946031746031729*G0_0_1_5_0_0 - 0.242539682539682*G0_0_1_5_0_1 - 0.0184126984126992*G0_0_1_6_0_0 + 0.146031746031745*G0_0_1_6_0_1 - 0.174603174603175*G0_0_1_7_0_0 - 0.0266666666666657*G0_0_1_7_0_1 + 0.0615873015873014*G0_0_1_8_0_0 + 0.156190476190474*G0_0_1_9_0_0 + 0.0533333333333321*G0_0_1_9_0_1 + 0.113015873015873*G0_0_1_10_1_0 + 0.113015873015874*G0_0_1_10_1_1 - 0.016507936507936*G0_0_1_12_1_1 - 0.0615873015873012*G0_0_1_13_1_0 + 0.0184126984126991*G0_0_1_14_1_0 - 0.0266666666666666*G0_0_1_14_1_1 - 0.0946031746031729*G0_0_1_15_1_0 - 0.242539682539682*G0_0_1_15_1_1 - 0.0184126984126992*G0_0_1_16_1_0 + 0.146031746031745*G0_0_1_16_1_1 - 0.174603174603175*G0_0_1_17_1_0 - 0.0266666666666657*G0_0_1_17_1_1 + 0.0615873015873014*G0_0_1_18_1_0 + 0.156190476190474*G0_0_1_19_1_0 + 0.0533333333333321*G0_0_1_19_1_1 - 0.113015873015873*G0_1_0_0_0_0 - 0.113015873015874*G0_1_0_0_0_1 + 0.016507936507936*G0_1_0_2_0_1 + 0.0615873015873012*G0_1_0_3_0_0 - 0.0184126984126991*G0_1_0_4_0_0 + 0.0266666666666666*G0_1_0_4_0_1 + 0.0946031746031729*G0_1_0_5_0_0 + 0.242539682539682*G0_1_0_5_0_1 + 0.0184126984126992*G0_1_0_6_0_0 - 0.146031746031745*G0_1_0_6_0_1 + 0.174603174603175*G0_1_0_7_0_0 + 0.0266666666666657*G0_1_0_7_0_1 - 0.0615873015873014*G0_1_0_8_0_0 - 0.156190476190474*G0_1_0_9_0_0 - 0.0533333333333321*G0_1_0_9_0_1 - 0.113015873015873*G0_1_0_10_1_0 - 0.113015873015874*G0_1_0_10_1_1 + 0.016507936507936*G0_1_0_12_1_1 + 0.0615873015873012*G0_1_0_13_1_0 - 0.0184126984126991*G0_1_0_14_1_0 + 0.0266666666666666*G0_1_0_14_1_1 + 0.0946031746031729*G0_1_0_15_1_0 + 0.242539682539682*G0_1_0_15_1_1 + 0.0184126984126992*G0_1_0_16_1_0 - 0.146031746031745*G0_1_0_16_1_1 + 0.174603174603175*G0_1_0_17_1_0 + 0.0266666666666657*G0_1_0_17_1_1 - 0.0615873015873014*G0_1_0_18_1_0 - 0.156190476190474*G0_1_0_19_1_0 - 0.0533333333333321*G0_1_0_19_1_1; + A[751] = 0.0; + A[65] = A[530]; + A[786] = 0.0; + A[158] = A[623]; + A[114] = 0.0; + A[139] = 0.0; + A[168] = 0.0; + A[502] = A[36] + 0.162539682539682*G0_0_0_0_0_0 + 0.162539682539682*G0_0_0_0_0_1 + 0.00539682539682479*G0_0_0_2_0_1 - 0.0377777777777787*G0_0_0_3_0_0 + 0.0357142857142811*G0_0_0_3_0_1 + 0.064126984126984*G0_0_0_4_0_0 - 0.0147619047619029*G0_0_0_4_0_1 - 0.0269841269841279*G0_0_0_5_0_0 - 0.283968253968253*G0_0_0_5_0_1 - 0.064126984126984*G0_0_0_6_0_0 + 0.116031746031746*G0_0_0_6_0_1 - 0.271746031746031*G0_0_0_7_0_0 - 0.0147619047619061*G0_0_0_7_0_1 + 0.109206349206351*G0_0_0_8_0_0 - 0.0357142857142812*G0_0_0_8_0_1 + 0.064761904761907*G0_0_0_9_0_0 + 0.0295238095238089*G0_0_0_9_0_1 + 0.162539682539682*G0_0_0_10_1_0 + 0.162539682539682*G0_0_0_10_1_1 + 0.00539682539682479*G0_0_0_12_1_1 - 0.0377777777777787*G0_0_0_13_1_0 + 0.0357142857142811*G0_0_0_13_1_1 + 0.064126984126984*G0_0_0_14_1_0 - 0.0147619047619029*G0_0_0_14_1_1 - 0.0269841269841279*G0_0_0_15_1_0 - 0.283968253968253*G0_0_0_15_1_1 - 0.064126984126984*G0_0_0_16_1_0 + 0.116031746031746*G0_0_0_16_1_1 - 0.271746031746031*G0_0_0_17_1_0 - 0.0147619047619061*G0_0_0_17_1_1 + 0.109206349206351*G0_0_0_18_1_0 - 0.0357142857142812*G0_0_0_18_1_1 + 0.064761904761907*G0_0_0_19_1_0 + 0.0295238095238089*G0_0_0_19_1_1 - 0.0885714285714296*G0_0_1_0_0_0 - 0.0885714285714297*G0_0_1_0_0_1 + 0.0409523809523802*G0_0_1_2_0_1 + 0.0357142857142845*G0_0_1_3_0_0 + 0.0290476190476182*G0_0_1_4_0_0 + 0.0238095238095247*G0_0_1_4_0_1 + 0.117619047619045*G0_0_1_5_0_0 + 0.218095238095239*G0_0_1_5_0_1 - 0.0290476190476182*G0_0_1_6_0_0 - 0.170476190476189*G0_0_1_6_0_1 + 0.124285714285715*G0_0_1_7_0_0 + 0.0238095238095215*G0_0_1_7_0_1 - 0.0357142857142841*G0_0_1_8_0_0 - 0.153333333333329*G0_0_1_9_0_0 - 0.047619047619046*G0_0_1_9_0_1 - 0.0885714285714296*G0_0_1_10_1_0 - 0.0885714285714297*G0_0_1_10_1_1 + 0.0409523809523802*G0_0_1_12_1_1 + 0.0357142857142845*G0_0_1_13_1_0 + 0.0290476190476182*G0_0_1_14_1_0 + 0.0238095238095247*G0_0_1_14_1_1 + 0.117619047619045*G0_0_1_15_1_0 + 0.218095238095239*G0_0_1_15_1_1 - 0.0290476190476182*G0_0_1_16_1_0 - 0.170476190476189*G0_0_1_16_1_1 + 0.124285714285715*G0_0_1_17_1_0 + 0.0238095238095215*G0_0_1_17_1_1 - 0.0357142857142841*G0_0_1_18_1_0 - 0.153333333333329*G0_0_1_19_1_0 - 0.047619047619046*G0_0_1_19_1_1; + A[205] = 0.0; + A[573] = 0.0; + A[533] = -A[530] + 0.34074074074074*G0_1_1_0_0_0 + 0.34074074074074*G0_1_1_0_0_1 - 0.340740740740741*G0_1_1_1_0_0 - 1.25502645502645*G0_1_1_2_0_1 + 0.730158730158726*G0_1_1_3_0_0 - 0.355555555555557*G0_1_1_3_0_1 - 2.0126984126984*G0_1_1_4_0_0 - 0.0126984126984129*G0_1_1_4_0_1 - 0.730158730158727*G0_1_1_5_0_0 - 1.08571428571428*G0_1_1_5_0_1 + 2.0126984126984*G0_1_1_6_0_0 + 1.99999999999999*G0_1_1_6_0_1 + 0.355555555555553*G0_1_1_7_0_1 + 0.355555555555557*G0_1_1_8_0_1 - 0.34285714285714*G0_1_1_9_0_1 + 0.34074074074074*G0_1_1_10_1_0 + 0.34074074074074*G0_1_1_10_1_1 - 0.340740740740741*G0_1_1_11_1_0 - 1.25502645502645*G0_1_1_12_1_1 + 0.730158730158726*G0_1_1_13_1_0 - 0.355555555555557*G0_1_1_13_1_1 - 2.0126984126984*G0_1_1_14_1_0 - 0.0126984126984129*G0_1_1_14_1_1 - 0.730158730158727*G0_1_1_15_1_0 - 1.08571428571428*G0_1_1_15_1_1 + 2.0126984126984*G0_1_1_16_1_0 + 1.99999999999999*G0_1_1_16_1_1 + 0.355555555555553*G0_1_1_17_1_1 + 0.355555555555557*G0_1_1_18_1_1 - 0.34285714285714*G0_1_1_19_1_1; + A[238] = 0.0; + A[604] = 0.0; + A[242] = A[533] + 0.423280423280422*G0_0_1_0_0_0 + 0.423280423280422*G0_0_1_0_0_1 - 0.423280423280422*G0_0_1_1_0_0 - 2.80423280423279*G0_0_1_2_0_1 + 2.02539682539681*G0_0_1_3_0_0 + 0.149206349206346*G0_0_1_3_0_1 - 5.11746031746029*G0_0_1_4_0_0 - 0.860317460317457*G0_0_1_4_0_1 - 2.02539682539681*G0_0_1_5_0_0 - 1.87619047619047*G0_0_1_5_0_1 + 5.11746031746029*G0_0_1_6_0_0 + 4.25714285714284*G0_0_1_6_0_1 - 0.14920634920635*G0_0_1_7_0_1 - 0.149206349206346*G0_0_1_8_0_1 + 1.00952380952381*G0_0_1_9_0_1 + 0.423280423280422*G0_0_1_10_1_0 + 0.423280423280422*G0_0_1_10_1_1 - 0.423280423280422*G0_0_1_11_1_0 - 2.80423280423279*G0_0_1_12_1_1 + 2.02539682539681*G0_0_1_13_1_0 + 0.149206349206346*G0_0_1_13_1_1 - 5.11746031746029*G0_0_1_14_1_0 - 0.860317460317457*G0_0_1_14_1_1 - 2.02539682539681*G0_0_1_15_1_0 - 1.87619047619047*G0_0_1_15_1_1 + 5.11746031746029*G0_0_1_16_1_0 + 4.25714285714284*G0_0_1_16_1_1 - 0.14920634920635*G0_0_1_17_1_1 - 0.149206349206346*G0_0_1_18_1_1 + 1.00952380952381*G0_0_1_19_1_1 - 0.423280423280422*G0_1_0_0_0_0 - 0.423280423280422*G0_1_0_0_0_1 + 0.423280423280422*G0_1_0_1_0_0 + 2.80423280423279*G0_1_0_2_0_1 - 2.02539682539681*G0_1_0_3_0_0 - 0.149206349206346*G0_1_0_3_0_1 + 5.11746031746029*G0_1_0_4_0_0 + 0.860317460317457*G0_1_0_4_0_1 + 2.02539682539681*G0_1_0_5_0_0 + 1.87619047619047*G0_1_0_5_0_1 - 5.11746031746029*G0_1_0_6_0_0 - 4.25714285714284*G0_1_0_6_0_1 + 0.14920634920635*G0_1_0_7_0_1 + 0.149206349206346*G0_1_0_8_0_1 - 1.00952380952381*G0_1_0_9_0_1 - 0.423280423280422*G0_1_0_10_1_0 - 0.423280423280422*G0_1_0_10_1_1 + 0.423280423280422*G0_1_0_11_1_0 + 2.80423280423279*G0_1_0_12_1_1 - 2.02539682539681*G0_1_0_13_1_0 - 0.149206349206346*G0_1_0_13_1_1 + 5.11746031746029*G0_1_0_14_1_0 + 0.860317460317457*G0_1_0_14_1_1 + 2.02539682539681*G0_1_0_15_1_0 + 1.87619047619047*G0_1_0_15_1_1 - 5.11746031746029*G0_1_0_16_1_0 - 4.25714285714284*G0_1_0_16_1_1 + 0.14920634920635*G0_1_0_17_1_1 + 0.149206349206346*G0_1_0_18_1_1 - 1.00952380952381*G0_1_0_19_1_1; + A[444] = 0.0; + A[324] = 0.0; + A[479] = A[14]; + A[351] = 0.0; + A[731] = 0.0; + A[422] = A[887]; + A[382] = 0.0; + A[760] = 0.0; + A[413] = 0.0; + A[857] = A[827] + 0.121904761904762*G0_0_1_0_0_0 + 0.121904761904762*G0_0_1_0_0_1 - 0.121904761904761*G0_0_1_1_0_0 - 0.121904761904761*G0_0_1_3_0_1 - 0.121904761904765*G0_0_1_5_0_1 - 0.365714285714283*G0_0_1_7_0_0 - 0.243809523809523*G0_0_1_7_0_1 + 0.365714285714282*G0_0_1_8_0_0 + 0.121904761904761*G0_0_1_8_0_1 + 0.243809523809527*G0_0_1_9_0_1 + 0.121904761904762*G0_0_1_10_1_0 + 0.121904761904762*G0_0_1_10_1_1 - 0.121904761904761*G0_0_1_11_1_0 - 0.121904761904761*G0_0_1_13_1_1 - 0.121904761904765*G0_0_1_15_1_1 - 0.365714285714283*G0_0_1_17_1_0 - 0.243809523809523*G0_0_1_17_1_1 + 0.365714285714282*G0_0_1_18_1_0 + 0.121904761904761*G0_0_1_18_1_1 + 0.243809523809527*G0_0_1_19_1_1 - 0.228571428571427*G0_1_1_0_0_0 - 0.228571428571427*G0_1_1_0_0_1 - 0.35047619047619*G0_1_1_1_0_0 - 0.0304761904761895*G0_1_1_3_0_0 - 0.655238095238094*G0_1_1_3_0_1 + 0.27428571428571*G0_1_1_4_0_1 - 0.0304761904761937*G0_1_1_5_0_0 + 0.502857142857137*G0_1_1_5_0_1 - 0.274285714285706*G0_1_1_6_0_1 + 0.106666666666666*G0_1_1_7_0_0 - 0.426666666666665*G0_1_1_7_0_1 + 0.472380952380951*G0_1_1_8_0_0 + 0.655238095238094*G0_1_1_8_0_1 + 0.0609523809523832*G0_1_1_9_0_0 + 0.152380952380955*G0_1_1_9_0_1 - 0.228571428571427*G0_1_1_10_1_0 - 0.228571428571427*G0_1_1_10_1_1 - 0.35047619047619*G0_1_1_11_1_0 - 0.0304761904761895*G0_1_1_13_1_0 - 0.655238095238094*G0_1_1_13_1_1 + 0.27428571428571*G0_1_1_14_1_1 - 0.0304761904761937*G0_1_1_15_1_0 + 0.502857142857137*G0_1_1_15_1_1 - 0.274285714285706*G0_1_1_16_1_1 + 0.106666666666666*G0_1_1_17_1_0 - 0.426666666666665*G0_1_1_17_1_1 + 0.472380952380951*G0_1_1_18_1_0 + 0.655238095238094*G0_1_1_18_1_1 + 0.0609523809523832*G0_1_1_19_1_0 + 0.152380952380955*G0_1_1_19_1_1; + A[88] = 0.0; + A[781] = 0.0; + A[91] = -A[331] + 0.34074074074074*G0_0_0_0_0_0 + 0.34074074074074*G0_0_0_0_0_1 - 1.25502645502645*G0_0_0_1_0_0 - 0.34074074074074*G0_0_0_2_0_1 - 0.0126984126984137*G0_0_0_3_0_0 - 2.01269841269841*G0_0_0_3_0_1 - 0.355555555555553*G0_0_0_4_0_0 + 0.73015873015873*G0_0_0_4_0_1 + 0.355555555555554*G0_0_0_5_0_0 + 0.355555555555553*G0_0_0_6_0_0 - 1.08571428571428*G0_0_0_7_0_0 - 0.730158730158728*G0_0_0_7_0_1 + 2*G0_0_0_8_0_0 + 2.01269841269841*G0_0_0_8_0_1 - 0.342857142857141*G0_0_0_9_0_0 + 0.34074074074074*G0_0_0_10_1_0 + 0.34074074074074*G0_0_0_10_1_1 - 1.25502645502645*G0_0_0_11_1_0 - 0.34074074074074*G0_0_0_12_1_1 - 0.0126984126984137*G0_0_0_13_1_0 - 2.01269841269841*G0_0_0_13_1_1 - 0.355555555555553*G0_0_0_14_1_0 + 0.73015873015873*G0_0_0_14_1_1 + 0.355555555555554*G0_0_0_15_1_0 + 0.355555555555553*G0_0_0_16_1_0 - 1.08571428571428*G0_0_0_17_1_0 - 0.730158730158728*G0_0_0_17_1_1 + 2*G0_0_0_18_1_0 + 2.01269841269841*G0_0_0_18_1_1 - 0.342857142857141*G0_0_0_19_1_0; + A[822] = 0.0; + A[146] = 0.0; + A[855] = A[14] - 0.228571428571427*G0_0_0_1_0_0 + 0.350476190476188*G0_0_0_2_0_1 - 0.426666666666663*G0_0_0_3_0_0 - 0.533333333333329*G0_0_0_3_0_1 + 0.655238095238091*G0_0_0_4_0_0 + 0.182857142857141*G0_0_0_4_0_1 + 0.274285714285714*G0_0_0_5_0_0 + 0.274285714285711*G0_0_0_5_0_1 - 0.655238095238091*G0_0_0_6_0_0 - 0.624761904761901*G0_0_0_6_0_1 - 0.274285714285715*G0_0_0_7_0_0 - 0.274285714285712*G0_0_0_7_0_1 + 0.502857142857141*G0_0_0_8_0_0 + 0.53333333333333*G0_0_0_8_0_1 + 0.15238095238095*G0_0_0_9_0_0 + 0.0914285714285705*G0_0_0_9_0_1 - 0.228571428571427*G0_0_0_11_1_0 + 0.350476190476188*G0_0_0_12_1_1 - 0.426666666666663*G0_0_0_13_1_0 - 0.533333333333329*G0_0_0_13_1_1 + 0.655238095238091*G0_0_0_14_1_0 + 0.182857142857141*G0_0_0_14_1_1 + 0.274285714285714*G0_0_0_15_1_0 + 0.274285714285711*G0_0_0_15_1_1 - 0.655238095238091*G0_0_0_16_1_0 - 0.624761904761901*G0_0_0_16_1_1 - 0.274285714285715*G0_0_0_17_1_0 - 0.274285714285712*G0_0_0_17_1_1 + 0.502857142857141*G0_0_0_18_1_0 + 0.53333333333333*G0_0_0_18_1_1 + 0.15238095238095*G0_0_0_19_1_0 + 0.0914285714285705*G0_0_0_19_1_1 - 0.238730158730157*G0_0_1_1_0_0 + 0.238730158730157*G0_0_1_2_0_1 - 0.27301587301587*G0_0_1_3_0_0 - 0.511746031746026*G0_0_1_3_0_1 + 0.511746031746028*G0_0_1_4_0_0 + 0.273015873015871*G0_0_1_4_0_1 + 0.204444444444444*G0_0_1_5_0_0 + 0.20444444444444*G0_0_1_5_0_1 - 0.511746031746028*G0_0_1_6_0_0 - 0.443174603174598*G0_0_1_6_0_1 - 0.204444444444446*G0_0_1_7_0_0 - 0.204444444444442*G0_0_1_7_0_1 + 0.4431746031746*G0_0_1_8_0_0 + 0.511746031746027*G0_0_1_8_0_1 + 0.0685714285714254*G0_0_1_9_0_0 - 0.0685714285714301*G0_0_1_9_0_1 - 0.238730158730157*G0_0_1_11_1_0 + 0.238730158730157*G0_0_1_12_1_1 - 0.27301587301587*G0_0_1_13_1_0 - 0.511746031746026*G0_0_1_13_1_1 + 0.511746031746028*G0_0_1_14_1_0 + 0.273015873015871*G0_0_1_14_1_1 + 0.204444444444444*G0_0_1_15_1_0 + 0.20444444444444*G0_0_1_15_1_1 - 0.511746031746028*G0_0_1_16_1_0 - 0.443174603174598*G0_0_1_16_1_1 - 0.204444444444446*G0_0_1_17_1_0 - 0.204444444444442*G0_0_1_17_1_1 + 0.4431746031746*G0_0_1_18_1_0 + 0.511746031746027*G0_0_1_18_1_1 + 0.0685714285714254*G0_0_1_19_1_0 - 0.0685714285714301*G0_0_1_19_1_1 - 0.340317460317459*G0_1_0_1_0_0 + 0.340317460317458*G0_1_0_2_0_1 - 0.336507936507934*G0_1_0_3_0_0 - 0.676825396825392*G0_1_0_3_0_1 + 0.676825396825393*G0_1_0_4_0_0 + 0.336507936507934*G0_1_0_4_0_1 + 0.344126984126984*G0_1_0_5_0_0 + 0.344126984126975*G0_1_0_5_0_1 - 0.676825396825393*G0_1_0_6_0_0 - 0.684444444444438*G0_1_0_6_0_1 - 0.344126984126989*G0_1_0_7_0_0 - 0.344126984126981*G0_1_0_7_0_1 + 0.684444444444443*G0_1_0_8_0_0 + 0.676825396825392*G0_1_0_8_0_1 - 0.00761904761904897*G0_1_0_9_0_0 + 0.0076190476190463*G0_1_0_9_0_1 - 0.340317460317459*G0_1_0_11_1_0 + 0.340317460317458*G0_1_0_12_1_1 - 0.336507936507934*G0_1_0_13_1_0 - 0.676825396825392*G0_1_0_13_1_1 + 0.676825396825393*G0_1_0_14_1_0 + 0.336507936507934*G0_1_0_14_1_1 + 0.344126984126984*G0_1_0_15_1_0 + 0.344126984126975*G0_1_0_15_1_1 - 0.676825396825393*G0_1_0_16_1_0 - 0.684444444444438*G0_1_0_16_1_1 - 0.344126984126989*G0_1_0_17_1_0 - 0.344126984126981*G0_1_0_17_1_1 + 0.684444444444443*G0_1_0_18_1_0 + 0.676825396825392*G0_1_0_18_1_1 - 0.00761904761904897*G0_1_0_19_1_0 + 0.0076190476190463*G0_1_0_19_1_1 - 0.350476190476188*G0_1_1_1_0_0 + 0.228571428571427*G0_1_1_2_0_1 - 0.18285714285714*G0_1_1_3_0_0 - 0.655238095238088*G0_1_1_3_0_1 + 0.533333333333331*G0_1_1_4_0_0 + 0.426666666666663*G0_1_1_4_0_1 + 0.274285714285714*G0_1_1_5_0_0 + 0.274285714285705*G0_1_1_5_0_1 - 0.533333333333331*G0_1_1_6_0_0 - 0.502857142857137*G0_1_1_6_0_1 - 0.27428571428572*G0_1_1_7_0_0 - 0.274285714285711*G0_1_1_7_0_1 + 0.624761904761903*G0_1_1_8_0_0 + 0.655238095238088*G0_1_1_8_0_1 - 0.0914285714285742*G0_1_1_9_0_0 - 0.152380952380953*G0_1_1_9_0_1 - 0.350476190476188*G0_1_1_11_1_0 + 0.228571428571427*G0_1_1_12_1_1 - 0.18285714285714*G0_1_1_13_1_0 - 0.655238095238088*G0_1_1_13_1_1 + 0.533333333333331*G0_1_1_14_1_0 + 0.426666666666663*G0_1_1_14_1_1 + 0.274285714285714*G0_1_1_15_1_0 + 0.274285714285705*G0_1_1_15_1_1 - 0.533333333333331*G0_1_1_16_1_0 - 0.502857142857137*G0_1_1_16_1_1 - 0.27428571428572*G0_1_1_17_1_0 - 0.274285714285711*G0_1_1_17_1_1 + 0.624761904761903*G0_1_1_18_1_0 + 0.655238095238088*G0_1_1_18_1_1 - 0.0914285714285742*G0_1_1_19_1_0 - 0.152380952380953*G0_1_1_19_1_1; + A[177] = 0.0; + A[884] = 0.0; + A[493] = 0.0; + A[196] = 0.0; + A[654] = A[741] + 1.93015873015873*G0_0_1_0_0_0 + 1.93015873015872*G0_0_1_0_0_1 - 0.406349206349204*G0_0_1_1_0_0 - 0.406349206349205*G0_0_1_2_0_1 - 0.0507936507936476*G0_0_1_3_0_0 - 0.0507936507936502*G0_0_1_3_0_1 - 0.0507936507936482*G0_0_1_4_0_0 - 0.0507936507936466*G0_0_1_4_0_1 - 0.863492063492058*G0_0_1_5_0_0 - 3.5047619047619*G0_0_1_5_0_1 + 0.0507936507936483*G0_0_1_6_0_0 + 1.98095238095238*G0_0_1_6_0_1 - 3.50476190476189*G0_0_1_7_0_0 - 0.863492063492055*G0_0_1_7_0_1 + 1.98095238095237*G0_0_1_8_0_0 + 0.0507936507936508*G0_0_1_8_0_1 + 0.914285714285706*G0_0_1_9_0_0 + 0.9142857142857*G0_0_1_9_0_1 + 1.93015873015873*G0_0_1_10_1_0 + 1.93015873015872*G0_0_1_10_1_1 - 0.406349206349204*G0_0_1_11_1_0 - 0.406349206349205*G0_0_1_12_1_1 - 0.0507936507936476*G0_0_1_13_1_0 - 0.0507936507936502*G0_0_1_13_1_1 - 0.0507936507936482*G0_0_1_14_1_0 - 0.0507936507936466*G0_0_1_14_1_1 - 0.863492063492058*G0_0_1_15_1_0 - 3.5047619047619*G0_0_1_15_1_1 + 0.0507936507936483*G0_0_1_16_1_0 + 1.98095238095238*G0_0_1_16_1_1 - 3.50476190476189*G0_0_1_17_1_0 - 0.863492063492055*G0_0_1_17_1_1 + 1.98095238095237*G0_0_1_18_1_0 + 0.0507936507936508*G0_0_1_18_1_1 + 0.914285714285706*G0_0_1_19_1_0 + 0.9142857142857*G0_0_1_19_1_1 - 1.93015873015873*G0_1_0_0_0_0 - 1.93015873015873*G0_1_0_0_0_1 + 0.406349206349204*G0_1_0_1_0_0 + 0.406349206349205*G0_1_0_2_0_1 + 0.0507936507936476*G0_1_0_3_0_0 + 0.0507936507936502*G0_1_0_3_0_1 + 0.0507936507936482*G0_1_0_4_0_0 + 0.0507936507936466*G0_1_0_4_0_1 + 0.863492063492057*G0_1_0_5_0_0 + 3.5047619047619*G0_1_0_5_0_1 - 0.0507936507936483*G0_1_0_6_0_0 - 1.98095238095238*G0_1_0_6_0_1 + 3.50476190476189*G0_1_0_7_0_0 + 0.863492063492055*G0_1_0_7_0_1 - 1.98095238095237*G0_1_0_8_0_0 - 0.0507936507936508*G0_1_0_8_0_1 - 0.914285714285705*G0_1_0_9_0_0 - 0.9142857142857*G0_1_0_9_0_1 - 1.93015873015873*G0_1_0_10_1_0 - 1.93015873015873*G0_1_0_10_1_1 + 0.406349206349204*G0_1_0_11_1_0 + 0.406349206349205*G0_1_0_12_1_1 + 0.0507936507936476*G0_1_0_13_1_0 + 0.0507936507936502*G0_1_0_13_1_1 + 0.0507936507936482*G0_1_0_14_1_0 + 0.0507936507936466*G0_1_0_14_1_1 + 0.863492063492057*G0_1_0_15_1_0 + 3.5047619047619*G0_1_0_15_1_1 - 0.0507936507936483*G0_1_0_16_1_0 - 1.98095238095238*G0_1_0_16_1_1 + 3.50476190476189*G0_1_0_17_1_0 + 0.863492063492055*G0_1_0_17_1_1 - 1.98095238095237*G0_1_0_18_1_0 - 0.0507936507936508*G0_1_0_18_1_1 - 0.914285714285705*G0_1_0_19_1_0 - 0.9142857142857*G0_1_0_19_1_1; + A[578] = 0.0; + A[518] = 0.0; + A[231] = 0.0; + A[603] = 0.0; + A[632] = 0.0; + A[669] = 0.0; + A[702] = 0.0; + A[21] = 0.0; + A[46] = 0.0; + A[769] = A[127] + 0.0647619047619049*G0_0_0_0_0_0 + 0.0647619047619048*G0_0_0_0_0_1 - 0.0952380952380959*G0_0_0_1_0_0 + 0.617142857142848*G0_0_0_2_0_1 - 0.834285714285707*G0_0_0_3_0_0 - 0.104761904761904*G0_0_0_3_0_1 + 0.217142857142843*G0_0_0_4_0_0 - 1.2247619047619*G0_0_0_4_0_1 + 1.08571428571428*G0_0_0_5_0_0 + 0.91619047619047*G0_0_0_5_0_1 - 0.217142857142843*G0_0_0_6_0_0 - 1.59809523809522*G0_0_0_6_0_1 - 0.899047619047616*G0_0_0_7_0_0 - 0.729523809523808*G0_0_0_7_0_1 + 0.929523809523807*G0_0_0_8_0_0 + 0.104761904761905*G0_0_0_8_0_1 - 0.25142857142857*G0_0_0_9_0_0 + 1.95428571428571*G0_0_0_9_0_1 + 0.0647619047619049*G0_0_0_10_1_0 + 0.0647619047619048*G0_0_0_10_1_1 - 0.0952380952380959*G0_0_0_11_1_0 + 0.617142857142848*G0_0_0_12_1_1 - 0.834285714285707*G0_0_0_13_1_0 - 0.104761904761904*G0_0_0_13_1_1 + 0.217142857142843*G0_0_0_14_1_0 - 1.2247619047619*G0_0_0_14_1_1 + 1.08571428571428*G0_0_0_15_1_0 + 0.91619047619047*G0_0_0_15_1_1 - 0.217142857142843*G0_0_0_16_1_0 - 1.59809523809522*G0_0_0_16_1_1 - 0.899047619047616*G0_0_0_17_1_0 - 0.729523809523808*G0_0_0_17_1_1 + 0.929523809523807*G0_0_0_18_1_0 + 0.104761904761905*G0_0_0_18_1_1 - 0.25142857142857*G0_0_0_19_1_0 + 1.95428571428571*G0_0_0_19_1_1 - 0.392380952380957*G0_0_1_1_0_0 + 0.392380952380945*G0_0_1_2_0_1 + 0.219047619047622*G0_0_1_3_0_0 - 0.17333333333334*G0_0_1_3_0_1 + 0.173333333333323*G0_0_1_4_0_0 - 0.219047619047616*G0_0_1_4_0_1 + 1.00380952380952*G0_0_1_5_0_0 + 1.00380952380952*G0_0_1_5_0_1 - 0.173333333333323*G0_0_1_6_0_0 - 1.39619047619046*G0_0_1_6_0_1 - 1.00380952380952*G0_0_1_7_0_0 - 1.00380952380953*G0_0_1_7_0_1 + 1.39619047619048*G0_0_1_8_0_0 + 0.17333333333334*G0_0_1_8_0_1 - 1.22285714285714*G0_0_1_9_0_0 + 1.22285714285714*G0_0_1_9_0_1 - 0.392380952380957*G0_0_1_11_1_0 + 0.392380952380945*G0_0_1_12_1_1 + 0.219047619047622*G0_0_1_13_1_0 - 0.17333333333334*G0_0_1_13_1_1 + 0.173333333333323*G0_0_1_14_1_0 - 0.219047619047616*G0_0_1_14_1_1 + 1.00380952380952*G0_0_1_15_1_0 + 1.00380952380952*G0_0_1_15_1_1 - 0.173333333333323*G0_0_1_16_1_0 - 1.39619047619046*G0_0_1_16_1_1 - 1.00380952380952*G0_0_1_17_1_0 - 1.00380952380953*G0_0_1_17_1_1 + 1.39619047619048*G0_0_1_18_1_0 + 0.17333333333334*G0_0_1_18_1_1 - 1.22285714285714*G0_0_1_19_1_0 + 1.22285714285714*G0_0_1_19_1_1 - 0.289523809523813*G0_1_0_1_0_0 + 0.289523809523802*G0_1_0_2_0_1 + 0.0761904761904746*G0_1_0_3_0_0 - 0.213333333333341*G0_1_0_3_0_1 + 0.213333333333322*G0_1_0_4_0_0 - 0.0761904761904785*G0_1_0_4_0_1 + 0.655238095238091*G0_1_0_5_0_0 + 0.65523809523809*G0_1_0_5_0_1 - 0.213333333333321*G0_1_0_6_0_0 - 0.944761904761894*G0_1_0_6_0_1 - 0.655238095238094*G0_1_0_7_0_0 - 0.655238095238093*G0_1_0_7_0_1 + 0.944761904761905*G0_1_0_8_0_0 + 0.213333333333341*G0_1_0_8_0_1 - 0.731428571428565*G0_1_0_9_0_0 + 0.731428571428571*G0_1_0_9_0_1 - 0.289523809523813*G0_1_0_11_1_0 + 0.289523809523802*G0_1_0_12_1_1 + 0.0761904761904746*G0_1_0_13_1_0 - 0.213333333333341*G0_1_0_13_1_1 + 0.213333333333322*G0_1_0_14_1_0 - 0.0761904761904785*G0_1_0_14_1_1 + 0.655238095238091*G0_1_0_15_1_0 + 0.65523809523809*G0_1_0_15_1_1 - 0.213333333333321*G0_1_0_16_1_0 - 0.944761904761894*G0_1_0_16_1_1 - 0.655238095238094*G0_1_0_17_1_0 - 0.655238095238093*G0_1_0_17_1_1 + 0.944761904761905*G0_1_0_18_1_0 + 0.213333333333341*G0_1_0_18_1_1 - 0.731428571428565*G0_1_0_19_1_0 + 0.731428571428571*G0_1_0_19_1_1 - 0.064761904761906*G0_1_1_0_0_0 - 0.0647619047619066*G0_1_1_0_0_1 - 0.61714285714286*G0_1_1_1_0_0 + 0.0952380952380907*G0_1_1_2_0_1 + 1.2247619047619*G0_1_1_3_0_0 - 0.217142857142866*G0_1_1_3_0_1 + 0.104761904761898*G0_1_1_4_0_0 + 0.834285714285712*G0_1_1_4_0_1 + 0.729523809523802*G0_1_1_5_0_0 + 0.899047619047618*G0_1_1_5_0_1 - 0.104761904761897*G0_1_1_6_0_0 - 0.929523809523802*G0_1_1_6_0_1 - 0.916190476190471*G0_1_1_7_0_0 - 1.08571428571429*G0_1_1_7_0_1 + 1.59809523809524*G0_1_1_8_0_0 + 0.217142857142867*G0_1_1_8_0_1 - 1.9542857142857*G0_1_1_9_0_0 + 0.251428571428575*G0_1_1_9_0_1 - 0.064761904761906*G0_1_1_10_1_0 - 0.0647619047619066*G0_1_1_10_1_1 - 0.61714285714286*G0_1_1_11_1_0 + 0.0952380952380907*G0_1_1_12_1_1 + 1.2247619047619*G0_1_1_13_1_0 - 0.217142857142866*G0_1_1_13_1_1 + 0.104761904761898*G0_1_1_14_1_0 + 0.834285714285712*G0_1_1_14_1_1 + 0.729523809523802*G0_1_1_15_1_0 + 0.899047619047618*G0_1_1_15_1_1 - 0.104761904761897*G0_1_1_16_1_0 - 0.929523809523802*G0_1_1_16_1_1 - 0.916190476190471*G0_1_1_17_1_0 - 1.08571428571429*G0_1_1_17_1_1 + 1.59809523809524*G0_1_1_18_1_0 + 0.217142857142867*G0_1_1_18_1_1 - 1.9542857142857*G0_1_1_19_1_0 + 0.251428571428575*G0_1_1_19_1_1; + A[450] = 0.0; + A[406] = 0.0; + A[83] = 0.0; + A[788] = 0.0; + A[815] = 0.0; + A[40] = -0.540423280423279*G0_0_0_0_0_0 - 0.540423280423278*G0_0_0_0_0_1 + 1.27883597883597*G0_0_0_1_0_0 + 0.122962962962963*G0_0_0_2_0_1 + 0.433333333333331*G0_0_0_3_0_0 + 2.1579365079365*G0_0_0_3_0_1 - 0.106666666666666*G0_0_0_4_0_0 - 0.675396825396823*G0_0_0_4_0_1 - 0.256190476190475*G0_0_0_5_0_0 + 0.336349206349205*G0_0_0_5_0_1 + 0.106666666666667*G0_0_0_6_0_0 + 0.0811111111111099*G0_0_0_6_0_1 + 1.53936507936507*G0_0_0_7_0_0 + 0.946825396825392*G0_0_0_7_0_1 - 2.27777777777777*G0_0_0_8_0_0 - 2.1579365079365*G0_0_0_8_0_1 - 0.177142857142856*G0_0_0_9_0_0 - 0.271428571428568*G0_0_0_9_0_1 - 0.540423280423279*G0_0_0_10_1_0 - 0.540423280423278*G0_0_0_10_1_1 + 1.27883597883597*G0_0_0_11_1_0 + 0.122962962962963*G0_0_0_12_1_1 + 0.433333333333331*G0_0_0_13_1_0 + 2.1579365079365*G0_0_0_13_1_1 - 0.106666666666666*G0_0_0_14_1_0 - 0.675396825396823*G0_0_0_14_1_1 - 0.256190476190475*G0_0_0_15_1_0 + 0.336349206349205*G0_0_0_15_1_1 + 0.106666666666667*G0_0_0_16_1_0 + 0.0811111111111099*G0_0_0_16_1_1 + 1.53936507936507*G0_0_0_17_1_0 + 0.946825396825392*G0_0_0_17_1_1 - 2.27777777777777*G0_0_0_18_1_0 - 2.1579365079365*G0_0_0_18_1_1 - 0.177142857142856*G0_0_0_19_1_0 - 0.271428571428568*G0_0_0_19_1_1 - 0.276190476190475*G0_0_1_0_0_0 - 0.276190476190474*G0_0_1_0_0_1 + 1.47777777777777*G0_0_1_1_0_0 + 0.174603174603173*G0_0_1_2_0_1 + 0.586507936507933*G0_0_1_3_0_0 + 2.70476190476189*G0_0_1_3_0_1 - 0.103968253968254*G0_0_1_4_0_0 - 0.919047619047614*G0_0_1_4_0_1 + 0.0849206349206333*G0_0_1_5_0_0 + 0.0507936507936502*G0_0_1_5_0_1 + 0.103968253968254*G0_0_1_6_0_0 + 0.0507936507936506*G0_0_1_6_0_1 + 1.15158730158729*G0_0_1_7_0_0 + 1.18571428571428*G0_0_1_7_0_1 - 2.35317460317459*G0_0_1_8_0_0 - 2.70476190476189*G0_0_1_8_0_1 - 0.671428571428566*G0_0_1_9_0_0 - 0.266666666666662*G0_0_1_9_0_1 - 0.276190476190475*G0_0_1_10_1_0 - 0.276190476190474*G0_0_1_10_1_1 + 1.47777777777777*G0_0_1_11_1_0 + 0.174603174603173*G0_0_1_12_1_1 + 0.586507936507933*G0_0_1_13_1_0 + 2.70476190476189*G0_0_1_13_1_1 - 0.103968253968254*G0_0_1_14_1_0 - 0.919047619047614*G0_0_1_14_1_1 + 0.0849206349206333*G0_0_1_15_1_0 + 0.0507936507936502*G0_0_1_15_1_1 + 0.103968253968254*G0_0_1_16_1_0 + 0.0507936507936506*G0_0_1_16_1_1 + 1.15158730158729*G0_0_1_17_1_0 + 1.18571428571428*G0_0_1_17_1_1 - 2.35317460317459*G0_0_1_18_1_0 - 2.70476190476189*G0_0_1_18_1_1 - 0.671428571428566*G0_0_1_19_1_0 - 0.266666666666662*G0_0_1_19_1_1; + A[121] = A[766] + 0.59206349206349*G0_0_0_0_0_0 + 0.59206349206349*G0_0_0_0_0_1 - 1.47777777777777*G0_0_0_1_0_0 + 0.14126984126984*G0_0_0_2_0_1 - 0.9047619047619*G0_0_0_3_0_0 - 2.70476190476189*G0_0_0_3_0_1 + 0.733333333333329*G0_0_0_4_0_0 + 0.914285714285708*G0_0_0_4_0_1 + 0.228571428571428*G0_0_0_5_0_0 - 0.366666666666666*G0_0_0_5_0_1 - 0.73333333333333*G0_0_0_6_0_0 - 0.366666666666664*G0_0_0_6_0_1 - 1.78571428571428*G0_0_0_7_0_0 - 1.19047619047618*G0_0_0_7_0_1 + 2.67142857142856*G0_0_0_8_0_0 + 2.70476190476189*G0_0_0_8_0_1 + 0.676190476190472*G0_0_0_9_0_0 + 0.276190476190473*G0_0_0_9_0_1 + 0.59206349206349*G0_0_0_10_1_0 + 0.59206349206349*G0_0_0_10_1_1 - 1.47777777777777*G0_0_0_11_1_0 + 0.14126984126984*G0_0_0_12_1_1 - 0.9047619047619*G0_0_0_13_1_0 - 2.70476190476189*G0_0_0_13_1_1 + 0.733333333333329*G0_0_0_14_1_0 + 0.914285714285708*G0_0_0_14_1_1 + 0.228571428571428*G0_0_0_15_1_0 - 0.366666666666666*G0_0_0_15_1_1 - 0.73333333333333*G0_0_0_16_1_0 - 0.366666666666664*G0_0_0_16_1_1 - 1.78571428571428*G0_0_0_17_1_0 - 1.19047619047618*G0_0_0_17_1_1 + 2.67142857142856*G0_0_0_18_1_0 + 2.70476190476189*G0_0_0_18_1_1 + 0.676190476190472*G0_0_0_19_1_0 + 0.276190476190473*G0_0_0_19_1_1 + 0.45079365079365*G0_1_0_0_0_0 + 0.450793650793649*G0_1_0_0_0_1 - 2.95555555555554*G0_1_0_1_0_0 - 0.450793650793648*G0_1_0_2_0_1 - 0.938095238095233*G0_1_0_3_0_0 - 5.40952380952378*G0_1_0_3_0_1 + 0.138095238095239*G0_1_0_4_0_0 + 2.10476190476189*G0_1_0_4_0_1 - 0.138095238095235*G0_1_0_5_0_0 - 0.138095238095239*G0_1_0_6_0_0 - 1.96666666666666*G0_1_0_7_0_0 - 2.10476190476189*G0_1_0_7_0_1 + 4.47142857142855*G0_1_0_8_0_0 + 5.40952380952378*G0_1_0_8_0_1 + 1.07619047619047*G0_1_0_9_0_0 + 0.45079365079365*G0_1_0_10_1_0 + 0.450793650793649*G0_1_0_10_1_1 - 2.95555555555554*G0_1_0_11_1_0 - 0.450793650793648*G0_1_0_12_1_1 - 0.938095238095233*G0_1_0_13_1_0 - 5.40952380952378*G0_1_0_13_1_1 + 0.138095238095239*G0_1_0_14_1_0 + 2.10476190476189*G0_1_0_14_1_1 - 0.138095238095235*G0_1_0_15_1_0 - 0.138095238095239*G0_1_0_16_1_0 - 1.96666666666666*G0_1_0_17_1_0 - 2.10476190476189*G0_1_0_17_1_1 + 4.47142857142855*G0_1_0_18_1_0 + 5.40952380952378*G0_1_0_18_1_1 + 1.07619047619047*G0_1_0_19_1_0; + A[846] = 0.0; + A[877] = 0.0; + A[484] = 0.0; + A[191] = A[656]; + A[587] = A[677] + 0.450793650793649*G0_0_1_0_0_0 + 0.450793650793649*G0_0_1_0_0_1 - 0.45079365079365*G0_0_1_1_0_0 - 2.95555555555554*G0_0_1_2_0_1 + 2.10476190476189*G0_0_1_3_0_0 + 0.138095238095233*G0_0_1_3_0_1 - 5.40952380952377*G0_0_1_4_0_0 - 0.938095238095233*G0_0_1_4_0_1 - 2.10476190476189*G0_0_1_5_0_0 - 1.96666666666665*G0_0_1_5_0_1 + 5.40952380952378*G0_0_1_6_0_0 + 4.47142857142854*G0_0_1_6_0_1 - 0.138095238095238*G0_0_1_7_0_1 - 0.138095238095234*G0_0_1_8_0_1 + 1.07619047619047*G0_0_1_9_0_1 + 0.450793650793649*G0_0_1_10_1_0 + 0.450793650793649*G0_0_1_10_1_1 - 0.45079365079365*G0_0_1_11_1_0 - 2.95555555555554*G0_0_1_12_1_1 + 2.10476190476189*G0_0_1_13_1_0 + 0.138095238095233*G0_0_1_13_1_1 - 5.40952380952377*G0_0_1_14_1_0 - 0.938095238095233*G0_0_1_14_1_1 - 2.10476190476189*G0_0_1_15_1_0 - 1.96666666666665*G0_0_1_15_1_1 + 5.40952380952378*G0_0_1_16_1_0 + 4.47142857142854*G0_0_1_16_1_1 - 0.138095238095238*G0_0_1_17_1_1 - 0.138095238095234*G0_0_1_18_1_1 + 1.07619047619047*G0_0_1_19_1_1 + 0.592063492063489*G0_1_1_0_0_0 + 0.592063492063489*G0_1_1_0_0_1 + 0.141269841269842*G0_1_1_1_0_0 - 1.47777777777777*G0_1_1_2_0_1 + 0.914285714285708*G0_1_1_3_0_0 + 0.733333333333331*G0_1_1_3_0_1 - 2.70476190476189*G0_1_1_4_0_0 - 0.9047619047619*G0_1_1_4_0_1 - 1.19047619047618*G0_1_1_5_0_0 - 1.78571428571427*G0_1_1_5_0_1 + 2.70476190476189*G0_1_1_6_0_0 + 2.67142857142855*G0_1_1_6_0_1 - 0.366666666666664*G0_1_1_7_0_0 + 0.228571428571428*G0_1_1_7_0_1 - 0.366666666666666*G0_1_1_8_0_0 - 0.733333333333331*G0_1_1_8_0_1 + 0.276190476190474*G0_1_1_9_0_0 + 0.676190476190472*G0_1_1_9_0_1 + 0.592063492063489*G0_1_1_10_1_0 + 0.592063492063489*G0_1_1_10_1_1 + 0.141269841269842*G0_1_1_11_1_0 - 1.47777777777777*G0_1_1_12_1_1 + 0.914285714285708*G0_1_1_13_1_0 + 0.733333333333331*G0_1_1_13_1_1 - 2.70476190476189*G0_1_1_14_1_0 - 0.9047619047619*G0_1_1_14_1_1 - 1.19047619047618*G0_1_1_15_1_0 - 1.78571428571427*G0_1_1_15_1_1 + 2.70476190476189*G0_1_1_16_1_0 + 2.67142857142855*G0_1_1_16_1_1 - 0.366666666666664*G0_1_1_17_1_0 + 0.228571428571428*G0_1_1_17_1_1 - 0.366666666666666*G0_1_1_18_1_0 - 0.733333333333331*G0_1_1_18_1_1 + 0.276190476190474*G0_1_1_19_1_0 + 0.676190476190472*G0_1_1_19_1_1; + A[511] = 0.0; + A[228] = 0.0; + A[610] = 0.0; + A[546] = 0.0; + A[506] = A[331] + 0.423280423280422*G0_0_1_0_0_0 + 0.423280423280421*G0_0_1_0_0_1 - 2.80423280423279*G0_0_1_1_0_0 - 0.423280423280421*G0_0_1_2_0_1 - 0.860317460317454*G0_0_1_3_0_0 - 5.11746031746029*G0_0_1_3_0_1 + 0.149206349206349*G0_0_1_4_0_0 + 2.02539682539681*G0_0_1_4_0_1 - 0.149206349206346*G0_0_1_5_0_0 - 0.14920634920635*G0_0_1_6_0_0 - 1.87619047619046*G0_0_1_7_0_0 - 2.02539682539681*G0_0_1_7_0_1 + 4.25714285714283*G0_0_1_8_0_0 + 5.11746031746029*G0_0_1_8_0_1 + 1.0095238095238*G0_0_1_9_0_0 + 0.423280423280422*G0_0_1_10_1_0 + 0.423280423280421*G0_0_1_10_1_1 - 2.80423280423279*G0_0_1_11_1_0 - 0.423280423280421*G0_0_1_12_1_1 - 0.860317460317454*G0_0_1_13_1_0 - 5.11746031746029*G0_0_1_13_1_1 + 0.149206349206349*G0_0_1_14_1_0 + 2.02539682539681*G0_0_1_14_1_1 - 0.149206349206346*G0_0_1_15_1_0 - 0.14920634920635*G0_0_1_16_1_0 - 1.87619047619046*G0_0_1_17_1_0 - 2.02539682539681*G0_0_1_17_1_1 + 4.25714285714283*G0_0_1_18_1_0 + 5.11746031746029*G0_0_1_18_1_1 + 1.0095238095238*G0_0_1_19_1_0 - 0.423280423280422*G0_1_0_0_0_0 - 0.423280423280421*G0_1_0_0_0_1 + 2.80423280423279*G0_1_0_1_0_0 + 0.423280423280421*G0_1_0_2_0_1 + 0.860317460317454*G0_1_0_3_0_0 + 5.11746031746029*G0_1_0_3_0_1 - 0.149206349206349*G0_1_0_4_0_0 - 2.02539682539681*G0_1_0_4_0_1 + 0.149206349206346*G0_1_0_5_0_0 + 0.14920634920635*G0_1_0_6_0_0 + 1.87619047619046*G0_1_0_7_0_0 + 2.02539682539681*G0_1_0_7_0_1 - 4.25714285714283*G0_1_0_8_0_0 - 5.11746031746029*G0_1_0_8_0_1 - 1.0095238095238*G0_1_0_9_0_0 - 0.423280423280422*G0_1_0_10_1_0 - 0.423280423280421*G0_1_0_10_1_1 + 2.80423280423279*G0_1_0_11_1_0 + 0.423280423280421*G0_1_0_12_1_1 + 0.860317460317454*G0_1_0_13_1_0 + 5.11746031746029*G0_1_0_13_1_1 - 0.149206349206349*G0_1_0_14_1_0 - 2.02539682539681*G0_1_0_14_1_1 + 0.149206349206346*G0_1_0_15_1_0 + 0.14920634920635*G0_1_0_16_1_0 + 1.87619047619046*G0_1_0_17_1_0 + 2.02539682539681*G0_1_0_17_1_1 - 4.25714285714283*G0_1_0_18_1_0 - 5.11746031746029*G0_1_0_18_1_1 - 1.0095238095238*G0_1_0_19_1_0; + A[641] = 0.0; + A[537] = A[72]; + A[660] = 0.0; + A[695] = 0.0; + A[262] = 0.0; + A[333] = A[101] + 0.406349206349206*G0_0_1_0_0_0 + 0.406349206349205*G0_0_1_0_0_1 - 1.93015873015873*G0_0_1_1_0_0 - 0.406349206349206*G0_0_1_2_0_1 + 0.86349206349206*G0_0_1_3_0_0 - 2.64126984126984*G0_0_1_3_0_1 - 0.0507936507936488*G0_0_1_4_0_0 + 1.93015873015873*G0_0_1_4_0_1 + 0.0507936507936529*G0_0_1_5_0_0 + 0.0507936507936492*G0_0_1_6_0_0 - 1.98095238095237*G0_0_1_7_0_0 - 1.93015873015872*G0_0_1_7_0_1 + 3.5047619047619*G0_0_1_8_0_0 + 2.64126984126984*G0_0_1_8_0_1 - 0.914285714285713*G0_0_1_9_0_0 + 0.406349206349206*G0_0_1_10_1_0 + 0.406349206349205*G0_0_1_10_1_1 - 1.93015873015873*G0_0_1_11_1_0 - 0.406349206349206*G0_0_1_12_1_1 + 0.86349206349206*G0_0_1_13_1_0 - 2.64126984126984*G0_0_1_13_1_1 - 0.0507936507936488*G0_0_1_14_1_0 + 1.93015873015873*G0_0_1_14_1_1 + 0.0507936507936529*G0_0_1_15_1_0 + 0.0507936507936492*G0_0_1_16_1_0 - 1.98095238095237*G0_0_1_17_1_0 - 1.93015873015872*G0_0_1_17_1_1 + 3.5047619047619*G0_0_1_18_1_0 + 2.64126984126984*G0_0_1_18_1_1 - 0.914285714285713*G0_0_1_19_1_0 - 0.406349206349206*G0_1_0_0_0_0 - 0.406349206349205*G0_1_0_0_0_1 + 1.93015873015873*G0_1_0_1_0_0 + 0.406349206349206*G0_1_0_2_0_1 - 0.86349206349206*G0_1_0_3_0_0 + 2.64126984126984*G0_1_0_3_0_1 + 0.0507936507936488*G0_1_0_4_0_0 - 1.93015873015873*G0_1_0_4_0_1 - 0.0507936507936529*G0_1_0_5_0_0 - 0.0507936507936492*G0_1_0_6_0_0 + 1.98095238095237*G0_1_0_7_0_0 + 1.93015873015872*G0_1_0_7_0_1 - 3.5047619047619*G0_1_0_8_0_0 - 2.64126984126984*G0_1_0_8_0_1 + 0.914285714285713*G0_1_0_9_0_0 - 0.406349206349206*G0_1_0_10_1_0 - 0.406349206349205*G0_1_0_10_1_1 + 1.93015873015873*G0_1_0_11_1_0 + 0.406349206349206*G0_1_0_12_1_1 - 0.86349206349206*G0_1_0_13_1_0 + 2.64126984126984*G0_1_0_13_1_1 + 0.0507936507936488*G0_1_0_14_1_0 - 1.93015873015873*G0_1_0_14_1_1 - 0.0507936507936529*G0_1_0_15_1_0 - 0.0507936507936492*G0_1_0_16_1_0 + 1.98095238095237*G0_1_0_17_1_0 + 1.93015873015872*G0_1_0_17_1_1 - 3.5047619047619*G0_1_0_18_1_0 - 2.64126984126984*G0_1_0_18_1_1 + 0.914285714285713*G0_1_0_19_1_0; + A[293] = 0.0; + A[320] = 0.0; + A[459] = 0.0; + A[355] = 0.0; + A[105] = 0.0; + A[33] = -A[506] + 0.34074074074074*G0_0_0_0_0_0 + 0.34074074074074*G0_0_0_0_0_1 - 1.25502645502645*G0_0_0_1_0_0 - 0.34074074074074*G0_0_0_2_0_1 - 0.0126984126984137*G0_0_0_3_0_0 - 2.01269841269841*G0_0_0_3_0_1 - 0.355555555555553*G0_0_0_4_0_0 + 0.73015873015873*G0_0_0_4_0_1 + 0.355555555555554*G0_0_0_5_0_0 + 0.355555555555553*G0_0_0_6_0_0 - 1.08571428571428*G0_0_0_7_0_0 - 0.730158730158728*G0_0_0_7_0_1 + 2*G0_0_0_8_0_0 + 2.01269841269841*G0_0_0_8_0_1 - 0.342857142857141*G0_0_0_9_0_0 + 0.34074074074074*G0_0_0_10_1_0 + 0.34074074074074*G0_0_0_10_1_1 - 1.25502645502645*G0_0_0_11_1_0 - 0.34074074074074*G0_0_0_12_1_1 - 0.0126984126984137*G0_0_0_13_1_0 - 2.01269841269841*G0_0_0_13_1_1 - 0.355555555555553*G0_0_0_14_1_0 + 0.73015873015873*G0_0_0_14_1_1 + 0.355555555555554*G0_0_0_15_1_0 + 0.355555555555553*G0_0_0_16_1_0 - 1.08571428571428*G0_0_0_17_1_0 - 0.730158730158728*G0_0_0_17_1_1 + 2*G0_0_0_18_1_0 + 2.01269841269841*G0_0_0_18_1_1 - 0.342857142857141*G0_0_0_19_1_0; + A[68] = A[533]; + A[163] = A[628]; + A[870] = 0.0; + A[111] = 0.0; + A[142] = 0.0; + A[592] = A[127]; + A[221] = -A[213] - 0.171005291005292*G0_0_0_0_0_0 - 0.171005291005292*G0_0_0_0_0_1 - 0.245502645502641*G0_0_0_1_0_0 + 0.0541798941798927*G0_0_0_2_0_1 + 0.929523809523809*G0_0_0_3_0_0 + 0.21587301587302*G0_0_0_3_0_1 - 0.41142857142857*G0_0_0_4_0_0 + 0.00253968253968433*G0_0_0_4_0_1 + 1.47809523809523*G0_0_0_5_0_0 + 1.3231746031746*G0_0_0_5_0_1 + 0.411428571428571*G0_0_0_6_0_0 - 1.2063492063492*G0_0_0_6_0_1 - 0.203174603174597*G0_0_0_7_0_0 - 0.0482539682539652*G0_0_0_7_0_1 + 0.61968253968253*G0_0_0_8_0_0 - 0.21587301587302*G0_0_0_8_0_1 - 2.40761904761904*G0_0_0_9_0_0 + 0.045714285714281*G0_0_0_9_0_1 - 0.171005291005292*G0_0_0_10_1_0 - 0.171005291005292*G0_0_0_10_1_1 - 0.245502645502641*G0_0_0_11_1_0 + 0.0541798941798927*G0_0_0_12_1_1 + 0.929523809523809*G0_0_0_13_1_0 + 0.21587301587302*G0_0_0_13_1_1 - 0.41142857142857*G0_0_0_14_1_0 + 0.00253968253968433*G0_0_0_14_1_1 + 1.47809523809523*G0_0_0_15_1_0 + 1.3231746031746*G0_0_0_15_1_1 + 0.411428571428571*G0_0_0_16_1_0 - 1.2063492063492*G0_0_0_16_1_1 - 0.203174603174597*G0_0_0_17_1_0 - 0.0482539682539652*G0_0_0_17_1_1 + 0.61968253968253*G0_0_0_18_1_0 - 0.21587301587302*G0_0_0_18_1_1 - 2.40761904761904*G0_0_0_19_1_0 + 0.045714285714281*G0_0_0_19_1_1 - 0.116825396825393*G0_1_0_0_0_0 - 0.116825396825392*G0_1_0_0_0_1 - 0.116825396825396*G0_1_0_2_0_1 + 0.0939682539682569*G0_1_0_3_0_0 - 0.256507936507935*G0_1_0_4_0_0 - 0.0457142857142837*G0_1_0_4_0_1 - 0.139682539682534*G0_1_0_5_0_0 + 0.116825396825392*G0_1_0_5_0_1 + 0.256507936507935*G0_1_0_6_0_0 + 0.116825396825397*G0_1_0_6_0_1 + 0.210793650793645*G0_1_0_7_0_0 - 0.0457142857142807*G0_1_0_7_0_1 - 0.0939682539682538*G0_1_0_8_0_0 + 0.045714285714277*G0_1_0_9_0_0 + 0.0914285714285639*G0_1_0_9_0_1 - 0.116825396825393*G0_1_0_10_1_0 - 0.116825396825392*G0_1_0_10_1_1 - 0.116825396825396*G0_1_0_12_1_1 + 0.0939682539682569*G0_1_0_13_1_0 - 0.256507936507935*G0_1_0_14_1_0 - 0.0457142857142837*G0_1_0_14_1_1 - 0.139682539682534*G0_1_0_15_1_0 + 0.116825396825392*G0_1_0_15_1_1 + 0.256507936507935*G0_1_0_16_1_0 + 0.116825396825397*G0_1_0_16_1_1 + 0.210793650793645*G0_1_0_17_1_0 - 0.0457142857142807*G0_1_0_17_1_1 - 0.0939682539682538*G0_1_0_18_1_0 + 0.045714285714277*G0_1_0_19_1_0 + 0.0914285714285639*G0_1_0_19_1_1; + A[219] = A[221] - 0.223492063492064*G0_0_0_0_0_0 - 0.223492063492064*G0_0_0_0_0_1 + 0.264126984126981*G0_0_0_1_0_0 - 0.85333333333333*G0_0_0_3_0_0 - 0.142222222222225*G0_0_0_3_0_1 - 0.446984126984124*G0_0_0_4_0_1 - 0.853333333333327*G0_0_0_5_0_0 - 0.223492063492057*G0_0_0_5_0_1 + 0.446984126984121*G0_0_0_6_0_1 + 0.711111111111108*G0_0_0_7_0_0 + 0.0812698412698394*G0_0_0_7_0_1 - 0.751746031746025*G0_0_0_8_0_0 + 0.142222222222225*G0_0_0_8_0_1 + 1.70666666666666*G0_0_0_9_0_0 + 0.365714285714285*G0_0_0_9_0_1 - 0.223492063492064*G0_0_0_10_1_0 - 0.223492063492064*G0_0_0_10_1_1 + 0.264126984126981*G0_0_0_11_1_0 - 0.85333333333333*G0_0_0_13_1_0 - 0.142222222222225*G0_0_0_13_1_1 - 0.446984126984124*G0_0_0_14_1_1 - 0.853333333333327*G0_0_0_15_1_0 - 0.223492063492057*G0_0_0_15_1_1 + 0.446984126984121*G0_0_0_16_1_1 + 0.711111111111108*G0_0_0_17_1_0 + 0.0812698412698394*G0_0_0_17_1_1 - 0.751746031746025*G0_0_0_18_1_0 + 0.142222222222225*G0_0_0_18_1_1 + 1.70666666666666*G0_0_0_19_1_0 + 0.365714285714285*G0_0_0_19_1_1 + 0.37079365079365*G0_0_1_0_0_0 + 0.37079365079365*G0_0_1_0_0_1 + 0.0457142857142814*G0_0_1_1_0_0 - 0.193015873015873*G0_0_1_2_0_1 - 0.274285714285714*G0_0_1_3_0_0 + 0.0203174603174522*G0_0_1_3_0_1 - 0.396190476190475*G0_0_1_4_0_0 - 0.452063492063486*G0_0_1_4_0_1 + 0.152380952380952*G0_0_1_5_0_0 - 0.599365079365077*G0_0_1_5_0_1 + 0.396190476190475*G0_0_1_6_0_0 + 0.421587301587301*G0_0_1_6_0_1 - 0.29968253968254*G0_0_1_7_0_0 + 0.452063492063489*G0_0_1_7_0_1 - 0.116825396825391*G0_0_1_8_0_0 - 0.0203174603174524*G0_0_1_8_0_1 + 0.121904761904762*G0_0_1_9_0_0 + 0.37079365079365*G0_0_1_10_1_0 + 0.37079365079365*G0_0_1_10_1_1 + 0.0457142857142814*G0_0_1_11_1_0 - 0.193015873015873*G0_0_1_12_1_1 - 0.274285714285714*G0_0_1_13_1_0 + 0.0203174603174522*G0_0_1_13_1_1 - 0.396190476190475*G0_0_1_14_1_0 - 0.452063492063486*G0_0_1_14_1_1 + 0.152380952380952*G0_0_1_15_1_0 - 0.599365079365077*G0_0_1_15_1_1 + 0.396190476190475*G0_0_1_16_1_0 + 0.421587301587301*G0_0_1_16_1_1 - 0.29968253968254*G0_0_1_17_1_0 + 0.452063492063489*G0_0_1_17_1_1 - 0.116825396825391*G0_0_1_18_1_0 - 0.0203174603174524*G0_0_1_18_1_1 + 0.121904761904762*G0_0_1_19_1_0 + 1.44761904761904*G0_1_0_0_0_0 + 1.44761904761904*G0_1_0_0_0_1 - 0.147301587301588*G0_1_0_1_0_0 - 0.172698412698411*G0_1_0_2_0_1 - 0.416507936507934*G0_1_0_3_0_0 + 0.106666666666662*G0_1_0_3_0_1 - 0.172698412698411*G0_1_0_4_0_0 - 0.670476190476185*G0_1_0_4_0_1 + 0.0507936507936504*G0_1_0_5_0_0 - 2.26031746031744*G0_1_0_5_0_1 + 0.172698412698411*G0_1_0_6_0_0 + 0.985396825396818*G0_1_0_6_0_1 - 2.46349206349205*G0_1_0_7_0_0 - 0.152380952380953*G0_1_0_7_0_1 + 1.1631746031746*G0_1_0_8_0_0 - 0.106666666666662*G0_1_0_8_0_1 + 0.365714285714284*G0_1_0_9_0_0 + 0.822857142857137*G0_1_0_9_0_1 + 1.44761904761904*G0_1_0_10_1_0 + 1.44761904761904*G0_1_0_10_1_1 - 0.147301587301588*G0_1_0_11_1_0 - 0.172698412698411*G0_1_0_12_1_1 - 0.416507936507934*G0_1_0_13_1_0 + 0.106666666666662*G0_1_0_13_1_1 - 0.172698412698411*G0_1_0_14_1_0 - 0.670476190476185*G0_1_0_14_1_1 + 0.0507936507936504*G0_1_0_15_1_0 - 2.26031746031744*G0_1_0_15_1_1 + 0.172698412698411*G0_1_0_16_1_0 + 0.985396825396818*G0_1_0_16_1_1 - 2.46349206349205*G0_1_0_17_1_0 - 0.152380952380953*G0_1_0_17_1_1 + 1.1631746031746*G0_1_0_18_1_0 - 0.106666666666662*G0_1_0_18_1_1 + 0.365714285714284*G0_1_0_19_1_0 + 0.822857142857137*G0_1_0_19_1_1 - 1.00571428571428*G0_1_1_0_0_0 - 1.00571428571428*G0_1_1_0_0_1 - 0.020317460317464*G0_1_1_1_0_0 + 0.416507936507933*G0_1_1_2_0_1 - 0.177777777777777*G0_1_1_3_0_0 + 0.0304761904761857*G0_1_1_3_0_1 - 0.421587301587301*G0_1_1_4_0_0 - 1.06666666666666*G0_1_1_4_0_1 + 0.452063492063493*G0_1_1_5_0_0 + 2.3974603174603*G0_1_1_5_0_1 + 0.421587301587301*G0_1_1_6_0_0 - 1.80825396825396*G0_1_1_6_0_1 + 0.634920634920625*G0_1_1_7_0_0 - 1.31047619047618*G0_1_1_7_0_1 + 0.391111111111116*G0_1_1_8_0_0 - 0.0304761904761857*G0_1_1_8_0_1 - 0.274285714285716*G0_1_1_9_0_0 + 2.37714285714284*G0_1_1_9_0_1 - 1.00571428571428*G0_1_1_10_1_0 - 1.00571428571428*G0_1_1_10_1_1 - 0.020317460317464*G0_1_1_11_1_0 + 0.416507936507933*G0_1_1_12_1_1 - 0.177777777777777*G0_1_1_13_1_0 + 0.0304761904761857*G0_1_1_13_1_1 - 0.421587301587301*G0_1_1_14_1_0 - 1.06666666666666*G0_1_1_14_1_1 + 0.452063492063493*G0_1_1_15_1_0 + 2.3974603174603*G0_1_1_15_1_1 + 0.421587301587301*G0_1_1_16_1_0 - 1.80825396825396*G0_1_1_16_1_1 + 0.634920634920625*G0_1_1_17_1_0 - 1.31047619047618*G0_1_1_17_1_1 + 0.391111111111116*G0_1_1_18_1_0 - 0.0304761904761857*G0_1_1_18_1_1 - 0.274285714285716*G0_1_1_19_1_0 + 2.37714285714284*G0_1_1_19_1_1; + A[715] = A[221] + 0.0541798941798938*G0_0_0_0_0_0 + 0.0541798941798939*G0_0_0_0_0_1 + 0.0677248677248648*G0_0_0_1_0_0 + 0.0982010582010601*G0_0_0_2_0_1 - 0.457142857142857*G0_0_0_3_0_0 - 0.152380952380957*G0_0_0_3_0_1 + 0.335238095238098*G0_0_0_4_0_0 - 0.39619047619047*G0_0_0_5_0_0 - 0.365714285714281*G0_0_0_5_0_1 - 0.335238095238098*G0_0_0_6_0_0 + 0.213333333333327*G0_0_0_6_0_1 + 0.0304761904761882*G0_0_0_7_0_0 - 0.152380952380947*G0_0_0_8_0_0 + 0.152380952380957*G0_0_0_8_0_1 + 0.853333333333328*G0_0_0_9_0_0 + 0.0541798941798938*G0_0_0_10_1_0 + 0.0541798941798939*G0_0_0_10_1_1 + 0.0677248677248648*G0_0_0_11_1_0 + 0.0982010582010601*G0_0_0_12_1_1 - 0.457142857142857*G0_0_0_13_1_0 - 0.152380952380957*G0_0_0_13_1_1 + 0.335238095238098*G0_0_0_14_1_0 - 0.39619047619047*G0_0_0_15_1_0 - 0.365714285714281*G0_0_0_15_1_1 - 0.335238095238098*G0_0_0_16_1_0 + 0.213333333333327*G0_0_0_16_1_1 + 0.0304761904761882*G0_0_0_17_1_0 - 0.152380952380947*G0_0_0_18_1_0 + 0.152380952380957*G0_0_0_18_1_1 + 0.853333333333328*G0_0_0_19_1_0 - 0.0965079365079405*G0_0_1_1_0_0 + 0.0965079365079332*G0_0_1_2_0_1 + 0.0253968253968263*G0_0_1_3_0_0 - 0.071111111111119*G0_0_1_3_0_1 + 0.0711111111111084*G0_0_1_4_0_0 - 0.02539682539682*G0_0_1_4_0_1 + 0.218412698412696*G0_0_1_5_0_0 + 0.218412698412697*G0_0_1_5_0_1 - 0.0711111111111084*G0_0_1_6_0_0 - 0.31492063492063*G0_0_1_6_0_1 - 0.218412698412697*G0_0_1_7_0_0 - 0.218412698412697*G0_0_1_7_0_1 + 0.314920634920637*G0_0_1_8_0_0 + 0.0711111111111191*G0_0_1_8_0_1 - 0.243809523809523*G0_0_1_9_0_0 + 0.243809523809517*G0_0_1_9_0_1 - 0.0965079365079405*G0_0_1_11_1_0 + 0.0965079365079332*G0_0_1_12_1_1 + 0.0253968253968263*G0_0_1_13_1_0 - 0.071111111111119*G0_0_1_13_1_1 + 0.0711111111111084*G0_0_1_14_1_0 - 0.02539682539682*G0_0_1_14_1_1 + 0.218412698412696*G0_0_1_15_1_0 + 0.218412698412697*G0_0_1_15_1_1 - 0.0711111111111084*G0_0_1_16_1_0 - 0.31492063492063*G0_0_1_16_1_1 - 0.218412698412697*G0_0_1_17_1_0 - 0.218412698412697*G0_0_1_17_1_1 + 0.314920634920637*G0_0_1_18_1_0 + 0.0711111111111191*G0_0_1_18_1_1 - 0.243809523809523*G0_0_1_19_1_0 + 0.243809523809517*G0_0_1_19_1_1 - 0.208253968253967*G0_1_0_1_0_0 + 0.208253968253969*G0_1_0_2_0_1 - 0.025396825396828*G0_1_0_3_0_0 - 0.233650793650795*G0_1_0_3_0_1 + 0.233650793650796*G0_1_0_4_0_0 + 0.0253968253968258*G0_1_0_4_0_1 + 0.391111111111109*G0_1_0_5_0_0 + 0.391111111111111*G0_1_0_5_0_1 - 0.233650793650796*G0_1_0_6_0_0 - 0.599365079365079*G0_1_0_6_0_1 - 0.391111111111107*G0_1_0_7_0_0 - 0.391111111111111*G0_1_0_7_0_1 + 0.599365079365077*G0_1_0_8_0_0 + 0.233650793650795*G0_1_0_8_0_1 - 0.365714285714281*G0_1_0_9_0_0 + 0.365714285714285*G0_1_0_9_0_1 - 0.208253968253967*G0_1_0_11_1_0 + 0.208253968253969*G0_1_0_12_1_1 - 0.025396825396828*G0_1_0_13_1_0 - 0.233650793650795*G0_1_0_13_1_1 + 0.233650793650796*G0_1_0_14_1_0 + 0.0253968253968258*G0_1_0_14_1_1 + 0.391111111111109*G0_1_0_15_1_0 + 0.391111111111111*G0_1_0_15_1_1 - 0.233650793650796*G0_1_0_16_1_0 - 0.599365079365079*G0_1_0_16_1_1 - 0.391111111111107*G0_1_0_17_1_0 - 0.391111111111111*G0_1_0_17_1_1 + 0.599365079365077*G0_1_0_18_1_0 + 0.233650793650795*G0_1_0_18_1_1 - 0.365714285714281*G0_1_0_19_1_0 + 0.365714285714285*G0_1_0_19_1_1 - 0.0541798941798914*G0_1_1_0_0_0 - 0.0541798941798913*G0_1_1_0_0_1 - 0.09820105820106*G0_1_1_1_0_0 - 0.0677248677248681*G0_1_1_2_0_1 - 0.335238095238098*G0_1_1_3_0_1 + 0.152380952380953*G0_1_1_4_0_0 + 0.457142857142858*G0_1_1_4_0_1 - 0.030476190476195*G0_1_1_5_0_1 - 0.152380952380953*G0_1_1_6_0_0 + 0.152380952380955*G0_1_1_6_0_1 + 0.36571428571428*G0_1_1_7_0_0 + 0.396190476190474*G0_1_1_7_0_1 - 0.213333333333329*G0_1_1_8_0_0 + 0.335238095238098*G0_1_1_8_0_1 - 0.853333333333332*G0_1_1_9_0_1 - 0.0541798941798914*G0_1_1_10_1_0 - 0.0541798941798913*G0_1_1_10_1_1 - 0.09820105820106*G0_1_1_11_1_0 - 0.0677248677248681*G0_1_1_12_1_1 - 0.335238095238098*G0_1_1_13_1_1 + 0.152380952380953*G0_1_1_14_1_0 + 0.457142857142858*G0_1_1_14_1_1 - 0.030476190476195*G0_1_1_15_1_1 - 0.152380952380953*G0_1_1_16_1_0 + 0.152380952380955*G0_1_1_16_1_1 + 0.36571428571428*G0_1_1_17_1_0 + 0.396190476190474*G0_1_1_17_1_1 - 0.213333333333329*G0_1_1_18_1_0 + 0.335238095238098*G0_1_1_18_1_1 - 0.853333333333332*G0_1_1_19_1_1; + A[625] = -A[715] - 0.116825396825395*G0_1_0_0_0_0 - 0.116825396825395*G0_1_0_0_0_1 - 0.116825396825392*G0_1_0_1_0_0 - 0.0457142857142883*G0_1_0_3_0_0 - 0.25650793650793*G0_1_0_3_0_1 + 0.0939682539682499*G0_1_0_4_0_1 - 0.0457142857142838*G0_1_0_5_0_0 + 0.210793650793647*G0_1_0_5_0_1 - 0.0939682539682541*G0_1_0_6_0_1 + 0.116825396825398*G0_1_0_7_0_0 - 0.139682539682534*G0_1_0_7_0_1 + 0.11682539682539*G0_1_0_8_0_0 + 0.25650793650793*G0_1_0_8_0_1 + 0.091428571428572*G0_1_0_9_0_0 + 0.0457142857142838*G0_1_0_9_0_1 - 0.116825396825395*G0_1_0_10_1_0 - 0.116825396825395*G0_1_0_10_1_1 - 0.116825396825392*G0_1_0_11_1_0 - 0.0457142857142883*G0_1_0_13_1_0 - 0.25650793650793*G0_1_0_13_1_1 + 0.0939682539682499*G0_1_0_14_1_1 - 0.0457142857142838*G0_1_0_15_1_0 + 0.210793650793647*G0_1_0_15_1_1 - 0.0939682539682541*G0_1_0_16_1_1 + 0.116825396825398*G0_1_0_17_1_0 - 0.139682539682534*G0_1_0_17_1_1 + 0.11682539682539*G0_1_0_18_1_0 + 0.25650793650793*G0_1_0_18_1_1 + 0.091428571428572*G0_1_0_19_1_0 + 0.0457142857142838*G0_1_0_19_1_1 - 0.171005291005289*G0_1_1_0_0_0 - 0.171005291005288*G0_1_1_0_0_1 + 0.0541798941798978*G0_1_1_1_0_0 - 0.245502645502643*G0_1_1_2_0_1 + 0.00253968253968011*G0_1_1_3_0_0 - 0.411428571428564*G0_1_1_3_0_1 + 0.215873015873017*G0_1_1_4_0_0 + 0.929523809523802*G0_1_1_4_0_1 - 0.0482539682539697*G0_1_1_5_0_0 - 0.203174603174606*G0_1_1_5_0_1 - 0.215873015873017*G0_1_1_6_0_0 + 0.619682539682538*G0_1_1_6_0_1 + 1.3231746031746*G0_1_1_7_0_0 + 1.47809523809523*G0_1_1_7_0_1 - 1.2063492063492*G0_1_1_8_0_0 + 0.411428571428564*G0_1_1_8_0_1 + 0.0457142857142895*G0_1_1_9_0_0 - 2.40761904761903*G0_1_1_9_0_1 - 0.171005291005289*G0_1_1_10_1_0 - 0.171005291005288*G0_1_1_10_1_1 + 0.0541798941798978*G0_1_1_11_1_0 - 0.245502645502643*G0_1_1_12_1_1 + 0.00253968253968011*G0_1_1_13_1_0 - 0.411428571428564*G0_1_1_13_1_1 + 0.215873015873017*G0_1_1_14_1_0 + 0.929523809523802*G0_1_1_14_1_1 - 0.0482539682539697*G0_1_1_15_1_0 - 0.203174603174606*G0_1_1_15_1_1 - 0.215873015873017*G0_1_1_16_1_0 + 0.619682539682538*G0_1_1_16_1_1 + 1.3231746031746*G0_1_1_17_1_0 + 1.47809523809523*G0_1_1_17_1_1 - 1.2063492063492*G0_1_1_18_1_0 + 0.411428571428564*G0_1_1_18_1_1 + 0.0457142857142895*G0_1_1_19_1_0 - 2.40761904761903*G0_1_1_19_1_1; + A[160] = A[625]; + A[305] = A[625] - 0.132063492063492*G0_0_1_0_0_0 - 0.132063492063492*G0_0_1_0_0_1 + 0.0152380952380984*G0_0_1_1_0_0 + 0.0203174603174584*G0_0_1_2_0_1 - 0.043174603174603*G0_0_1_3_0_0 - 0.0609523809523767*G0_0_1_3_0_1 + 0.0330158730158684*G0_0_1_4_0_0 + 0.0457142857142817*G0_0_1_4_0_1 - 0.00253968253968376*G0_0_1_5_0_0 + 0.193015873015871*G0_0_1_5_0_1 - 0.0330158730158683*G0_0_1_6_0_0 - 0.0812698412698372*G0_0_1_6_0_1 + 0.271746031746036*G0_0_1_7_0_0 + 0.0761904761904804*G0_0_1_7_0_1 - 0.154920634920642*G0_0_1_8_0_0 + 0.0609523809523765*G0_0_1_8_0_1 + 0.0457142857142867*G0_0_1_9_0_0 - 0.121904761904762*G0_0_1_9_0_1 - 0.132063492063492*G0_0_1_10_1_0 - 0.132063492063492*G0_0_1_10_1_1 + 0.0152380952380984*G0_0_1_11_1_0 + 0.0203174603174584*G0_0_1_12_1_1 - 0.043174603174603*G0_0_1_13_1_0 - 0.0609523809523767*G0_0_1_13_1_1 + 0.0330158730158684*G0_0_1_14_1_0 + 0.0457142857142817*G0_0_1_14_1_1 - 0.00253968253968376*G0_0_1_15_1_0 + 0.193015873015871*G0_0_1_15_1_1 - 0.0330158730158683*G0_0_1_16_1_0 - 0.0812698412698372*G0_0_1_16_1_1 + 0.271746031746036*G0_0_1_17_1_0 + 0.0761904761904804*G0_0_1_17_1_1 - 0.154920634920642*G0_0_1_18_1_0 + 0.0609523809523765*G0_0_1_18_1_1 + 0.0457142857142867*G0_0_1_19_1_0 - 0.121904761904762*G0_0_1_19_1_1 + 0.132063492063492*G0_1_0_0_0_0 + 0.132063492063492*G0_1_0_0_0_1 - 0.0152380952380982*G0_1_0_1_0_0 - 0.0203174603174583*G0_1_0_2_0_1 + 0.043174603174603*G0_1_0_3_0_0 + 0.060952380952377*G0_1_0_3_0_1 - 0.0330158730158684*G0_1_0_4_0_0 - 0.045714285714282*G0_1_0_4_0_1 + 0.00253968253968372*G0_1_0_5_0_0 - 0.193015873015871*G0_1_0_5_0_1 + 0.0330158730158684*G0_1_0_6_0_0 + 0.0812698412698372*G0_1_0_6_0_1 - 0.271746031746036*G0_1_0_7_0_0 - 0.0761904761904805*G0_1_0_7_0_1 + 0.154920634920641*G0_1_0_8_0_0 - 0.0609523809523769*G0_1_0_8_0_1 - 0.0457142857142866*G0_1_0_9_0_0 + 0.121904761904763*G0_1_0_9_0_1 + 0.132063492063492*G0_1_0_10_1_0 + 0.132063492063492*G0_1_0_10_1_1 - 0.0152380952380982*G0_1_0_11_1_0 - 0.0203174603174583*G0_1_0_12_1_1 + 0.043174603174603*G0_1_0_13_1_0 + 0.060952380952377*G0_1_0_13_1_1 - 0.0330158730158684*G0_1_0_14_1_0 - 0.045714285714282*G0_1_0_14_1_1 + 0.00253968253968372*G0_1_0_15_1_0 - 0.193015873015871*G0_1_0_15_1_1 + 0.0330158730158684*G0_1_0_16_1_0 + 0.0812698412698372*G0_1_0_16_1_1 - 0.271746031746036*G0_1_0_17_1_0 - 0.0761904761904805*G0_1_0_17_1_1 + 0.154920634920641*G0_1_0_18_1_0 - 0.0609523809523769*G0_1_0_18_1_1 - 0.0457142857142866*G0_1_0_19_1_0 + 0.121904761904763*G0_1_0_19_1_1; + A[770] = A[305]; + A[173] = 0.0; + A[617] = -A[242] + 0.34074074074074*G0_1_1_0_0_0 + 0.34074074074074*G0_1_1_0_0_1 - 0.340740740740741*G0_1_1_1_0_0 - 1.25502645502645*G0_1_1_2_0_1 + 0.730158730158726*G0_1_1_3_0_0 - 0.355555555555557*G0_1_1_3_0_1 - 2.0126984126984*G0_1_1_4_0_0 - 0.0126984126984128*G0_1_1_4_0_1 - 0.730158730158726*G0_1_1_5_0_0 - 1.08571428571428*G0_1_1_5_0_1 + 2.0126984126984*G0_1_1_6_0_0 + 1.99999999999999*G0_1_1_6_0_1 + 0.355555555555553*G0_1_1_7_0_1 + 0.355555555555557*G0_1_1_8_0_1 - 0.34285714285714*G0_1_1_9_0_1 + 0.34074074074074*G0_1_1_10_1_0 + 0.34074074074074*G0_1_1_10_1_1 - 0.340740740740741*G0_1_1_11_1_0 - 1.25502645502645*G0_1_1_12_1_1 + 0.730158730158726*G0_1_1_13_1_0 - 0.355555555555557*G0_1_1_13_1_1 - 2.0126984126984*G0_1_1_14_1_0 - 0.0126984126984128*G0_1_1_14_1_1 - 0.730158730158726*G0_1_1_15_1_0 - 1.08571428571428*G0_1_1_15_1_1 + 2.0126984126984*G0_1_1_16_1_0 + 1.99999999999999*G0_1_1_16_1_1 + 0.355555555555553*G0_1_1_17_1_1 + 0.355555555555557*G0_1_1_18_1_1 - 0.34285714285714*G0_1_1_19_1_1; + A[541] = 0.0; + A[497] = 0.017010582010582*G0_0_1_0_0_0 + 0.017010582010582*G0_0_1_0_0_1 - 0.137962962962963*G0_0_1_1_0_0 - 0.137962962962962*G0_0_1_2_0_1 + 0.109444444444444*G0_0_1_3_0_0 - 0.197222222222223*G0_0_1_3_0_1 - 0.197222222222221*G0_0_1_4_0_0 + 0.109444444444444*G0_0_1_4_0_1 - 0.0532539682539681*G0_0_1_5_0_0 - 0.0366666666666665*G0_0_1_5_0_1 + 0.197222222222221*G0_0_1_6_0_0 + 0.157619047619047*G0_0_1_6_0_1 - 0.0366666666666668*G0_0_1_7_0_0 - 0.0532539682539685*G0_0_1_7_0_1 + 0.157619047619048*G0_0_1_8_0_0 + 0.197222222222223*G0_0_1_8_0_1 - 0.0561904761904755*G0_0_1_9_0_0 - 0.0561904761904759*G0_0_1_9_0_1 + 0.017010582010582*G0_0_1_10_1_0 + 0.017010582010582*G0_0_1_10_1_1 - 0.137962962962963*G0_0_1_11_1_0 - 0.137962962962962*G0_0_1_12_1_1 + 0.109444444444444*G0_0_1_13_1_0 - 0.197222222222223*G0_0_1_13_1_1 - 0.197222222222221*G0_0_1_14_1_0 + 0.109444444444444*G0_0_1_14_1_1 - 0.0532539682539681*G0_0_1_15_1_0 - 0.0366666666666665*G0_0_1_15_1_1 + 0.197222222222221*G0_0_1_16_1_0 + 0.157619047619047*G0_0_1_16_1_1 - 0.0366666666666668*G0_0_1_17_1_0 - 0.0532539682539685*G0_0_1_17_1_1 + 0.157619047619048*G0_0_1_18_1_0 + 0.197222222222223*G0_0_1_18_1_1 - 0.0561904761904755*G0_0_1_19_1_0 - 0.0561904761904759*G0_0_1_19_1_1; + A[30] = -A[497] - 0.137962962962963*G0_0_0_0_0_0 - 0.137962962962963*G0_0_0_0_0_1 + 0.137962962962963*G0_0_0_1_0_0 + 0.017010582010582*G0_0_0_2_0_1 + 0.0396031746031743*G0_0_0_3_0_0 + 0.197222222222222*G0_0_0_3_0_1 - 0.0165873015873017*G0_0_0_4_0_0 - 0.0532539682539684*G0_0_0_4_0_1 - 0.0396031746031746*G0_0_0_5_0_0 + 0.157619047619048*G0_0_0_5_0_1 + 0.0165873015873017*G0_0_0_6_0_0 - 0.0366666666666669*G0_0_0_6_0_1 + 0.306666666666666*G0_0_0_7_0_0 + 0.109444444444444*G0_0_0_7_0_1 - 0.306666666666666*G0_0_0_8_0_0 - 0.197222222222222*G0_0_0_8_0_1 - 0.0561904761904752*G0_0_0_9_0_1 - 0.137962962962963*G0_0_0_10_1_0 - 0.137962962962963*G0_0_0_10_1_1 + 0.137962962962963*G0_0_0_11_1_0 + 0.017010582010582*G0_0_0_12_1_1 + 0.0396031746031743*G0_0_0_13_1_0 + 0.197222222222222*G0_0_0_13_1_1 - 0.0165873015873017*G0_0_0_14_1_0 - 0.0532539682539684*G0_0_0_14_1_1 - 0.0396031746031746*G0_0_0_15_1_0 + 0.157619047619048*G0_0_0_15_1_1 + 0.0165873015873017*G0_0_0_16_1_0 - 0.0366666666666669*G0_0_0_16_1_1 + 0.306666666666666*G0_0_0_17_1_0 + 0.109444444444444*G0_0_0_17_1_1 - 0.306666666666666*G0_0_0_18_1_0 - 0.197222222222222*G0_0_0_18_1_1 - 0.0561904761904752*G0_0_0_19_1_1 - 0.120952380952381*G0_0_1_0_0_0 - 0.120952380952381*G0_0_1_0_0_1 - 0.12095238095238*G0_0_1_2_0_1 + 0.149047619047618*G0_0_1_3_0_0 - 0.213809523809523*G0_0_1_4_0_0 + 0.056190476190476*G0_0_1_4_0_1 - 0.0928571428571428*G0_0_1_5_0_0 + 0.120952380952381*G0_0_1_5_0_1 + 0.213809523809523*G0_0_1_6_0_0 + 0.12095238095238*G0_0_1_6_0_1 + 0.269999999999999*G0_0_1_7_0_0 + 0.0561904761904751*G0_0_1_7_0_1 - 0.149047619047617*G0_0_1_8_0_0 - 0.0561904761904752*G0_0_1_9_0_0 - 0.112380952380951*G0_0_1_9_0_1 - 0.120952380952381*G0_0_1_10_1_0 - 0.120952380952381*G0_0_1_10_1_1 - 0.12095238095238*G0_0_1_12_1_1 + 0.149047619047618*G0_0_1_13_1_0 - 0.213809523809523*G0_0_1_14_1_0 + 0.056190476190476*G0_0_1_14_1_1 - 0.0928571428571428*G0_0_1_15_1_0 + 0.120952380952381*G0_0_1_15_1_1 + 0.213809523809523*G0_0_1_16_1_0 + 0.12095238095238*G0_0_1_16_1_1 + 0.269999999999999*G0_0_1_17_1_0 + 0.0561904761904751*G0_0_1_17_1_1 - 0.149047619047617*G0_0_1_18_1_0 - 0.0561904761904752*G0_0_1_19_1_0 - 0.112380952380951*G0_0_1_19_1_1; + A[2] = -A[497] - 0.12095238095238*G0_0_1_0_0_0 - 0.12095238095238*G0_0_1_0_0_1 - 0.120952380952381*G0_0_1_1_0_0 + 0.0561904761904756*G0_0_1_3_0_0 - 0.213809523809524*G0_0_1_3_0_1 + 0.149047619047619*G0_0_1_4_0_1 + 0.0561904761904757*G0_0_1_5_0_0 + 0.269999999999999*G0_0_1_5_0_1 - 0.149047619047618*G0_0_1_6_0_1 + 0.12095238095238*G0_0_1_7_0_0 - 0.092857142857143*G0_0_1_7_0_1 + 0.120952380952381*G0_0_1_8_0_0 + 0.213809523809524*G0_0_1_8_0_1 - 0.112380952380951*G0_0_1_9_0_0 - 0.0561904761904757*G0_0_1_9_0_1 - 0.12095238095238*G0_0_1_10_1_0 - 0.12095238095238*G0_0_1_10_1_1 - 0.120952380952381*G0_0_1_11_1_0 + 0.0561904761904756*G0_0_1_13_1_0 - 0.213809523809524*G0_0_1_13_1_1 + 0.149047619047619*G0_0_1_14_1_1 + 0.0561904761904757*G0_0_1_15_1_0 + 0.269999999999999*G0_0_1_15_1_1 - 0.149047619047618*G0_0_1_16_1_1 + 0.12095238095238*G0_0_1_17_1_0 - 0.092857142857143*G0_0_1_17_1_1 + 0.120952380952381*G0_0_1_18_1_0 + 0.213809523809524*G0_0_1_18_1_1 - 0.112380952380951*G0_0_1_19_1_0 - 0.0561904761904757*G0_0_1_19_1_1 - 0.137962962962963*G0_1_1_0_0_0 - 0.137962962962963*G0_1_1_0_0_1 + 0.017010582010582*G0_1_1_1_0_0 + 0.137962962962963*G0_1_1_2_0_1 - 0.0532539682539688*G0_1_1_3_0_0 - 0.0165873015873017*G0_1_1_3_0_1 + 0.197222222222223*G0_1_1_4_0_0 + 0.0396031746031749*G0_1_1_4_0_1 + 0.109444444444445*G0_1_1_5_0_0 + 0.306666666666666*G0_1_1_5_0_1 - 0.197222222222223*G0_1_1_6_0_0 - 0.306666666666667*G0_1_1_6_0_1 + 0.157619047619047*G0_1_1_7_0_0 - 0.0396031746031744*G0_1_1_7_0_1 - 0.0366666666666664*G0_1_1_8_0_0 + 0.0165873015873017*G0_1_1_8_0_1 - 0.0561904761904758*G0_1_1_9_0_0 - 0.137962962962963*G0_1_1_10_1_0 - 0.137962962962963*G0_1_1_10_1_1 + 0.017010582010582*G0_1_1_11_1_0 + 0.137962962962963*G0_1_1_12_1_1 - 0.0532539682539688*G0_1_1_13_1_0 - 0.0165873015873017*G0_1_1_13_1_1 + 0.197222222222223*G0_1_1_14_1_0 + 0.0396031746031749*G0_1_1_14_1_1 + 0.109444444444445*G0_1_1_15_1_0 + 0.306666666666666*G0_1_1_15_1_1 - 0.197222222222223*G0_1_1_16_1_0 - 0.306666666666667*G0_1_1_16_1_1 + 0.157619047619047*G0_1_1_17_1_0 - 0.0396031746031744*G0_1_1_17_1_1 - 0.0366666666666664*G0_1_1_18_1_0 + 0.0165873015873017*G0_1_1_18_1_1 - 0.0561904761904758*G0_1_1_19_1_0; + A[538] = A[72] + 0.121904761904762*G0_1_0_0_0_0 + 0.121904761904762*G0_1_0_0_0_1 - 0.121904761904761*G0_1_0_1_0_0 - 0.121904761904761*G0_1_0_3_0_1 - 0.121904761904765*G0_1_0_5_0_1 - 0.365714285714283*G0_1_0_7_0_0 - 0.243809523809523*G0_1_0_7_0_1 + 0.365714285714282*G0_1_0_8_0_0 + 0.121904761904761*G0_1_0_8_0_1 + 0.243809523809527*G0_1_0_9_0_1 + 0.121904761904762*G0_1_0_10_1_0 + 0.121904761904762*G0_1_0_10_1_1 - 0.121904761904761*G0_1_0_11_1_0 - 0.121904761904761*G0_1_0_13_1_1 - 0.121904761904765*G0_1_0_15_1_1 - 0.365714285714283*G0_1_0_17_1_0 - 0.243809523809523*G0_1_0_17_1_1 + 0.365714285714282*G0_1_0_18_1_0 + 0.121904761904761*G0_1_0_18_1_1 + 0.243809523809527*G0_1_0_19_1_1 - 0.228571428571427*G0_1_1_0_0_0 - 0.228571428571427*G0_1_1_0_0_1 - 0.35047619047619*G0_1_1_1_0_0 - 0.0304761904761895*G0_1_1_3_0_0 - 0.655238095238093*G0_1_1_3_0_1 + 0.27428571428571*G0_1_1_4_0_1 - 0.0304761904761937*G0_1_1_5_0_0 + 0.502857142857137*G0_1_1_5_0_1 - 0.274285714285706*G0_1_1_6_0_1 + 0.106666666666666*G0_1_1_7_0_0 - 0.426666666666665*G0_1_1_7_0_1 + 0.472380952380951*G0_1_1_8_0_0 + 0.655238095238093*G0_1_1_8_0_1 + 0.0609523809523831*G0_1_1_9_0_0 + 0.152380952380956*G0_1_1_9_0_1 - 0.228571428571427*G0_1_1_10_1_0 - 0.228571428571427*G0_1_1_10_1_1 - 0.35047619047619*G0_1_1_11_1_0 - 0.0304761904761895*G0_1_1_13_1_0 - 0.655238095238093*G0_1_1_13_1_1 + 0.27428571428571*G0_1_1_14_1_1 - 0.0304761904761937*G0_1_1_15_1_0 + 0.502857142857137*G0_1_1_15_1_1 - 0.274285714285706*G0_1_1_16_1_1 + 0.106666666666666*G0_1_1_17_1_0 - 0.426666666666665*G0_1_1_17_1_1 + 0.472380952380951*G0_1_1_18_1_0 + 0.655238095238093*G0_1_1_18_1_1 + 0.0609523809523831*G0_1_1_19_1_0 + 0.152380952380956*G0_1_1_19_1_1; + A[692] = 0.0; + A[269] = 0.0; + A[294] = 0.0; + A[443] = 0.0; + A[472] = A[7]; + A[392] = A[857]; + A[806] = -A[101] - 0.778835978835978*G0_0_0_0_0_0 - 0.778835978835977*G0_0_0_0_0_1 + 2.7089947089947*G0_0_0_1_0_0 + 0.677248677248675*G0_0_0_2_0_1 + 0.406349206349207*G0_0_0_3_0_0 + 4.92698412698411*G0_0_0_3_0_1 + 0.101587301587299*G0_0_0_4_0_0 - 2.38730158730158*G0_0_0_4_0_1 - 1.62539682539682*G0_0_0_5_0_0 + 0.0507936507936542*G0_0_0_5_0_1 - 0.101587301587299*G0_0_0_6_0_0 + 0.0507936507936481*G0_0_0_6_0_1 + 1.32063492063492*G0_0_0_7_0_0 - 0.355555555555553*G0_0_0_7_0_1 - 3.25079365079364*G0_0_0_8_0_0 - 4.92698412698411*G0_0_0_8_0_1 + 1.21904761904761*G0_0_0_9_0_0 + 2.74285714285713*G0_0_0_9_0_1 - 0.778835978835978*G0_0_0_10_1_0 - 0.778835978835977*G0_0_0_10_1_1 + 2.7089947089947*G0_0_0_11_1_0 + 0.677248677248675*G0_0_0_12_1_1 + 0.406349206349207*G0_0_0_13_1_0 + 4.92698412698411*G0_0_0_13_1_1 + 0.101587301587299*G0_0_0_14_1_0 - 2.38730158730158*G0_0_0_14_1_1 - 1.62539682539682*G0_0_0_15_1_0 + 0.0507936507936542*G0_0_0_15_1_1 - 0.101587301587299*G0_0_0_16_1_0 + 0.0507936507936481*G0_0_0_16_1_1 + 1.32063492063492*G0_0_0_17_1_0 - 0.355555555555553*G0_0_0_17_1_1 - 3.25079365079364*G0_0_0_18_1_0 - 4.92698412698411*G0_0_0_18_1_1 + 1.21904761904761*G0_0_0_19_1_0 + 2.74285714285713*G0_0_0_19_1_1 - 0.406349206349205*G0_0_1_0_0_0 - 0.406349206349204*G0_0_1_0_0_1 + 1.93015873015873*G0_0_1_1_0_0 + 0.406349206349206*G0_0_1_2_0_1 - 0.863492063492061*G0_0_1_3_0_0 + 2.64126984126984*G0_0_1_3_0_1 + 0.050793650793649*G0_0_1_4_0_0 - 1.93015873015873*G0_0_1_4_0_1 - 0.0507936507936531*G0_0_1_5_0_0 - 0.0507936507936494*G0_0_1_6_0_0 + 1.98095238095237*G0_0_1_7_0_0 + 1.93015873015872*G0_0_1_7_0_1 - 3.5047619047619*G0_0_1_8_0_0 - 2.64126984126984*G0_0_1_8_0_1 + 0.914285714285714*G0_0_1_9_0_0 - 0.406349206349205*G0_0_1_10_1_0 - 0.406349206349204*G0_0_1_10_1_1 + 1.93015873015873*G0_0_1_11_1_0 + 0.406349206349206*G0_0_1_12_1_1 - 0.863492063492061*G0_0_1_13_1_0 + 2.64126984126984*G0_0_1_13_1_1 + 0.050793650793649*G0_0_1_14_1_0 - 1.93015873015873*G0_0_1_14_1_1 - 0.0507936507936531*G0_0_1_15_1_0 - 0.0507936507936494*G0_0_1_16_1_0 + 1.98095238095237*G0_0_1_17_1_0 + 1.93015873015872*G0_0_1_17_1_1 - 3.5047619047619*G0_0_1_18_1_0 - 2.64126984126984*G0_0_1_18_1_1 + 0.914285714285714*G0_0_1_19_1_0; + A[279] = -A[806] - 5.24190476190474*G0_0_0_0_0_0 - 5.24190476190474*G0_0_0_0_0_1 + 5.24190476190474*G0_0_0_1_0_0 + 1.34095238095237*G0_0_0_2_0_1 + 2.31619047619046*G0_0_0_3_0_0 + 8.89904761904758*G0_0_0_3_0_1 - 0.487619047619049*G0_0_0_4_0_0 - 3.1695238095238*G0_0_0_4_0_1 - 2.31619047619047*G0_0_0_5_0_0 + 6.58285714285712*G0_0_0_5_0_1 + 0.48761904761905*G0_0_0_6_0_0 - 2.68190476190475*G0_0_0_6_0_1 + 8.89904761904758*G0_0_0_7_0_0 - 8.89904761904758*G0_0_0_8_0_0 - 8.89904761904758*G0_0_0_8_0_1 + 3.16952380952381*G0_0_0_9_0_1 - 5.24190476190474*G0_0_0_10_1_0 - 5.24190476190474*G0_0_0_10_1_1 + 5.24190476190474*G0_0_0_11_1_0 + 1.34095238095237*G0_0_0_12_1_1 + 2.31619047619046*G0_0_0_13_1_0 + 8.89904761904758*G0_0_0_13_1_1 - 0.487619047619049*G0_0_0_14_1_0 - 3.1695238095238*G0_0_0_14_1_1 - 2.31619047619047*G0_0_0_15_1_0 + 6.58285714285712*G0_0_0_15_1_1 + 0.48761904761905*G0_0_0_16_1_0 - 2.68190476190475*G0_0_0_16_1_1 + 8.89904761904758*G0_0_0_17_1_0 - 8.89904761904758*G0_0_0_18_1_0 - 8.89904761904758*G0_0_0_18_1_1 + 3.16952380952381*G0_0_0_19_1_1 - 0.609523809523806*G0_0_1_0_0_0 - 0.609523809523805*G0_0_1_0_0_1 + 4.63238095238093*G0_0_1_1_0_0 + 0.670476190476186*G0_0_1_2_0_1 + 2.62095238095237*G0_0_1_3_0_0 + 9.20380952380948*G0_0_1_3_0_1 - 0.243809523809524*G0_0_1_4_0_0 - 2.86476190476189*G0_0_1_4_0_1 + 0.304761904761899*G0_0_1_5_0_0 + 0.243809523809524*G0_0_1_6_0_0 - 0.0609523809523776*G0_0_1_6_0_1 + 2.43809523809522*G0_0_1_7_0_0 + 2.74285714285713*G0_0_1_7_0_1 - 6.46095238095235*G0_0_1_8_0_0 - 9.20380952380948*G0_0_1_8_0_1 - 2.92571428571426*G0_0_1_9_0_0 + 0.121904761904766*G0_0_1_9_0_1 - 0.609523809523806*G0_0_1_10_1_0 - 0.609523809523805*G0_0_1_10_1_1 + 4.63238095238093*G0_0_1_11_1_0 + 0.670476190476186*G0_0_1_12_1_1 + 2.62095238095237*G0_0_1_13_1_0 + 9.20380952380948*G0_0_1_13_1_1 - 0.243809523809524*G0_0_1_14_1_0 - 2.86476190476189*G0_0_1_14_1_1 + 0.304761904761899*G0_0_1_15_1_0 + 0.243809523809524*G0_0_1_16_1_0 - 0.0609523809523776*G0_0_1_16_1_1 + 2.43809523809522*G0_0_1_17_1_0 + 2.74285714285713*G0_0_1_17_1_1 - 6.46095238095235*G0_0_1_18_1_0 - 9.20380952380948*G0_0_1_18_1_1 - 2.92571428571426*G0_0_1_19_1_0 + 0.121904761904766*G0_0_1_19_1_1 - 0.609523809523806*G0_1_0_0_0_0 - 0.609523809523805*G0_1_0_0_0_1 + 4.63238095238093*G0_1_0_1_0_0 + 0.670476190476186*G0_1_0_2_0_1 + 2.62095238095237*G0_1_0_3_0_0 + 9.20380952380948*G0_1_0_3_0_1 - 0.243809523809524*G0_1_0_4_0_0 - 2.86476190476189*G0_1_0_4_0_1 + 0.304761904761899*G0_1_0_5_0_0 + 0.243809523809524*G0_1_0_6_0_0 - 0.0609523809523777*G0_1_0_6_0_1 + 2.43809523809522*G0_1_0_7_0_0 + 2.74285714285713*G0_1_0_7_0_1 - 6.46095238095235*G0_1_0_8_0_0 - 9.20380952380948*G0_1_0_8_0_1 - 2.92571428571426*G0_1_0_9_0_0 + 0.121904761904766*G0_1_0_9_0_1 - 0.609523809523806*G0_1_0_10_1_0 - 0.609523809523805*G0_1_0_10_1_1 + 4.63238095238093*G0_1_0_11_1_0 + 0.670476190476186*G0_1_0_12_1_1 + 2.62095238095237*G0_1_0_13_1_0 + 9.20380952380948*G0_1_0_13_1_1 - 0.243809523809524*G0_1_0_14_1_0 - 2.86476190476189*G0_1_0_14_1_1 + 0.304761904761899*G0_1_0_15_1_0 + 0.243809523809524*G0_1_0_16_1_0 - 0.0609523809523777*G0_1_0_16_1_1 + 2.43809523809522*G0_1_0_17_1_0 + 2.74285714285713*G0_1_0_17_1_1 - 6.46095238095235*G0_1_0_18_1_0 - 9.20380952380948*G0_1_0_18_1_1 - 2.92571428571426*G0_1_0_19_1_0 + 0.121904761904766*G0_1_0_19_1_1 - 3.1153439153439*G0_1_1_0_0_0 - 3.1153439153439*G0_1_1_0_0_1 + 7.13820105820102*G0_1_1_1_0_0 + 1.65248677248676*G0_1_1_2_0_1 + 3.73841269841268*G0_1_1_3_0_0 + 13.9784126984126*G0_1_1_3_0_1 - 0.65015873015873*G0_1_1_4_0_0 - 5.40444444444441*G0_1_1_4_0_1 - 0.812698412698416*G0_1_1_5_0_0 + 3.65714285714283*G0_1_1_5_0_1 + 0.650158730158731*G0_1_1_6_0_0 - 2.1942857142857*G0_1_1_6_0_1 + 5.48571428571425*G0_1_1_7_0_0 + 1.015873015873*G0_1_1_7_0_1 - 9.50857142857137*G0_1_1_8_0_0 - 13.9784126984126*G0_1_1_8_0_1 - 2.92571428571426*G0_1_1_9_0_0 + 4.38857142857142*G0_1_1_9_0_1 - 3.1153439153439*G0_1_1_10_1_0 - 3.1153439153439*G0_1_1_10_1_1 + 7.13820105820102*G0_1_1_11_1_0 + 1.65248677248676*G0_1_1_12_1_1 + 3.73841269841268*G0_1_1_13_1_0 + 13.9784126984126*G0_1_1_13_1_1 - 0.65015873015873*G0_1_1_14_1_0 - 5.40444444444441*G0_1_1_14_1_1 - 0.812698412698416*G0_1_1_15_1_0 + 3.65714285714283*G0_1_1_15_1_1 + 0.650158730158731*G0_1_1_16_1_0 - 2.1942857142857*G0_1_1_16_1_1 + 5.48571428571425*G0_1_1_17_1_0 + 1.015873015873*G0_1_1_17_1_1 - 9.50857142857137*G0_1_1_18_1_0 - 13.9784126984126*G0_1_1_18_1_1 - 2.92571428571426*G0_1_1_19_1_0 + 4.38857142857142*G0_1_1_19_1_1; + A[25] = 0.0; + A[726] = 0.0; + A[385] = 0.0; + A[34] = A[40] + 0.59206349206349*G0_0_0_0_0_0 + 0.59206349206349*G0_0_0_0_0_1 - 1.47777777777777*G0_0_0_1_0_0 + 0.14126984126984*G0_0_0_2_0_1 - 0.9047619047619*G0_0_0_3_0_0 - 2.70476190476189*G0_0_0_3_0_1 + 0.733333333333329*G0_0_0_4_0_0 + 0.914285714285708*G0_0_0_4_0_1 + 0.228571428571428*G0_0_0_5_0_0 - 0.366666666666666*G0_0_0_5_0_1 - 0.73333333333333*G0_0_0_6_0_0 - 0.366666666666664*G0_0_0_6_0_1 - 1.78571428571428*G0_0_0_7_0_0 - 1.19047619047618*G0_0_0_7_0_1 + 2.67142857142856*G0_0_0_8_0_0 + 2.70476190476189*G0_0_0_8_0_1 + 0.676190476190472*G0_0_0_9_0_0 + 0.276190476190473*G0_0_0_9_0_1 + 0.59206349206349*G0_0_0_10_1_0 + 0.59206349206349*G0_0_0_10_1_1 - 1.47777777777777*G0_0_0_11_1_0 + 0.14126984126984*G0_0_0_12_1_1 - 0.9047619047619*G0_0_0_13_1_0 - 2.70476190476189*G0_0_0_13_1_1 + 0.733333333333329*G0_0_0_14_1_0 + 0.914285714285708*G0_0_0_14_1_1 + 0.228571428571428*G0_0_0_15_1_0 - 0.366666666666666*G0_0_0_15_1_1 - 0.73333333333333*G0_0_0_16_1_0 - 0.366666666666664*G0_0_0_16_1_1 - 1.78571428571428*G0_0_0_17_1_0 - 1.19047619047618*G0_0_0_17_1_1 + 2.67142857142856*G0_0_0_18_1_0 + 2.70476190476189*G0_0_0_18_1_1 + 0.676190476190472*G0_0_0_19_1_0 + 0.276190476190473*G0_0_0_19_1_1 + 0.45079365079365*G0_0_1_0_0_0 + 0.450793650793649*G0_0_1_0_0_1 - 2.95555555555554*G0_0_1_1_0_0 - 0.450793650793648*G0_0_1_2_0_1 - 0.938095238095233*G0_0_1_3_0_0 - 5.40952380952378*G0_0_1_3_0_1 + 0.138095238095239*G0_0_1_4_0_0 + 2.10476190476189*G0_0_1_4_0_1 - 0.138095238095235*G0_0_1_5_0_0 - 0.138095238095239*G0_0_1_6_0_0 - 1.96666666666666*G0_0_1_7_0_0 - 2.10476190476189*G0_0_1_7_0_1 + 4.47142857142855*G0_0_1_8_0_0 + 5.40952380952378*G0_0_1_8_0_1 + 1.07619047619047*G0_0_1_9_0_0 + 0.45079365079365*G0_0_1_10_1_0 + 0.450793650793649*G0_0_1_10_1_1 - 2.95555555555554*G0_0_1_11_1_0 - 0.450793650793648*G0_0_1_12_1_1 - 0.938095238095233*G0_0_1_13_1_0 - 5.40952380952378*G0_0_1_13_1_1 + 0.138095238095239*G0_0_1_14_1_0 + 2.10476190476189*G0_0_1_14_1_1 - 0.138095238095235*G0_0_1_15_1_0 - 0.138095238095239*G0_0_1_16_1_0 - 1.96666666666666*G0_0_1_17_1_0 - 2.10476190476189*G0_0_1_17_1_1 + 4.47142857142855*G0_0_1_18_1_0 + 5.40952380952378*G0_0_1_18_1_1 + 1.07619047619047*G0_0_1_19_1_0; + A[757] = 0.0; + A[418] = 0.0; + A[784] = 0.0; + A[116] = 0.0; + A[819] = 0.0; + A[149] = 0.0; + A[210] = A[7] + 1.47777777777777*G0_0_1_0_0_0 + 1.47777777777777*G0_0_1_0_0_1 - 0.174603174603174*G0_0_1_1_0_0 - 0.276190476190474*G0_0_1_2_0_1 + 0.0531746031746031*G0_0_1_3_0_0 + 0.103968253968252*G0_0_1_3_0_1 + 0.0341269841269868*G0_0_1_4_0_0 + 0.0849206349206362*G0_0_1_4_0_1 + 0.351587301587302*G0_0_1_5_0_0 - 2.35317460317459*G0_0_1_5_0_1 - 0.0341269841269869*G0_0_1_6_0_0 + 1.15158730158729*G0_0_1_6_0_1 - 2.11825396825396*G0_0_1_7_0_0 + 0.586507936507934*G0_0_1_7_0_1 + 0.815079365079361*G0_0_1_8_0_0 - 0.103968253968252*G0_0_1_8_0_1 - 0.404761904761905*G0_0_1_9_0_0 - 0.671428571428572*G0_0_1_9_0_1 + 1.47777777777777*G0_0_1_10_1_0 + 1.47777777777777*G0_0_1_10_1_1 - 0.174603174603174*G0_0_1_11_1_0 - 0.276190476190474*G0_0_1_12_1_1 + 0.0531746031746031*G0_0_1_13_1_0 + 0.103968253968252*G0_0_1_13_1_1 + 0.0341269841269868*G0_0_1_14_1_0 + 0.0849206349206362*G0_0_1_14_1_1 + 0.351587301587302*G0_0_1_15_1_0 - 2.35317460317459*G0_0_1_15_1_1 - 0.0341269841269869*G0_0_1_16_1_0 + 1.15158730158729*G0_0_1_16_1_1 - 2.11825396825396*G0_0_1_17_1_0 + 0.586507936507934*G0_0_1_17_1_1 + 0.815079365079361*G0_0_1_18_1_0 - 0.103968253968252*G0_0_1_18_1_1 - 0.404761904761905*G0_0_1_19_1_0 - 0.671428571428572*G0_0_1_19_1_1 - 1.47777777777777*G0_1_0_0_0_0 - 1.47777777777777*G0_1_0_0_0_1 + 0.174603174603174*G0_1_0_1_0_0 + 0.276190476190474*G0_1_0_2_0_1 - 0.0531746031746031*G0_1_0_3_0_0 - 0.103968253968252*G0_1_0_3_0_1 - 0.0341269841269868*G0_1_0_4_0_0 - 0.0849206349206362*G0_1_0_4_0_1 - 0.351587301587302*G0_1_0_5_0_0 + 2.35317460317459*G0_1_0_5_0_1 + 0.0341269841269868*G0_1_0_6_0_0 - 1.15158730158729*G0_1_0_6_0_1 + 2.11825396825396*G0_1_0_7_0_0 - 0.586507936507934*G0_1_0_7_0_1 - 0.815079365079361*G0_1_0_8_0_0 + 0.103968253968252*G0_1_0_8_0_1 + 0.404761904761905*G0_1_0_9_0_0 + 0.671428571428571*G0_1_0_9_0_1 - 1.47777777777777*G0_1_0_10_1_0 - 1.47777777777777*G0_1_0_10_1_1 + 0.174603174603174*G0_1_0_11_1_0 + 0.276190476190474*G0_1_0_12_1_1 - 0.0531746031746031*G0_1_0_13_1_0 - 0.103968253968252*G0_1_0_13_1_1 - 0.0341269841269868*G0_1_0_14_1_0 - 0.0849206349206362*G0_1_0_14_1_1 - 0.351587301587302*G0_1_0_15_1_0 + 2.35317460317459*G0_1_0_15_1_1 + 0.0341269841269868*G0_1_0_16_1_0 - 1.15158730158729*G0_1_0_16_1_1 + 2.11825396825396*G0_1_0_17_1_0 - 0.586507936507934*G0_1_0_17_1_1 - 0.815079365079361*G0_1_0_18_1_0 + 0.103968253968252*G0_1_0_18_1_1 + 0.404761904761905*G0_1_0_19_1_0 + 0.671428571428571*G0_1_0_19_1_1; + A[166] = 0.0; + A[488] = 0.0; + A[659] = A[194]; + A[575] = 0.0; + A[678] = A[213]; + A[606] = 0.0; + A[558] = -A[101] - 0.27089947089947*G0_0_0_0_0_0 - 0.27089947089947*G0_0_0_0_0_1 + 0.778835978835978*G0_0_0_1_0_0 + 0.372486772486769*G0_0_0_2_0_1 + 2.53968253968254*G0_0_0_3_0_0 + 2.28571428571428*G0_0_0_3_0_1 + 1.62539682539682*G0_0_0_4_0_0 + 2.28571428571428*G0_0_0_4_0_1 - 0.101587301587297*G0_0_0_5_0_0 - 0.0507936507936484*G0_0_0_5_0_1 - 1.62539682539682*G0_0_0_6_0_0 - 0.0507936507936509*G0_0_0_6_0_1 + 0.507936507936508*G0_0_0_7_0_0 + 0.457142857142862*G0_0_0_7_0_1 - 1.01587301587302*G0_0_0_8_0_0 - 2.28571428571428*G0_0_0_8_0_1 - 2.43809523809524*G0_0_0_9_0_0 - 2.74285714285714*G0_0_0_9_0_1 - 0.27089947089947*G0_0_0_10_1_0 - 0.27089947089947*G0_0_0_10_1_1 + 0.778835978835978*G0_0_0_11_1_0 + 0.372486772486769*G0_0_0_12_1_1 + 2.53968253968254*G0_0_0_13_1_0 + 2.28571428571428*G0_0_0_13_1_1 + 1.62539682539682*G0_0_0_14_1_0 + 2.28571428571428*G0_0_0_14_1_1 - 0.101587301587297*G0_0_0_15_1_0 - 0.0507936507936484*G0_0_0_15_1_1 - 1.62539682539682*G0_0_0_16_1_0 - 0.0507936507936509*G0_0_0_16_1_1 + 0.507936507936508*G0_0_0_17_1_0 + 0.457142857142862*G0_0_0_17_1_1 - 1.01587301587302*G0_0_0_18_1_0 - 2.28571428571428*G0_0_0_18_1_1 - 2.43809523809524*G0_0_0_19_1_0 - 2.74285714285714*G0_0_0_19_1_1 + 0.406349206349206*G0_1_0_0_0_0 + 0.406349206349205*G0_1_0_0_0_1 - 1.93015873015873*G0_1_0_1_0_0 - 0.406349206349207*G0_1_0_2_0_1 + 0.863492063492061*G0_1_0_3_0_0 - 2.64126984126984*G0_1_0_3_0_1 - 0.0507936507936493*G0_1_0_4_0_0 + 1.93015873015873*G0_1_0_4_0_1 + 0.0507936507936523*G0_1_0_5_0_0 + 0.0507936507936497*G0_1_0_6_0_0 - 1.98095238095237*G0_1_0_7_0_0 - 1.93015873015872*G0_1_0_7_0_1 + 3.5047619047619*G0_1_0_8_0_0 + 2.64126984126984*G0_1_0_8_0_1 - 0.914285714285713*G0_1_0_9_0_0 + 0.406349206349206*G0_1_0_10_1_0 + 0.406349206349205*G0_1_0_10_1_1 - 1.93015873015873*G0_1_0_11_1_0 - 0.406349206349207*G0_1_0_12_1_1 + 0.863492063492061*G0_1_0_13_1_0 - 2.64126984126984*G0_1_0_13_1_1 - 0.0507936507936493*G0_1_0_14_1_0 + 1.93015873015873*G0_1_0_14_1_1 + 0.0507936507936523*G0_1_0_15_1_0 + 0.0507936507936497*G0_1_0_16_1_0 - 1.98095238095237*G0_1_0_17_1_0 - 1.93015873015872*G0_1_0_17_1_1 + 3.5047619047619*G0_1_0_18_1_0 + 2.64126984126984*G0_1_0_18_1_1 - 0.914285714285713*G0_1_0_19_1_0; + A[717] = A[252]; + A[637] = 0.0; + A[353] = 0.0; + A[16] = 0.0; + A[733] = 0.0; + A[420] = A[14] - 0.0101587301587299*G0_0_1_1_0_0 - 0.111746031746032*G0_0_1_2_0_1 + 0.153650793650793*G0_0_1_3_0_0 + 0.021587301587302*G0_0_1_3_0_1 - 0.143492063492063*G0_0_1_4_0_0 + 0.0901587301587294*G0_0_1_4_0_1 - 0.0698412698412703*G0_0_1_5_0_0 - 0.0698412698412708*G0_0_1_5_0_1 + 0.143492063492064*G0_0_1_6_0_0 + 0.181587301587303*G0_0_1_6_0_1 + 0.069841269841269*G0_0_1_7_0_0 + 0.0698412698412699*G0_0_1_7_0_1 - 0.0596825396825398*G0_0_1_8_0_0 - 0.0215873015873019*G0_0_1_8_0_1 - 0.0838095238095233*G0_0_1_9_0_0 - 0.16*G0_0_1_9_0_1 - 0.0101587301587299*G0_0_1_11_1_0 - 0.111746031746032*G0_0_1_12_1_1 + 0.153650793650793*G0_0_1_13_1_0 + 0.021587301587302*G0_0_1_13_1_1 - 0.143492063492063*G0_0_1_14_1_0 + 0.0901587301587294*G0_0_1_14_1_1 - 0.0698412698412703*G0_0_1_15_1_0 - 0.0698412698412708*G0_0_1_15_1_1 + 0.143492063492064*G0_0_1_16_1_0 + 0.181587301587303*G0_0_1_16_1_1 + 0.069841269841269*G0_0_1_17_1_0 + 0.0698412698412699*G0_0_1_17_1_1 - 0.0596825396825398*G0_0_1_18_1_0 - 0.0215873015873019*G0_0_1_18_1_1 - 0.0838095238095233*G0_0_1_19_1_0 - 0.16*G0_0_1_19_1_1 + 0.0101587301587299*G0_1_0_1_0_0 + 0.111746031746032*G0_1_0_2_0_1 - 0.153650793650793*G0_1_0_3_0_0 - 0.0215873015873019*G0_1_0_3_0_1 + 0.143492063492063*G0_1_0_4_0_0 - 0.0901587301587294*G0_1_0_4_0_1 + 0.0698412698412704*G0_1_0_5_0_0 + 0.0698412698412709*G0_1_0_5_0_1 - 0.143492063492064*G0_1_0_6_0_0 - 0.181587301587303*G0_1_0_6_0_1 - 0.069841269841269*G0_1_0_7_0_0 - 0.0698412698412699*G0_1_0_7_0_1 + 0.0596825396825398*G0_1_0_8_0_0 + 0.0215873015873019*G0_1_0_8_0_1 + 0.0838095238095232*G0_1_0_9_0_0 + 0.16*G0_1_0_9_0_1 + 0.0101587301587299*G0_1_0_11_1_0 + 0.111746031746032*G0_1_0_12_1_1 - 0.153650793650793*G0_1_0_13_1_0 - 0.0215873015873019*G0_1_0_13_1_1 + 0.143492063492063*G0_1_0_14_1_0 - 0.0901587301587294*G0_1_0_14_1_1 + 0.0698412698412704*G0_1_0_15_1_0 + 0.0698412698412709*G0_1_0_15_1_1 - 0.143492063492064*G0_1_0_16_1_0 - 0.181587301587303*G0_1_0_16_1_1 - 0.069841269841269*G0_1_0_17_1_0 - 0.0698412698412699*G0_1_0_17_1_1 + 0.0596825396825398*G0_1_0_18_1_0 + 0.0215873015873019*G0_1_0_18_1_1 + 0.0838095238095232*G0_1_0_19_1_0 + 0.16*G0_1_0_19_1_1; + A[376] = 0.0; + A[59] = 0.0; + A[758] = 0.0; + A[455] = 0.0; + A[411] = 0.0; + A[86] = 0.0; + A[93] = A[558]; + A[824] = 0.0; + A[849] = 0.0; + A[175] = 0.0; + A[882] = 0.0; + A[495] = A[30]; + A[202] = 0.0; + A[580] = 0.0; + A[524] = 0.0; + A[233] = 0.0; + A[613] = 0.0; + A[553] = 0.0; + A[706] = A[181] + 0.126984126984126*G0_0_0_0_0_0 + 0.126984126984126*G0_0_0_0_0_1 + 0.256507936507935*G0_0_0_2_0_1 - 0.218412698412697*G0_0_0_3_0_0 + 0.4215873015873*G0_0_0_4_0_0 - 0.053333333333333*G0_0_0_4_0_1 + 0.294603174603173*G0_0_0_5_0_0 + 0.00253968253968256*G0_0_0_5_0_1 - 0.4215873015873*G0_0_0_6_0_0 - 0.386031746031744*G0_0_0_6_0_1 - 0.345396825396822*G0_0_0_7_0_0 - 0.0533333333333324*G0_0_0_7_0_1 + 0.218412698412696*G0_0_0_8_0_0 - 0.0761904761904755*G0_0_0_9_0_0 + 0.106666666666666*G0_0_0_9_0_1 + 0.126984126984126*G0_0_0_10_1_0 + 0.126984126984126*G0_0_0_10_1_1 + 0.256507936507935*G0_0_0_12_1_1 - 0.218412698412697*G0_0_0_13_1_0 + 0.4215873015873*G0_0_0_14_1_0 - 0.053333333333333*G0_0_0_14_1_1 + 0.294603174603173*G0_0_0_15_1_0 + 0.00253968253968256*G0_0_0_15_1_1 - 0.4215873015873*G0_0_0_16_1_0 - 0.386031746031744*G0_0_0_16_1_1 - 0.345396825396822*G0_0_0_17_1_0 - 0.0533333333333324*G0_0_0_17_1_1 + 0.218412698412696*G0_0_0_18_1_0 - 0.0761904761904755*G0_0_0_19_1_0 + 0.106666666666666*G0_0_0_19_1_1 - 0.12952380952381*G0_1_0_0_0_0 - 0.12952380952381*G0_1_0_0_0_1 + 0.129523809523809*G0_1_0_2_0_1 + 0.129523809523808*G0_1_0_4_0_0 + 0.259047619047617*G0_1_0_5_0_0 + 0.388571428571428*G0_1_0_5_0_1 - 0.129523809523808*G0_1_0_6_0_0 - 0.388571428571427*G0_1_0_6_0_1 + 0.129523809523811*G0_1_0_7_0_0 - 0.259047619047618*G0_1_0_9_0_0 - 0.12952380952381*G0_1_0_10_1_0 - 0.12952380952381*G0_1_0_10_1_1 + 0.129523809523809*G0_1_0_12_1_1 + 0.129523809523808*G0_1_0_14_1_0 + 0.259047619047617*G0_1_0_15_1_0 + 0.388571428571428*G0_1_0_15_1_1 - 0.129523809523808*G0_1_0_16_1_0 - 0.388571428571427*G0_1_0_16_1_1 + 0.129523809523811*G0_1_0_17_1_0 - 0.259047619047618*G0_1_0_19_1_0; + A[151] = -A[706] - 0.0876190476190475*G0_1_0_0_0_0 - 0.0876190476190473*G0_1_0_0_0_1 + 0.590476190476191*G0_1_0_1_0_0 + 0.285714285714285*G0_1_0_2_0_1 + 0.0622222222222224*G0_1_0_3_0_0 + 1.07936507936508*G0_1_0_3_0_1 + 0.260317460317458*G0_1_0_4_0_0 - 0.452063492063493*G0_1_0_4_0_1 + 0.227301587301586*G0_1_0_5_0_0 + 0.156190476190475*G0_1_0_5_0_1 - 0.260317460317458*G0_1_0_6_0_0 - 0.354285714285712*G0_1_0_6_0_1 + 0.251428571428572*G0_1_0_7_0_0 + 0.322539682539683*G0_1_0_7_0_1 - 0.754285714285715*G0_1_0_8_0_0 - 1.07936507936508*G0_1_0_8_0_1 - 0.289523809523808*G0_1_0_9_0_0 + 0.12952380952381*G0_1_0_9_0_1 - 0.0876190476190475*G0_1_0_10_1_0 - 0.0876190476190473*G0_1_0_10_1_1 + 0.590476190476191*G0_1_0_11_1_0 + 0.285714285714285*G0_1_0_12_1_1 + 0.0622222222222224*G0_1_0_13_1_0 + 1.07936507936508*G0_1_0_13_1_1 + 0.260317460317458*G0_1_0_14_1_0 - 0.452063492063493*G0_1_0_14_1_1 + 0.227301587301586*G0_1_0_15_1_0 + 0.156190476190475*G0_1_0_15_1_1 - 0.260317460317458*G0_1_0_16_1_0 - 0.354285714285712*G0_1_0_16_1_1 + 0.251428571428572*G0_1_0_17_1_0 + 0.322539682539683*G0_1_0_17_1_1 - 0.754285714285715*G0_1_0_18_1_0 - 1.07936507936508*G0_1_0_18_1_1 - 0.289523809523808*G0_1_0_19_1_0 + 0.12952380952381*G0_1_0_19_1_1; + A[240] = -A[706] + 0.0304761904761901*G0_0_0_0_0_0 + 0.0304761904761901*G0_0_0_0_0_1 + 0.0304761904761911*G0_0_0_1_0_0 - 0.289523809523807*G0_0_0_3_0_0 - 0.0838095238095216*G0_0_0_3_0_1 - 0.175238095238095*G0_0_0_4_0_1 - 0.289523809523807*G0_0_0_5_0_0 - 0.205714285714284*G0_0_0_5_0_1 + 0.175238095238094*G0_0_0_6_0_1 - 0.0304761904761897*G0_0_0_7_0_0 - 0.114285714285713*G0_0_0_7_0_1 - 0.0304761904761915*G0_0_0_8_0_0 + 0.0838095238095216*G0_0_0_8_0_1 + 0.579047619047614*G0_0_0_9_0_0 + 0.289523809523808*G0_0_0_9_0_1 + 0.0304761904761901*G0_0_0_10_1_0 + 0.0304761904761901*G0_0_0_10_1_1 + 0.0304761904761911*G0_0_0_11_1_0 - 0.289523809523807*G0_0_0_13_1_0 - 0.0838095238095216*G0_0_0_13_1_1 - 0.175238095238095*G0_0_0_14_1_1 - 0.289523809523807*G0_0_0_15_1_0 - 0.205714285714284*G0_0_0_15_1_1 + 0.175238095238094*G0_0_0_16_1_1 - 0.0304761904761897*G0_0_0_17_1_0 - 0.114285714285713*G0_0_0_17_1_1 - 0.0304761904761915*G0_0_0_18_1_0 + 0.0838095238095216*G0_0_0_18_1_1 + 0.579047619047614*G0_0_0_19_1_0 + 0.289523809523808*G0_0_0_19_1_1 + 0.0296296296296299*G0_0_1_0_0_0 + 0.02962962962963*G0_0_1_0_0_1 + 0.000846560846560314*G0_0_1_1_0_0 - 0.23915343915344*G0_0_1_2_0_1 + 0.0520634920634936*G0_0_1_3_0_0 + 0.00825396825396813*G0_0_1_3_0_1 - 0.431746031746034*G0_0_1_4_0_0 - 0.147936507936508*G0_0_1_4_0_1 - 0.341587301587302*G0_0_1_5_0_0 - 0.24952380952381*G0_0_1_5_0_1 + 0.431746031746034*G0_0_1_6_0_0 + 0.45904761904762*G0_0_1_6_0_1 + 0.0304761904761903*G0_0_1_7_0_0 - 0.0615873015873012*G0_0_1_7_0_1 - 0.0609523809523805*G0_0_1_8_0_0 - 0.00825396825396815*G0_0_1_8_0_1 + 0.289523809523808*G0_0_1_9_0_0 + 0.209523809523809*G0_0_1_9_0_1 + 0.0296296296296299*G0_0_1_10_1_0 + 0.02962962962963*G0_0_1_10_1_1 + 0.000846560846560314*G0_0_1_11_1_0 - 0.23915343915344*G0_0_1_12_1_1 + 0.0520634920634936*G0_0_1_13_1_0 + 0.00825396825396813*G0_0_1_13_1_1 - 0.431746031746034*G0_0_1_14_1_0 - 0.147936507936508*G0_0_1_14_1_1 - 0.341587301587302*G0_0_1_15_1_0 - 0.24952380952381*G0_0_1_15_1_1 + 0.431746031746034*G0_0_1_16_1_0 + 0.45904761904762*G0_0_1_16_1_1 + 0.0304761904761903*G0_0_1_17_1_0 - 0.0615873015873012*G0_0_1_17_1_1 - 0.0609523809523805*G0_0_1_18_1_0 - 0.00825396825396815*G0_0_1_18_1_1 + 0.289523809523808*G0_0_1_19_1_0 + 0.209523809523809*G0_0_1_19_1_1 + 0.603597883597881*G0_1_0_0_0_0 + 0.603597883597881*G0_1_0_0_0_1 - 0.0702645502645485*G0_1_0_1_0_0 - 0.298835978835977*G0_1_0_2_0_1 + 0.053333333333334*G0_1_0_3_0_0 + 0.0609523809523831*G0_1_0_3_0_1 - 0.396190476190474*G0_1_0_4_0_0 - 0.175238095238095*G0_1_0_4_0_1 - 0.053333333333332*G0_1_0_5_0_0 - 1.05904761904761*G0_1_0_5_0_1 + 0.396190476190474*G0_1_0_6_0_0 + 0.754285714285711*G0_1_0_6_0_1 - 0.830476190476186*G0_1_0_7_0_0 + 0.175238095238096*G0_1_0_7_0_1 + 0.297142857142853*G0_1_0_8_0_0 - 0.0609523809523831*G0_1_0_8_0_1 + 0.603597883597881*G0_1_0_10_1_0 + 0.603597883597881*G0_1_0_10_1_1 - 0.0702645502645485*G0_1_0_11_1_0 - 0.298835978835977*G0_1_0_12_1_1 + 0.053333333333334*G0_1_0_13_1_0 + 0.0609523809523831*G0_1_0_13_1_1 - 0.396190476190474*G0_1_0_14_1_0 - 0.175238095238095*G0_1_0_14_1_1 - 0.053333333333332*G0_1_0_15_1_0 - 1.05904761904761*G0_1_0_15_1_1 + 0.396190476190474*G0_1_0_16_1_0 + 0.754285714285711*G0_1_0_16_1_1 - 0.830476190476186*G0_1_0_17_1_0 + 0.175238095238096*G0_1_0_17_1_1 + 0.297142857142853*G0_1_0_18_1_0 - 0.0609523809523831*G0_1_0_18_1_1 + 0.620105820105818*G0_1_1_0_0_0 + 0.620105820105818*G0_1_1_0_0_1 - 0.0702645502645503*G0_1_1_1_0_0 - 0.411851851851852*G0_1_1_2_0_1 + 0.114920634920636*G0_1_1_3_0_0 + 0.0609523809523804*G0_1_1_3_0_1 - 0.544126984126985*G0_1_1_4_0_0 - 0.148571428571428*G0_1_1_4_0_1 - 0.217777777777778*G0_1_1_5_0_0 - 1.20507936507936*G0_1_1_5_0_1 + 0.544126984126985*G0_1_1_6_0_0 + 0.996825396825396*G0_1_1_6_0_1 - 0.785396825396823*G0_1_1_7_0_0 + 0.201904761904761*G0_1_1_7_0_1 + 0.235555555555554*G0_1_1_8_0_0 - 0.0609523809523804*G0_1_1_8_0_1 + 0.102857142857142*G0_1_1_9_0_0 - 0.0533333333333335*G0_1_1_9_0_1 + 0.620105820105818*G0_1_1_10_1_0 + 0.620105820105818*G0_1_1_10_1_1 - 0.0702645502645503*G0_1_1_11_1_0 - 0.411851851851852*G0_1_1_12_1_1 + 0.114920634920636*G0_1_1_13_1_0 + 0.0609523809523804*G0_1_1_13_1_1 - 0.544126984126985*G0_1_1_14_1_0 - 0.148571428571428*G0_1_1_14_1_1 - 0.217777777777778*G0_1_1_15_1_0 - 1.20507936507936*G0_1_1_15_1_1 + 0.544126984126985*G0_1_1_16_1_0 + 0.996825396825396*G0_1_1_16_1_1 - 0.785396825396823*G0_1_1_17_1_0 + 0.201904761904761*G0_1_1_17_1_1 + 0.235555555555554*G0_1_1_18_1_0 - 0.0609523809523804*G0_1_1_18_1_1 + 0.102857142857142*G0_1_1_19_1_0 - 0.0533333333333335*G0_1_1_19_1_1; + A[736] = -A[151] + 0.41100529100529*G0_0_0_0_0_0 + 0.41100529100529*G0_0_0_0_0_1 - 0.649735449735448*G0_0_0_1_0_0 - 0.309417989417988*G0_0_0_2_0_1 + 0.139682539682539*G0_0_0_3_0_0 - 0.895238095238094*G0_0_0_3_0_1 - 0.370793650793649*G0_0_0_4_0_0 + 0.323809523809523*G0_0_0_4_0_1 + 0.0965079365079358*G0_0_0_5_0_0 - 0.439365079365079*G0_0_0_5_0_1 + 0.370793650793649*G0_0_0_6_0_0 + 0.337777777777778*G0_0_0_6_0_1 - 0.935873015873013*G0_0_0_7_0_0 - 0.399999999999999*G0_0_0_7_0_1 + 1.17460317460317*G0_0_0_8_0_0 + 0.895238095238094*G0_0_0_8_0_1 - 0.236190476190475*G0_0_0_9_0_0 + 0.0761904761904749*G0_0_0_9_0_1 + 0.41100529100529*G0_0_0_10_1_0 + 0.41100529100529*G0_0_0_10_1_1 - 0.649735449735448*G0_0_0_11_1_0 - 0.309417989417988*G0_0_0_12_1_1 + 0.139682539682539*G0_0_0_13_1_0 - 0.895238095238094*G0_0_0_13_1_1 - 0.370793650793649*G0_0_0_14_1_0 + 0.323809523809523*G0_0_0_14_1_1 + 0.0965079365079358*G0_0_0_15_1_0 - 0.439365079365079*G0_0_0_15_1_1 + 0.370793650793649*G0_0_0_16_1_0 + 0.337777777777778*G0_0_0_16_1_1 - 0.935873015873013*G0_0_0_17_1_0 - 0.399999999999999*G0_0_0_17_1_1 + 1.17460317460317*G0_0_0_18_1_0 + 0.895238095238094*G0_0_0_18_1_1 - 0.236190476190475*G0_0_0_19_1_0 + 0.0761904761904749*G0_0_0_19_1_1 + 0.101587301587301*G0_1_0_0_0_0 + 0.101587301587301*G0_1_0_0_0_1 + 0.101587301587301*G0_1_0_2_0_1 - 0.139682539682539*G0_1_0_3_0_0 + 0.165079365079363*G0_1_0_4_0_0 - 0.0761904761904785*G0_1_0_4_0_1 + 0.0634920634920629*G0_1_0_5_0_0 - 0.101587301587301*G0_1_0_5_0_1 - 0.165079365079363*G0_1_0_6_0_0 - 0.101587301587301*G0_1_0_6_0_1 - 0.241269841269838*G0_1_0_7_0_0 - 0.0761904761904741*G0_1_0_7_0_1 + 0.139682539682535*G0_1_0_8_0_0 + 0.0761904761904757*G0_1_0_9_0_0 + 0.152380952380952*G0_1_0_9_0_1 + 0.101587301587301*G0_1_0_10_1_0 + 0.101587301587301*G0_1_0_10_1_1 + 0.101587301587301*G0_1_0_12_1_1 - 0.139682539682539*G0_1_0_13_1_0 + 0.165079365079363*G0_1_0_14_1_0 - 0.0761904761904785*G0_1_0_14_1_1 + 0.0634920634920629*G0_1_0_15_1_0 - 0.101587301587301*G0_1_0_15_1_1 - 0.165079365079363*G0_1_0_16_1_0 - 0.101587301587301*G0_1_0_16_1_1 - 0.241269841269838*G0_1_0_17_1_0 - 0.0761904761904741*G0_1_0_17_1_1 + 0.139682539682535*G0_1_0_18_1_0 + 0.0761904761904757*G0_1_0_19_1_0 + 0.152380952380952*G0_1_0_19_1_1; + A[271] = A[736]; + A[630] = 0.0; + A[251] = A[716]; + A[675] = A[210]; + A[704] = 0.0; + A[301] = A[766]; + A[257] = 0.0; + A[23] = 0.0; + A[740] = -A[743] - 0.528253968253966*G0_0_1_0_0_0 - 0.528253968253966*G0_0_1_0_0_1 + 0.142222222222219*G0_0_1_1_0_0 - 0.121904761904759*G0_0_1_3_0_0 - 0.111746031746033*G0_0_1_3_0_1 + 0.132063492063494*G0_0_1_4_0_1 - 0.121904761904762*G0_0_1_5_0_0 + 0.660317460317458*G0_0_1_5_0_1 - 0.132063492063492*G0_0_1_6_0_1 + 1.19873015873015*G0_0_1_7_0_0 + 0.416507936507932*G0_0_1_7_0_1 - 0.812698412698404*G0_0_1_8_0_0 + 0.111746031746033*G0_0_1_8_0_1 + 0.24380952380952*G0_0_1_9_0_0 - 0.548571428571426*G0_0_1_9_0_1 - 0.528253968253966*G0_0_1_10_1_0 - 0.528253968253966*G0_0_1_10_1_1 + 0.142222222222219*G0_0_1_11_1_0 - 0.121904761904759*G0_0_1_13_1_0 - 0.111746031746033*G0_0_1_13_1_1 + 0.132063492063494*G0_0_1_14_1_1 - 0.121904761904762*G0_0_1_15_1_0 + 0.660317460317458*G0_0_1_15_1_1 - 0.132063492063492*G0_0_1_16_1_1 + 1.19873015873015*G0_0_1_17_1_0 + 0.416507936507932*G0_0_1_17_1_1 - 0.812698412698404*G0_0_1_18_1_0 + 0.111746031746033*G0_0_1_18_1_1 + 0.24380952380952*G0_0_1_19_1_0 - 0.548571428571426*G0_0_1_19_1_1 + 0.826243386243381*G0_1_1_0_0_0 + 0.826243386243381*G0_1_1_0_0_1 + 0.128677248677247*G0_1_1_1_0_0 - 0.440211640211638*G0_1_1_2_0_1 - 0.294603174603172*G0_1_1_3_0_0 - 0.0406349206349223*G0_1_1_3_0_1 - 0.0507936507936511*G0_1_1_4_0_0 + 0.264126984126984*G0_1_1_4_0_1 - 0.497777777777777*G0_1_1_5_0_0 - 2.05206349206348*G0_1_1_5_0_1 + 0.0507936507936509*G0_1_1_6_0_0 + 1.66603174603174*G0_1_1_6_0_1 - 0.355555555555553*G0_1_1_7_0_0 + 1.19873015873015*G0_1_1_7_0_1 - 0.599365079365076*G0_1_1_8_0_0 + 0.0406349206349221*G0_1_1_8_0_1 + 0.792380952380949*G0_1_1_9_0_0 - 1.46285714285714*G0_1_1_9_0_1 + 0.826243386243381*G0_1_1_10_1_0 + 0.826243386243381*G0_1_1_10_1_1 + 0.128677248677247*G0_1_1_11_1_0 - 0.440211640211638*G0_1_1_12_1_1 - 0.294603174603172*G0_1_1_13_1_0 - 0.0406349206349223*G0_1_1_13_1_1 - 0.0507936507936511*G0_1_1_14_1_0 + 0.264126984126984*G0_1_1_14_1_1 - 0.497777777777777*G0_1_1_15_1_0 - 2.05206349206348*G0_1_1_15_1_1 + 0.0507936507936509*G0_1_1_16_1_0 + 1.66603174603174*G0_1_1_16_1_1 - 0.355555555555553*G0_1_1_17_1_0 + 1.19873015873015*G0_1_1_17_1_1 - 0.599365079365076*G0_1_1_18_1_0 + 0.0406349206349221*G0_1_1_18_1_1 + 0.792380952380949*G0_1_1_19_1_0 - 1.46285714285714*G0_1_1_19_1_1; + A[403] = -A[740] - 1.56444444444443*G0_0_0_0_0_0 - 1.56444444444443*G0_0_0_0_0_1 + 3.53523809523807*G0_0_0_1_0_0 - 0.772063492063487*G0_0_0_2_0_1 + 9.26476190476184*G0_0_0_3_0_0 + 8.76698412698407*G0_0_0_3_0_1 + 2.07238095238096*G0_0_0_4_0_0 + 6.87746031746029*G0_0_0_4_0_1 - 3.65714285714285*G0_0_0_5_0_0 - 1.63555555555556*G0_0_0_5_0_1 - 2.07238095238095*G0_0_0_6_0_0 + 3.97206349206348*G0_0_0_6_0_1 + 4.59174603174599*G0_0_0_7_0_0 + 2.5701587301587*G0_0_0_7_0_1 - 6.56253968253964*G0_0_0_8_0_0 - 8.76698412698408*G0_0_0_8_0_1 - 5.60761904761899*G0_0_0_9_0_0 - 9.44761904761899*G0_0_0_9_0_1 - 1.56444444444443*G0_0_0_10_1_0 - 1.56444444444443*G0_0_0_10_1_1 + 3.53523809523807*G0_0_0_11_1_0 - 0.772063492063487*G0_0_0_12_1_1 + 9.26476190476184*G0_0_0_13_1_0 + 8.76698412698407*G0_0_0_13_1_1 + 2.07238095238096*G0_0_0_14_1_0 + 6.87746031746029*G0_0_0_14_1_1 - 3.65714285714285*G0_0_0_15_1_0 - 1.63555555555556*G0_0_0_15_1_1 - 2.07238095238095*G0_0_0_16_1_0 + 3.97206349206348*G0_0_0_16_1_1 + 4.59174603174599*G0_0_0_17_1_0 + 2.5701587301587*G0_0_0_17_1_1 - 6.56253968253964*G0_0_0_18_1_0 - 8.76698412698408*G0_0_0_18_1_1 - 5.60761904761899*G0_0_0_19_1_0 - 9.44761904761899*G0_0_0_19_1_1 - 1.57460317460316*G0_0_1_0_0_0 - 1.57460317460316*G0_0_1_0_0_1 + 2.57015873015871*G0_0_1_1_0_0 - 0.761904761904758*G0_0_1_2_0_1 + 9.1123809523809*G0_0_1_3_0_0 + 7.54793650793646*G0_0_1_3_0_1 + 4.89650793650792*G0_0_1_4_0_1 + 2.10285714285712*G0_0_1_5_0_0 + 2.05206349206347*G0_0_1_5_0_1 + 0.284444444444448*G0_0_1_6_0_1 + 4.50031746031742*G0_0_1_7_0_0 + 4.55111111111108*G0_0_1_7_0_1 - 5.49587301587298*G0_0_1_8_0_0 - 7.54793650793647*G0_0_1_8_0_1 - 11.215238095238*G0_0_1_9_0_0 - 9.44761904761899*G0_0_1_9_0_1 - 1.57460317460316*G0_0_1_10_1_0 - 1.57460317460316*G0_0_1_10_1_1 + 2.57015873015871*G0_0_1_11_1_0 - 0.761904761904758*G0_0_1_12_1_1 + 9.1123809523809*G0_0_1_13_1_0 + 7.54793650793646*G0_0_1_13_1_1 + 4.89650793650792*G0_0_1_14_1_1 + 2.10285714285712*G0_0_1_15_1_0 + 2.05206349206347*G0_0_1_15_1_1 + 0.284444444444448*G0_0_1_16_1_1 + 4.50031746031742*G0_0_1_17_1_0 + 4.55111111111108*G0_0_1_17_1_1 - 5.49587301587298*G0_0_1_18_1_0 - 7.54793650793647*G0_0_1_18_1_1 - 11.215238095238*G0_0_1_19_1_0 - 9.44761904761899*G0_0_1_19_1_1 - 1.5542857142857*G0_1_0_0_0_0 - 1.5542857142857*G0_1_0_0_0_1 + 2.54984126984126*G0_1_0_1_0_0 - 0.782222222222218*G0_1_0_2_0_1 + 9.28507936507931*G0_1_0_3_0_0 + 7.6292063492063*G0_1_0_3_0_1 - 0.0711111111111032*G0_1_0_4_0_0 + 4.91682539682537*G0_1_0_4_0_1 + 2.23492063492061*G0_1_0_5_0_0 + 2.11301587301585*G0_1_0_5_0_1 + 0.0711111111111066*G0_1_0_6_0_0 + 0.223492063492067*G0_1_0_6_0_1 + 4.40888888888886*G0_1_0_7_0_0 + 4.53079365079362*G0_1_0_7_0_1 - 5.40444444444441*G0_1_0_8_0_0 - 7.62920634920631*G0_1_0_8_0_1 - 11.5199999999999*G0_1_0_9_0_0 - 9.44761904761899*G0_1_0_9_0_1 - 1.5542857142857*G0_1_0_10_1_0 - 1.5542857142857*G0_1_0_10_1_1 + 2.54984126984126*G0_1_0_11_1_0 - 0.782222222222218*G0_1_0_12_1_1 + 9.28507936507931*G0_1_0_13_1_0 + 7.6292063492063*G0_1_0_13_1_1 - 0.0711111111111032*G0_1_0_14_1_0 + 4.91682539682537*G0_1_0_14_1_1 + 2.23492063492061*G0_1_0_15_1_0 + 2.11301587301585*G0_1_0_15_1_1 + 0.0711111111111066*G0_1_0_16_1_0 + 0.223492063492067*G0_1_0_16_1_1 + 4.40888888888886*G0_1_0_17_1_0 + 4.53079365079362*G0_1_0_17_1_1 - 5.40444444444441*G0_1_0_18_1_0 - 7.62920634920631*G0_1_0_18_1_1 - 11.5199999999999*G0_1_0_19_1_0 - 9.44761904761899*G0_1_0_19_1_1 - 0.792380952380944*G0_1_1_0_0_0 - 0.792380952380944*G0_1_1_0_0_1 + 5.11999999999997*G0_1_1_1_0_0 + 0.792380952380945*G0_1_1_2_0_1 + 11.3371428571428*G0_1_1_3_0_0 + 15.1771428571428*G0_1_1_3_0_1 - 0.121904761904761*G0_1_1_4_0_0 + 0.365714285714285*G0_1_1_4_0_1 + 1.95047619047617*G0_1_1_5_0_0 + 1.82857142857141*G0_1_1_5_0_1 + 0.121904761904766*G0_1_1_6_0_0 - 1.82857142857141*G0_1_1_6_0_1 - 0.487619047619063*G0_1_1_7_0_0 - 0.365714285714301*G0_1_1_7_0_1 - 3.83999999999996*G0_1_1_8_0_0 - 15.1771428571428*G0_1_1_8_0_1 - 13.287619047619*G0_1_1_9_0_0 - 0.792380952380944*G0_1_1_10_1_0 - 0.792380952380944*G0_1_1_10_1_1 + 5.11999999999997*G0_1_1_11_1_0 + 0.792380952380945*G0_1_1_12_1_1 + 11.3371428571428*G0_1_1_13_1_0 + 15.1771428571428*G0_1_1_13_1_1 - 0.121904761904761*G0_1_1_14_1_0 + 0.365714285714285*G0_1_1_14_1_1 + 1.95047619047617*G0_1_1_15_1_0 + 1.82857142857141*G0_1_1_15_1_1 + 0.121904761904766*G0_1_1_16_1_0 - 1.82857142857141*G0_1_1_16_1_1 - 0.487619047619063*G0_1_1_17_1_0 - 0.365714285714301*G0_1_1_17_1_1 - 3.83999999999996*G0_1_1_18_1_0 - 15.1771428571428*G0_1_1_18_1_1 - 13.287619047619*G0_1_1_19_1_0; + A[899] = A[403] + 0.487619047619039*G0_0_0_0_0_0 + 0.487619047619037*G0_0_0_0_0_1 - 2.43809523809522*G0_0_0_1_0_0 + 5.85142857142855*G0_0_0_2_0_1 - 8.7771428571428*G0_0_0_3_0_0 - 8.53333333333328*G0_0_0_3_0_1 + 13.1657142857142*G0_0_0_4_0_0 + 4.63238095238095*G0_0_0_4_0_1 + 2.92571428571428*G0_0_0_5_0_0 + 1.21904761904763*G0_0_0_5_0_1 - 13.1657142857142*G0_0_0_6_0_0 - 7.55809523809522*G0_0_0_6_0_1 - 1.95047619047616*G0_0_0_7_0_0 - 0.243809523809508*G0_0_0_7_0_1 + 3.90095238095235*G0_0_0_8_0_0 + 8.53333333333329*G0_0_0_8_0_1 + 5.85142857142852*G0_0_0_9_0_0 - 4.38857142857144*G0_0_0_9_0_1 + 0.487619047619039*G0_0_0_10_1_0 + 0.487619047619037*G0_0_0_10_1_1 - 2.43809523809522*G0_0_0_11_1_0 + 5.85142857142855*G0_0_0_12_1_1 - 8.7771428571428*G0_0_0_13_1_0 - 8.53333333333328*G0_0_0_13_1_1 + 13.1657142857142*G0_0_0_14_1_0 + 4.63238095238095*G0_0_0_14_1_1 + 2.92571428571428*G0_0_0_15_1_0 + 1.21904761904763*G0_0_0_15_1_1 - 13.1657142857142*G0_0_0_16_1_0 - 7.55809523809522*G0_0_0_16_1_1 - 1.95047619047616*G0_0_0_17_1_0 - 0.243809523809508*G0_0_0_17_1_1 + 3.90095238095235*G0_0_0_18_1_0 + 8.53333333333329*G0_0_0_18_1_1 + 5.85142857142852*G0_0_0_19_1_0 - 4.38857142857144*G0_0_0_19_1_1 - 3.16952380952379*G0_0_1_1_0_0 + 3.1695238095238*G0_0_1_2_0_1 - 4.26666666666664*G0_0_1_3_0_0 - 7.43619047619044*G0_0_1_3_0_1 + 7.43619047619046*G0_0_1_4_0_0 + 4.26666666666666*G0_0_1_4_0_1 + 2.07238095238095*G0_0_1_5_0_0 + 2.07238095238096*G0_0_1_5_0_1 - 7.43619047619046*G0_0_1_6_0_0 - 5.24190476190476*G0_0_1_6_0_1 - 2.07238095238093*G0_0_1_7_0_0 - 2.07238095238094*G0_0_1_7_0_1 + 5.24190476190473*G0_0_1_8_0_0 + 7.43619047619044*G0_0_1_8_0_1 + 2.19428571428569*G0_0_1_9_0_0 - 2.19428571428572*G0_0_1_9_0_1 - 3.16952380952379*G0_0_1_11_1_0 + 3.1695238095238*G0_0_1_12_1_1 - 4.26666666666664*G0_0_1_13_1_0 - 7.43619047619044*G0_0_1_13_1_1 + 7.43619047619046*G0_0_1_14_1_0 + 4.26666666666666*G0_0_1_14_1_1 + 2.07238095238095*G0_0_1_15_1_0 + 2.07238095238096*G0_0_1_15_1_1 - 7.43619047619046*G0_0_1_16_1_0 - 5.24190476190476*G0_0_1_16_1_1 - 2.07238095238093*G0_0_1_17_1_0 - 2.07238095238094*G0_0_1_17_1_1 + 5.24190476190473*G0_0_1_18_1_0 + 7.43619047619044*G0_0_1_18_1_1 + 2.19428571428569*G0_0_1_19_1_0 - 2.19428571428572*G0_0_1_19_1_1 - 3.16952380952379*G0_1_0_1_0_0 + 3.1695238095238*G0_1_0_2_0_1 - 4.26666666666664*G0_1_0_3_0_0 - 7.43619047619044*G0_1_0_3_0_1 + 7.43619047619046*G0_1_0_4_0_0 + 4.26666666666666*G0_1_0_4_0_1 + 2.07238095238095*G0_1_0_5_0_0 + 2.07238095238096*G0_1_0_5_0_1 - 7.43619047619046*G0_1_0_6_0_0 - 5.24190476190476*G0_1_0_6_0_1 - 2.07238095238093*G0_1_0_7_0_0 - 2.07238095238094*G0_1_0_7_0_1 + 5.24190476190473*G0_1_0_8_0_0 + 7.43619047619044*G0_1_0_8_0_1 + 2.19428571428569*G0_1_0_9_0_0 - 2.19428571428572*G0_1_0_9_0_1 - 3.16952380952379*G0_1_0_11_1_0 + 3.1695238095238*G0_1_0_12_1_1 - 4.26666666666664*G0_1_0_13_1_0 - 7.43619047619044*G0_1_0_13_1_1 + 7.43619047619046*G0_1_0_14_1_0 + 4.26666666666666*G0_1_0_14_1_1 + 2.07238095238095*G0_1_0_15_1_0 + 2.07238095238096*G0_1_0_15_1_1 - 7.43619047619046*G0_1_0_16_1_0 - 5.24190476190476*G0_1_0_16_1_1 - 2.07238095238093*G0_1_0_17_1_0 - 2.07238095238094*G0_1_0_17_1_1 + 5.24190476190473*G0_1_0_18_1_0 + 7.43619047619044*G0_1_0_18_1_1 + 2.19428571428569*G0_1_0_19_1_0 - 2.19428571428572*G0_1_0_19_1_1 - 0.487619047619051*G0_1_1_0_0_0 - 0.487619047619052*G0_1_1_0_0_1 - 5.85142857142854*G0_1_1_1_0_0 + 2.43809523809523*G0_1_1_2_0_1 - 4.63238095238093*G0_1_1_3_0_0 - 13.1657142857142*G0_1_1_3_0_1 + 8.53333333333331*G0_1_1_4_0_0 + 8.77714285714282*G0_1_1_4_0_1 + 0.243809523809524*G0_1_1_5_0_0 + 1.95047619047619*G0_1_1_5_0_1 - 8.53333333333331*G0_1_1_6_0_0 - 3.90095238095237*G0_1_1_6_0_1 - 1.2190476190476*G0_1_1_7_0_0 - 2.92571428571427*G0_1_1_7_0_1 + 7.55809523809518*G0_1_1_8_0_0 + 13.1657142857142*G0_1_1_8_0_1 + 4.38857142857141*G0_1_1_9_0_0 - 5.85142857142856*G0_1_1_9_0_1 - 0.487619047619051*G0_1_1_10_1_0 - 0.487619047619052*G0_1_1_10_1_1 - 5.85142857142854*G0_1_1_11_1_0 + 2.43809523809523*G0_1_1_12_1_1 - 4.63238095238093*G0_1_1_13_1_0 - 13.1657142857142*G0_1_1_13_1_1 + 8.53333333333331*G0_1_1_14_1_0 + 8.77714285714282*G0_1_1_14_1_1 + 0.243809523809524*G0_1_1_15_1_0 + 1.95047619047619*G0_1_1_15_1_1 - 8.53333333333331*G0_1_1_16_1_0 - 3.90095238095237*G0_1_1_16_1_1 - 1.2190476190476*G0_1_1_17_1_0 - 2.92571428571427*G0_1_1_17_1_1 + 7.55809523809518*G0_1_1_18_1_0 + 13.1657142857142*G0_1_1_18_1_1 + 4.38857142857141*G0_1_1_19_1_0 - 5.85142857142856*G0_1_1_19_1_1; + A[434] = A[899]; + A[624] = A[740] + 0.0203174603174589*G0_0_1_0_0_0 + 0.0203174603174589*G0_0_1_0_0_1 - 0.0203174603174583*G0_0_1_1_0_0 - 0.0203174603174597*G0_0_1_2_0_1 + 0.172698412698409*G0_0_1_3_0_0 + 0.0812698412698423*G0_0_1_3_0_1 - 0.0711111111111116*G0_0_1_4_0_0 + 0.0203174603174563*G0_0_1_4_0_1 + 0.13206349206349*G0_0_1_5_0_0 + 0.0609523809523817*G0_0_1_5_0_1 + 0.0711111111111116*G0_0_1_6_0_0 - 0.0609523809523809*G0_0_1_6_0_1 - 0.0914285714285682*G0_0_1_7_0_0 - 0.0203174603174605*G0_0_1_7_0_1 + 0.0914285714285678*G0_0_1_8_0_0 - 0.0812698412698424*G0_0_1_8_0_1 - 0.304761904761899*G0_0_1_9_0_0 + 0.0203174603174589*G0_0_1_10_1_0 + 0.0203174603174589*G0_0_1_10_1_1 - 0.0203174603174583*G0_0_1_11_1_0 - 0.0203174603174597*G0_0_1_12_1_1 + 0.172698412698409*G0_0_1_13_1_0 + 0.0812698412698423*G0_0_1_13_1_1 - 0.0711111111111116*G0_0_1_14_1_0 + 0.0203174603174563*G0_0_1_14_1_1 + 0.13206349206349*G0_0_1_15_1_0 + 0.0609523809523817*G0_0_1_15_1_1 + 0.0711111111111116*G0_0_1_16_1_0 - 0.0609523809523809*G0_0_1_16_1_1 - 0.0914285714285682*G0_0_1_17_1_0 - 0.0203174603174605*G0_0_1_17_1_1 + 0.0914285714285678*G0_0_1_18_1_0 - 0.0812698412698424*G0_0_1_18_1_1 - 0.304761904761899*G0_0_1_19_1_0 - 0.0203174603174589*G0_1_0_0_0_0 - 0.0203174603174589*G0_1_0_0_0_1 + 0.0203174603174584*G0_1_0_1_0_0 + 0.0203174603174597*G0_1_0_2_0_1 - 0.172698412698409*G0_1_0_3_0_0 - 0.0812698412698423*G0_1_0_3_0_1 + 0.0711111111111116*G0_1_0_4_0_0 - 0.0203174603174563*G0_1_0_4_0_1 - 0.13206349206349*G0_1_0_5_0_0 - 0.0609523809523818*G0_1_0_5_0_1 - 0.0711111111111116*G0_1_0_6_0_0 + 0.0609523809523809*G0_1_0_6_0_1 + 0.0914285714285683*G0_1_0_7_0_0 + 0.0203174603174607*G0_1_0_7_0_1 - 0.0914285714285678*G0_1_0_8_0_0 + 0.0812698412698424*G0_1_0_8_0_1 + 0.304761904761899*G0_1_0_9_0_0 - 0.0203174603174589*G0_1_0_10_1_0 - 0.0203174603174589*G0_1_0_10_1_1 + 0.0203174603174584*G0_1_0_11_1_0 + 0.0203174603174597*G0_1_0_12_1_1 - 0.172698412698409*G0_1_0_13_1_0 - 0.0812698412698423*G0_1_0_13_1_1 + 0.0711111111111116*G0_1_0_14_1_0 - 0.0203174603174563*G0_1_0_14_1_1 - 0.13206349206349*G0_1_0_15_1_0 - 0.0609523809523818*G0_1_0_15_1_1 - 0.0711111111111116*G0_1_0_16_1_0 + 0.0609523809523809*G0_1_0_16_1_1 + 0.0914285714285683*G0_1_0_17_1_0 + 0.0203174603174607*G0_1_0_17_1_1 - 0.0914285714285678*G0_1_0_18_1_0 + 0.0812698412698424*G0_1_0_18_1_1 + 0.304761904761899*G0_1_0_19_1_0; + A[249] = -A[624] - 0.528253968253966*G0_1_0_0_0_0 - 0.528253968253966*G0_1_0_0_0_1 + 0.142222222222219*G0_1_0_1_0_0 - 0.121904761904759*G0_1_0_3_0_0 - 0.111746031746033*G0_1_0_3_0_1 + 0.132063492063494*G0_1_0_4_0_1 - 0.121904761904762*G0_1_0_5_0_0 + 0.660317460317458*G0_1_0_5_0_1 - 0.132063492063492*G0_1_0_6_0_1 + 1.19873015873015*G0_1_0_7_0_0 + 0.416507936507932*G0_1_0_7_0_1 - 0.812698412698404*G0_1_0_8_0_0 + 0.111746031746033*G0_1_0_8_0_1 + 0.24380952380952*G0_1_0_9_0_0 - 0.548571428571426*G0_1_0_9_0_1 - 0.528253968253966*G0_1_0_10_1_0 - 0.528253968253966*G0_1_0_10_1_1 + 0.142222222222219*G0_1_0_11_1_0 - 0.121904761904759*G0_1_0_13_1_0 - 0.111746031746033*G0_1_0_13_1_1 + 0.132063492063494*G0_1_0_14_1_1 - 0.121904761904762*G0_1_0_15_1_0 + 0.660317460317458*G0_1_0_15_1_1 - 0.132063492063492*G0_1_0_16_1_1 + 1.19873015873015*G0_1_0_17_1_0 + 0.416507936507932*G0_1_0_17_1_1 - 0.812698412698404*G0_1_0_18_1_0 + 0.111746031746033*G0_1_0_18_1_1 + 0.24380952380952*G0_1_0_19_1_0 - 0.548571428571426*G0_1_0_19_1_1 + 0.826243386243381*G0_1_1_0_0_0 + 0.826243386243381*G0_1_1_0_0_1 + 0.128677248677247*G0_1_1_1_0_0 - 0.440211640211638*G0_1_1_2_0_1 - 0.294603174603172*G0_1_1_3_0_0 - 0.0406349206349221*G0_1_1_3_0_1 - 0.0507936507936511*G0_1_1_4_0_0 + 0.264126984126984*G0_1_1_4_0_1 - 0.497777777777777*G0_1_1_5_0_0 - 2.05206349206348*G0_1_1_5_0_1 + 0.0507936507936509*G0_1_1_6_0_0 + 1.66603174603174*G0_1_1_6_0_1 - 0.355555555555553*G0_1_1_7_0_0 + 1.19873015873015*G0_1_1_7_0_1 - 0.599365079365076*G0_1_1_8_0_0 + 0.0406349206349221*G0_1_1_8_0_1 + 0.792380952380949*G0_1_1_9_0_0 - 1.46285714285714*G0_1_1_9_0_1 + 0.826243386243381*G0_1_1_10_1_0 + 0.826243386243381*G0_1_1_10_1_1 + 0.128677248677247*G0_1_1_11_1_0 - 0.440211640211638*G0_1_1_12_1_1 - 0.294603174603172*G0_1_1_13_1_0 - 0.0406349206349221*G0_1_1_13_1_1 - 0.0507936507936511*G0_1_1_14_1_0 + 0.264126984126984*G0_1_1_14_1_1 - 0.497777777777777*G0_1_1_15_1_0 - 2.05206349206348*G0_1_1_15_1_1 + 0.0507936507936509*G0_1_1_16_1_0 + 1.66603174603174*G0_1_1_16_1_1 - 0.355555555555553*G0_1_1_17_1_0 + 1.19873015873015*G0_1_1_17_1_1 - 0.599365079365076*G0_1_1_18_1_0 + 0.0406349206349221*G0_1_1_18_1_1 + 0.792380952380949*G0_1_1_19_1_0 - 1.46285714285714*G0_1_1_19_1_1; + A[375] = 0.0; + A[52] = 0.0; + A[767] = A[70] + 0.0244444444444444*G0_0_1_0_0_0 + 0.0244444444444444*G0_0_1_0_0_1 + 0.0244444444444436*G0_0_1_1_0_0 - 0.00285714285714167*G0_0_1_3_0_0 + 0.0474603174603168*G0_0_1_3_0_1 - 0.0258730158730158*G0_0_1_4_0_1 - 0.00285714285714399*G0_0_1_5_0_0 - 0.0503174603174606*G0_0_1_5_0_1 + 0.0258730158730176*G0_0_1_6_0_1 - 0.0244444444444445*G0_0_1_7_0_0 + 0.0230158730158722*G0_0_1_7_0_1 - 0.0244444444444435*G0_0_1_8_0_0 - 0.0474603174603168*G0_0_1_8_0_1 + 0.00571428571428568*G0_0_1_9_0_0 + 0.00285714285714368*G0_0_1_9_0_1 + 0.0244444444444444*G0_0_1_10_1_0 + 0.0244444444444444*G0_0_1_10_1_1 + 0.0244444444444436*G0_0_1_11_1_0 - 0.00285714285714167*G0_0_1_13_1_0 + 0.0474603174603168*G0_0_1_13_1_1 - 0.0258730158730158*G0_0_1_14_1_1 - 0.00285714285714399*G0_0_1_15_1_0 - 0.0503174603174606*G0_0_1_15_1_1 + 0.0258730158730176*G0_0_1_16_1_1 - 0.0244444444444445*G0_0_1_17_1_0 + 0.0230158730158722*G0_0_1_17_1_1 - 0.0244444444444435*G0_0_1_18_1_0 - 0.0474603174603168*G0_0_1_18_1_1 + 0.00571428571428568*G0_0_1_19_1_0 + 0.00285714285714368*G0_0_1_19_1_1 - 0.0244444444444443*G0_1_0_0_0_0 - 0.0244444444444443*G0_1_0_0_0_1 - 0.0244444444444436*G0_1_0_1_0_0 + 0.00285714285714168*G0_1_0_3_0_0 - 0.0474603174603168*G0_1_0_3_0_1 + 0.0258730158730158*G0_1_0_4_0_1 + 0.00285714285714402*G0_1_0_5_0_0 + 0.0503174603174606*G0_1_0_5_0_1 - 0.0258730158730176*G0_1_0_6_0_1 + 0.0244444444444445*G0_1_0_7_0_0 - 0.0230158730158722*G0_1_0_7_0_1 + 0.0244444444444435*G0_1_0_8_0_0 + 0.0474603174603168*G0_1_0_8_0_1 - 0.00571428571428571*G0_1_0_9_0_0 - 0.00285714285714368*G0_1_0_9_0_1 - 0.0244444444444443*G0_1_0_10_1_0 - 0.0244444444444443*G0_1_0_10_1_1 - 0.0244444444444436*G0_1_0_11_1_0 + 0.00285714285714168*G0_1_0_13_1_0 - 0.0474603174603168*G0_1_0_13_1_1 + 0.0258730158730158*G0_1_0_14_1_1 + 0.00285714285714402*G0_1_0_15_1_0 + 0.0503174603174606*G0_1_0_15_1_1 - 0.0258730158730176*G0_1_0_16_1_1 + 0.0244444444444445*G0_1_0_17_1_0 - 0.0230158730158722*G0_1_0_17_1_1 + 0.0244444444444435*G0_1_0_18_1_0 + 0.0474603174603168*G0_1_0_18_1_1 - 0.00571428571428571*G0_1_0_19_1_0 - 0.00285714285714368*G0_1_0_19_1_1; + A[452] = 0.0; + A[81] = 0.0; + A[802] = -A[562] - 0.171005291005291*G0_0_0_0_0_0 - 0.171005291005292*G0_0_0_0_0_1 - 0.245502645502641*G0_0_0_1_0_0 + 0.0541798941798926*G0_0_0_2_0_1 + 0.929523809523809*G0_0_0_3_0_0 + 0.21587301587302*G0_0_0_3_0_1 - 0.41142857142857*G0_0_0_4_0_0 + 0.00253968253968436*G0_0_0_4_0_1 + 1.47809523809523*G0_0_0_5_0_0 + 1.3231746031746*G0_0_0_5_0_1 + 0.411428571428571*G0_0_0_6_0_0 - 1.2063492063492*G0_0_0_6_0_1 - 0.203174603174597*G0_0_0_7_0_0 - 0.0482539682539652*G0_0_0_7_0_1 + 0.61968253968253*G0_0_0_8_0_0 - 0.21587301587302*G0_0_0_8_0_1 - 2.40761904761904*G0_0_0_9_0_0 + 0.045714285714281*G0_0_0_9_0_1 - 0.171005291005291*G0_0_0_10_1_0 - 0.171005291005292*G0_0_0_10_1_1 - 0.245502645502641*G0_0_0_11_1_0 + 0.0541798941798926*G0_0_0_12_1_1 + 0.929523809523809*G0_0_0_13_1_0 + 0.21587301587302*G0_0_0_13_1_1 - 0.41142857142857*G0_0_0_14_1_0 + 0.00253968253968436*G0_0_0_14_1_1 + 1.47809523809523*G0_0_0_15_1_0 + 1.3231746031746*G0_0_0_15_1_1 + 0.411428571428571*G0_0_0_16_1_0 - 1.2063492063492*G0_0_0_16_1_1 - 0.203174603174597*G0_0_0_17_1_0 - 0.0482539682539652*G0_0_0_17_1_1 + 0.61968253968253*G0_0_0_18_1_0 - 0.21587301587302*G0_0_0_18_1_1 - 2.40761904761904*G0_0_0_19_1_0 + 0.045714285714281*G0_0_0_19_1_1 - 0.116825396825393*G0_0_1_0_0_0 - 0.116825396825393*G0_0_1_0_0_1 - 0.116825396825396*G0_0_1_2_0_1 + 0.0939682539682571*G0_0_1_3_0_0 - 0.256507936507935*G0_0_1_4_0_0 - 0.0457142857142838*G0_0_1_4_0_1 - 0.139682539682534*G0_0_1_5_0_0 + 0.116825396825392*G0_0_1_5_0_1 + 0.256507936507935*G0_0_1_6_0_0 + 0.116825396825397*G0_0_1_6_0_1 + 0.210793650793645*G0_0_1_7_0_0 - 0.0457142857142807*G0_0_1_7_0_1 - 0.0939682539682537*G0_0_1_8_0_0 + 0.0457142857142768*G0_0_1_9_0_0 + 0.0914285714285639*G0_0_1_9_0_1 - 0.116825396825393*G0_0_1_10_1_0 - 0.116825396825393*G0_0_1_10_1_1 - 0.116825396825396*G0_0_1_12_1_1 + 0.0939682539682571*G0_0_1_13_1_0 - 0.256507936507935*G0_0_1_14_1_0 - 0.0457142857142838*G0_0_1_14_1_1 - 0.139682539682534*G0_0_1_15_1_0 + 0.116825396825392*G0_0_1_15_1_1 + 0.256507936507935*G0_0_1_16_1_0 + 0.116825396825397*G0_0_1_16_1_1 + 0.210793650793645*G0_0_1_17_1_0 - 0.0457142857142807*G0_0_1_17_1_1 - 0.0939682539682537*G0_0_1_18_1_0 + 0.0457142857142768*G0_0_1_19_1_0 + 0.0914285714285639*G0_0_1_19_1_1; + A[13] = A[855] - 0.111746031746032*G0_0_1_1_0_0 - 0.0101587301587305*G0_0_1_2_0_1 + 0.0901587301587284*G0_0_1_3_0_0 - 0.143492063492063*G0_0_1_3_0_1 + 0.0215873015873021*G0_0_1_4_0_0 + 0.153650793650793*G0_0_1_4_0_1 + 0.069841269841269*G0_0_1_5_0_0 + 0.0698412698412638*G0_0_1_5_0_1 - 0.021587301587302*G0_0_1_6_0_0 - 0.0596825396825367*G0_0_1_6_0_1 - 0.0698412698412742*G0_0_1_7_0_0 - 0.069841269841269*G0_0_1_7_0_1 + 0.181587301587303*G0_0_1_8_0_0 + 0.143492063492063*G0_0_1_8_0_1 - 0.159999999999998*G0_0_1_9_0_0 - 0.0838095238095233*G0_0_1_9_0_1 - 0.111746031746032*G0_0_1_11_1_0 - 0.0101587301587305*G0_0_1_12_1_1 + 0.0901587301587284*G0_0_1_13_1_0 - 0.143492063492063*G0_0_1_13_1_1 + 0.0215873015873021*G0_0_1_14_1_0 + 0.153650793650793*G0_0_1_14_1_1 + 0.069841269841269*G0_0_1_15_1_0 + 0.0698412698412638*G0_0_1_15_1_1 - 0.021587301587302*G0_0_1_16_1_0 - 0.0596825396825367*G0_0_1_16_1_1 - 0.0698412698412742*G0_0_1_17_1_0 - 0.069841269841269*G0_0_1_17_1_1 + 0.181587301587303*G0_0_1_18_1_0 + 0.143492063492063*G0_0_1_18_1_1 - 0.159999999999998*G0_0_1_19_1_0 - 0.0838095238095233*G0_0_1_19_1_1 + 0.111746031746032*G0_1_0_1_0_0 + 0.0101587301587305*G0_1_0_2_0_1 - 0.0901587301587286*G0_1_0_3_0_0 + 0.143492063492063*G0_1_0_3_0_1 - 0.0215873015873021*G0_1_0_4_0_0 - 0.153650793650793*G0_1_0_4_0_1 - 0.069841269841269*G0_1_0_5_0_0 - 0.0698412698412637*G0_1_0_5_0_1 + 0.021587301587302*G0_1_0_6_0_0 + 0.0596825396825366*G0_1_0_6_0_1 + 0.0698412698412743*G0_1_0_7_0_0 + 0.069841269841269*G0_1_0_7_0_1 - 0.181587301587303*G0_1_0_8_0_0 - 0.143492063492063*G0_1_0_8_0_1 + 0.159999999999998*G0_1_0_9_0_0 + 0.0838095238095234*G0_1_0_9_0_1 + 0.111746031746032*G0_1_0_11_1_0 + 0.0101587301587305*G0_1_0_12_1_1 - 0.0901587301587286*G0_1_0_13_1_0 + 0.143492063492063*G0_1_0_13_1_1 - 0.0215873015873021*G0_1_0_14_1_0 - 0.153650793650793*G0_1_0_14_1_1 - 0.069841269841269*G0_1_0_15_1_0 - 0.0698412698412637*G0_1_0_15_1_1 + 0.021587301587302*G0_1_0_16_1_0 + 0.0596825396825366*G0_1_0_16_1_1 + 0.0698412698412743*G0_1_0_17_1_0 + 0.069841269841269*G0_1_0_17_1_1 - 0.181587301587303*G0_1_0_18_1_0 - 0.143492063492063*G0_1_0_18_1_1 + 0.159999999999998*G0_1_0_19_1_0 + 0.0838095238095234*G0_1_0_19_1_1; + A[98] = -A[803] + 0.0135449735449745*G0_0_0_0_0_0 + 0.0135449735449744*G0_0_0_0_0_1 - 0.440211640211639*G0_0_0_1_0_0 - 1.35449735449735*G0_0_0_2_0_1 + 1.74730158730158*G0_0_0_3_0_0 - 0.0507936507936532*G0_0_0_3_0_1 - 2.33650793650792*G0_0_0_4_0_0 + 0.375873015873014*G0_0_0_4_0_1 - 0.284444444444444*G0_0_0_5_0_0 - 0.213333333333334*G0_0_0_5_0_1 + 2.33650793650792*G0_0_0_6_0_0 + 1.55428571428571*G0_0_0_6_0_1 + 0.24380952380952*G0_0_0_7_0_0 + 0.172698412698409*G0_0_0_7_0_1 + 0.182857142857145*G0_0_0_8_0_0 + 0.0507936507936529*G0_0_0_8_0_1 - 1.46285714285713*G0_0_0_9_0_0 - 0.548571428571423*G0_0_0_9_0_1 + 0.0135449735449745*G0_0_0_10_1_0 + 0.0135449735449744*G0_0_0_10_1_1 - 0.440211640211639*G0_0_0_11_1_0 - 1.35449735449735*G0_0_0_12_1_1 + 1.74730158730158*G0_0_0_13_1_0 - 0.0507936507936532*G0_0_0_13_1_1 - 2.33650793650792*G0_0_0_14_1_0 + 0.375873015873014*G0_0_0_14_1_1 - 0.284444444444444*G0_0_0_15_1_0 - 0.213333333333334*G0_0_0_15_1_1 + 2.33650793650792*G0_0_0_16_1_0 + 1.55428571428571*G0_0_0_16_1_1 + 0.24380952380952*G0_0_0_17_1_0 + 0.172698412698409*G0_0_0_17_1_1 + 0.182857142857145*G0_0_0_18_1_0 + 0.0507936507936529*G0_0_0_18_1_1 - 1.46285714285713*G0_0_0_19_1_0 - 0.548571428571423*G0_0_0_19_1_1 + 0.142222222222221*G0_0_1_0_0_0 + 0.142222222222221*G0_0_1_0_0_1 - 0.528253968253965*G0_0_1_2_0_1 + 0.132063492063487*G0_0_1_3_0_0 - 0.782222222222218*G0_0_1_4_0_0 - 0.121904761904762*G0_0_1_4_0_1 - 0.924444444444442*G0_0_1_5_0_0 - 0.812698412698407*G0_0_1_5_0_1 + 0.782222222222217*G0_0_1_6_0_0 + 1.19873015873015*G0_0_1_6_0_1 - 0.0101587301587299*G0_0_1_7_0_0 - 0.121904761904765*G0_0_1_7_0_1 - 0.132063492063488*G0_0_1_8_0_0 + 0.792380952380955*G0_0_1_9_0_0 + 0.243809523809527*G0_0_1_9_0_1 + 0.142222222222221*G0_0_1_10_1_0 + 0.142222222222221*G0_0_1_10_1_1 - 0.528253968253965*G0_0_1_12_1_1 + 0.132063492063487*G0_0_1_13_1_0 - 0.782222222222218*G0_0_1_14_1_0 - 0.121904761904762*G0_0_1_14_1_1 - 0.924444444444442*G0_0_1_15_1_0 - 0.812698412698407*G0_0_1_15_1_1 + 0.782222222222217*G0_0_1_16_1_0 + 1.19873015873015*G0_0_1_16_1_1 - 0.0101587301587299*G0_0_1_17_1_0 - 0.121904761904765*G0_0_1_17_1_1 - 0.132063492063488*G0_0_1_18_1_0 + 0.792380952380955*G0_0_1_19_1_0 + 0.243809523809527*G0_0_1_19_1_1; + A[560] = -A[98] + 0.318306878306877*G0_0_1_0_0_0 + 0.318306878306877*G0_0_1_0_0_1 - 0.115132275132276*G0_0_1_1_0_0 - 0.64338624338624*G0_0_1_2_0_1 - 1.11746031746032*G0_0_1_3_0_0 - 0.640000000000002*G0_0_1_3_0_1 - 1.42222222222222*G0_0_1_4_0_0 - 1.37142857142857*G0_0_1_4_0_1 - 1.32063492063492*G0_0_1_5_0_0 - 1.1479365079365*G0_0_1_5_0_1 + 1.42222222222222*G0_0_1_6_0_0 + 1.47301587301587*G0_0_1_6_0_1 - 0.345396825396825*G0_0_1_7_0_0 - 0.518095238095239*G0_0_1_7_0_1 + 0.142222222222224*G0_0_1_8_0_0 + 0.640000000000003*G0_0_1_8_0_1 + 2.43809523809523*G0_0_1_9_0_0 + 1.88952380952381*G0_0_1_9_0_1 + 0.318306878306877*G0_0_1_10_1_0 + 0.318306878306877*G0_0_1_10_1_1 - 0.115132275132276*G0_0_1_11_1_0 - 0.64338624338624*G0_0_1_12_1_1 - 1.11746031746032*G0_0_1_13_1_0 - 0.640000000000002*G0_0_1_13_1_1 - 1.42222222222222*G0_0_1_14_1_0 - 1.37142857142857*G0_0_1_14_1_1 - 1.32063492063492*G0_0_1_15_1_0 - 1.1479365079365*G0_0_1_15_1_1 + 1.42222222222222*G0_0_1_16_1_0 + 1.47301587301587*G0_0_1_16_1_1 - 0.345396825396825*G0_0_1_17_1_0 - 0.518095238095239*G0_0_1_17_1_1 + 0.142222222222224*G0_0_1_18_1_0 + 0.640000000000003*G0_0_1_18_1_1 + 2.43809523809523*G0_0_1_19_1_0 + 1.88952380952381*G0_0_1_19_1_1 - 0.0135449735449751*G0_1_1_0_0_0 - 0.0135449735449747*G0_1_1_0_0_1 + 1.35449735449736*G0_1_1_1_0_0 + 0.44021164021164*G0_1_1_2_0_1 - 0.375873015873017*G0_1_1_3_0_0 + 2.33650793650794*G0_1_1_3_0_1 + 0.0507936507936506*G0_1_1_4_0_0 - 1.74730158730159*G0_1_1_4_0_1 - 0.172698412698414*G0_1_1_5_0_0 - 0.243809523809523*G0_1_1_5_0_1 - 0.0507936507936508*G0_1_1_6_0_0 - 0.182857142857143*G0_1_1_6_0_1 + 0.213333333333337*G0_1_1_7_0_0 + 0.284444444444446*G0_1_1_7_0_1 - 1.55428571428572*G0_1_1_8_0_0 - 2.33650793650793*G0_1_1_8_0_1 + 0.548571428571431*G0_1_1_9_0_0 + 1.46285714285714*G0_1_1_9_0_1 - 0.0135449735449751*G0_1_1_10_1_0 - 0.0135449735449747*G0_1_1_10_1_1 + 1.35449735449736*G0_1_1_11_1_0 + 0.44021164021164*G0_1_1_12_1_1 - 0.375873015873017*G0_1_1_13_1_0 + 2.33650793650794*G0_1_1_13_1_1 + 0.0507936507936506*G0_1_1_14_1_0 - 1.74730158730159*G0_1_1_14_1_1 - 0.172698412698414*G0_1_1_15_1_0 - 0.243809523809523*G0_1_1_15_1_1 - 0.0507936507936508*G0_1_1_16_1_0 - 0.182857142857143*G0_1_1_16_1_1 + 0.213333333333337*G0_1_1_17_1_0 + 0.284444444444446*G0_1_1_17_1_1 - 1.55428571428572*G0_1_1_18_1_0 - 2.33650793650793*G0_1_1_18_1_1 + 0.548571428571431*G0_1_1_19_1_0 + 1.46285714285714*G0_1_1_19_1_1; + A[869] = A[560] - 0.595978835978832*G0_0_0_0_0_0 - 0.595978835978833*G0_0_0_0_0_1 - 1.76084656084655*G0_0_0_1_0_0 - 2.77671957671956*G0_0_0_2_0_1 + 6.62349206349203*G0_0_0_3_0_0 - 5.38412698412696*G0_0_0_4_0_0 + 2.25523809523808*G0_0_0_4_0_1 + 3.3726984126984*G0_0_0_5_0_0 + 3.08825396825396*G0_0_0_5_0_1 + 5.38412698412696*G0_0_0_6_0_0 + 0.284444444444441*G0_0_0_6_0_1 + 0.751746031746026*G0_0_0_7_0_0 + 1.03619047619047*G0_0_0_7_0_1 + 1.60507936507936*G0_0_0_8_0_0 - 9.99619047619043*G0_0_0_9_0_0 - 3.29142857142855*G0_0_0_9_0_1 - 0.595978835978832*G0_0_0_10_1_0 - 0.595978835978833*G0_0_0_10_1_1 - 1.76084656084655*G0_0_0_11_1_0 - 2.77671957671956*G0_0_0_12_1_1 + 6.62349206349203*G0_0_0_13_1_0 - 5.38412698412696*G0_0_0_14_1_0 + 2.25523809523808*G0_0_0_14_1_1 + 3.3726984126984*G0_0_0_15_1_0 + 3.08825396825396*G0_0_0_15_1_1 + 5.38412698412696*G0_0_0_16_1_0 + 0.284444444444441*G0_0_0_16_1_1 + 0.751746031746026*G0_0_0_17_1_0 + 1.03619047619047*G0_0_0_17_1_1 + 1.60507936507936*G0_0_0_18_1_0 - 9.99619047619043*G0_0_0_19_1_0 - 3.29142857142855*G0_0_0_19_1_1 + 0.26074074074074*G0_0_1_0_0_0 + 0.26074074074074*G0_0_1_0_0_1 - 1.17502645502645*G0_0_1_1_0_0 - 1.17502645502645*G0_0_1_2_0_1 + 4.51047619047616*G0_0_1_3_0_0 - 0.0914285714285684*G0_0_1_3_0_1 - 0.0914285714285634*G0_0_1_4_0_0 + 4.51047619047617*G0_0_1_4_0_1 - 1.15809523809523*G0_0_1_5_0_0 - 1.09714285714285*G0_0_1_5_0_1 + 0.0914285714285651*G0_0_1_6_0_0 + 2.01142857142856*G0_0_1_6_0_1 - 1.09714285714286*G0_0_1_7_0_0 - 1.15809523809524*G0_0_1_7_0_1 + 2.01142857142856*G0_0_1_8_0_0 + 0.091428571428569*G0_0_1_8_0_1 - 3.35238095238093*G0_0_1_9_0_0 - 3.35238095238093*G0_0_1_9_0_1 + 0.26074074074074*G0_0_1_10_1_0 + 0.26074074074074*G0_0_1_10_1_1 - 1.17502645502645*G0_0_1_11_1_0 - 1.17502645502645*G0_0_1_12_1_1 + 4.51047619047616*G0_0_1_13_1_0 - 0.0914285714285684*G0_0_1_13_1_1 - 0.0914285714285634*G0_0_1_14_1_0 + 4.51047619047617*G0_0_1_14_1_1 - 1.15809523809523*G0_0_1_15_1_0 - 1.09714285714285*G0_0_1_15_1_1 + 0.0914285714285651*G0_0_1_16_1_0 + 2.01142857142856*G0_0_1_16_1_1 - 1.09714285714286*G0_0_1_17_1_0 - 1.15809523809524*G0_0_1_17_1_1 + 2.01142857142856*G0_0_1_18_1_0 + 0.091428571428569*G0_0_1_18_1_1 - 3.35238095238093*G0_0_1_19_1_0 - 3.35238095238093*G0_0_1_19_1_1 - 0.518095238095236*G0_1_0_0_0_0 - 0.518095238095236*G0_1_0_0_0_1 - 0.335238095238093*G0_1_0_1_0_0 - 0.335238095238093*G0_1_0_2_0_1 + 3.98222222222221*G0_1_0_3_0_0 + 0.782222222222221*G0_1_0_3_0_1 + 0.782222222222223*G0_1_0_4_0_0 + 3.98222222222221*G0_1_0_4_0_1 + 1.0768253968254*G0_1_0_5_0_0 + 1.03619047619048*G0_1_0_5_0_1 - 0.782222222222221*G0_1_0_6_0_0 - 0.182857142857146*G0_1_0_6_0_1 + 1.03619047619047*G0_1_0_7_0_0 + 1.0768253968254*G0_1_0_7_0_1 - 0.182857142857145*G0_1_0_8_0_0 - 0.78222222222222*G0_1_0_8_0_1 - 5.05904761904761*G0_1_0_9_0_0 - 5.0590476190476*G0_1_0_9_0_1 - 0.518095238095236*G0_1_0_10_1_0 - 0.518095238095236*G0_1_0_10_1_1 - 0.335238095238093*G0_1_0_11_1_0 - 0.335238095238093*G0_1_0_12_1_1 + 3.98222222222221*G0_1_0_13_1_0 + 0.782222222222221*G0_1_0_13_1_1 + 0.782222222222223*G0_1_0_14_1_0 + 3.98222222222221*G0_1_0_14_1_1 + 1.0768253968254*G0_1_0_15_1_0 + 1.03619047619048*G0_1_0_15_1_1 - 0.782222222222221*G0_1_0_16_1_0 - 0.182857142857146*G0_1_0_16_1_1 + 1.03619047619047*G0_1_0_17_1_0 + 1.0768253968254*G0_1_0_17_1_1 - 0.182857142857145*G0_1_0_18_1_0 - 0.78222222222222*G0_1_0_18_1_1 - 5.05904761904761*G0_1_0_19_1_0 - 5.0590476190476*G0_1_0_19_1_1 - 0.595978835978831*G0_1_1_0_0_0 - 0.595978835978832*G0_1_1_0_0_1 - 2.77671957671957*G0_1_1_1_0_0 - 1.76084656084655*G0_1_1_2_0_1 + 2.25523809523808*G0_1_1_3_0_0 - 5.38412698412697*G0_1_1_3_0_1 + 6.62349206349204*G0_1_1_4_0_1 + 1.03619047619047*G0_1_1_5_0_0 + 0.75174603174603*G0_1_1_5_0_1 + 1.60507936507935*G0_1_1_6_0_1 + 3.08825396825395*G0_1_1_7_0_0 + 3.37269841269839*G0_1_1_7_0_1 + 0.28444444444445*G0_1_1_8_0_0 + 5.38412698412697*G0_1_1_8_0_1 - 3.29142857142855*G0_1_1_9_0_0 - 9.99619047619043*G0_1_1_9_0_1 - 0.595978835978831*G0_1_1_10_1_0 - 0.595978835978832*G0_1_1_10_1_1 - 2.77671957671957*G0_1_1_11_1_0 - 1.76084656084655*G0_1_1_12_1_1 + 2.25523809523808*G0_1_1_13_1_0 - 5.38412698412697*G0_1_1_13_1_1 + 6.62349206349204*G0_1_1_14_1_1 + 1.03619047619047*G0_1_1_15_1_0 + 0.75174603174603*G0_1_1_15_1_1 + 1.60507936507935*G0_1_1_16_1_1 + 3.08825396825395*G0_1_1_17_1_0 + 3.37269841269839*G0_1_1_17_1_1 + 0.28444444444445*G0_1_1_18_1_0 + 5.38412698412697*G0_1_1_18_1_1 - 3.29142857142855*G0_1_1_19_1_0 - 9.99619047619043*G0_1_1_19_1_1; + A[404] = A[869]; + A[817] = 0.0; + A[38] = A[36] + 0.126984126984126*G0_0_0_0_0_0 + 0.126984126984126*G0_0_0_0_0_1 + 0.256507936507935*G0_0_0_2_0_1 - 0.218412698412697*G0_0_0_3_0_0 + 0.4215873015873*G0_0_0_4_0_0 - 0.053333333333333*G0_0_0_4_0_1 + 0.294603174603173*G0_0_0_5_0_0 + 0.00253968253968256*G0_0_0_5_0_1 - 0.4215873015873*G0_0_0_6_0_0 - 0.386031746031744*G0_0_0_6_0_1 - 0.345396825396823*G0_0_0_7_0_0 - 0.0533333333333324*G0_0_0_7_0_1 + 0.218412698412696*G0_0_0_8_0_0 - 0.0761904761904755*G0_0_0_9_0_0 + 0.106666666666666*G0_0_0_9_0_1 + 0.126984126984126*G0_0_0_10_1_0 + 0.126984126984126*G0_0_0_10_1_1 + 0.256507936507935*G0_0_0_12_1_1 - 0.218412698412697*G0_0_0_13_1_0 + 0.4215873015873*G0_0_0_14_1_0 - 0.053333333333333*G0_0_0_14_1_1 + 0.294603174603173*G0_0_0_15_1_0 + 0.00253968253968256*G0_0_0_15_1_1 - 0.4215873015873*G0_0_0_16_1_0 - 0.386031746031744*G0_0_0_16_1_1 - 0.345396825396823*G0_0_0_17_1_0 - 0.0533333333333324*G0_0_0_17_1_1 + 0.218412698412696*G0_0_0_18_1_0 - 0.0761904761904755*G0_0_0_19_1_0 + 0.106666666666666*G0_0_0_19_1_1 - 0.12952380952381*G0_0_1_0_0_0 - 0.12952380952381*G0_0_1_0_0_1 + 0.129523809523809*G0_0_1_2_0_1 + 0.129523809523808*G0_0_1_4_0_0 + 0.259047619047618*G0_0_1_5_0_0 + 0.388571428571428*G0_0_1_5_0_1 - 0.129523809523808*G0_0_1_6_0_0 - 0.388571428571427*G0_0_1_6_0_1 + 0.129523809523811*G0_0_1_7_0_0 - 0.259047619047618*G0_0_1_9_0_0 - 0.12952380952381*G0_0_1_10_1_0 - 0.12952380952381*G0_0_1_10_1_1 + 0.129523809523809*G0_0_1_12_1_1 + 0.129523809523808*G0_0_1_14_1_0 + 0.259047619047618*G0_0_1_15_1_0 + 0.388571428571428*G0_0_1_15_1_1 - 0.129523809523808*G0_0_1_16_1_0 - 0.388571428571427*G0_0_1_16_1_1 + 0.129523809523811*G0_0_1_17_1_0 - 0.259047619047618*G0_0_1_19_1_0; + A[500] = -A[38] - 0.0876190476190475*G0_0_1_0_0_0 - 0.0876190476190473*G0_0_1_0_0_1 + 0.590476190476191*G0_0_1_1_0_0 + 0.285714285714285*G0_0_1_2_0_1 + 0.0622222222222224*G0_0_1_3_0_0 + 1.07936507936508*G0_0_1_3_0_1 + 0.260317460317458*G0_0_1_4_0_0 - 0.452063492063493*G0_0_1_4_0_1 + 0.227301587301586*G0_0_1_5_0_0 + 0.156190476190475*G0_0_1_5_0_1 - 0.260317460317458*G0_0_1_6_0_0 - 0.354285714285712*G0_0_1_6_0_1 + 0.251428571428572*G0_0_1_7_0_0 + 0.322539682539683*G0_0_1_7_0_1 - 0.754285714285715*G0_0_1_8_0_0 - 1.07936507936508*G0_0_1_8_0_1 - 0.289523809523808*G0_0_1_9_0_0 + 0.12952380952381*G0_0_1_9_0_1 - 0.0876190476190475*G0_0_1_10_1_0 - 0.0876190476190473*G0_0_1_10_1_1 + 0.590476190476191*G0_0_1_11_1_0 + 0.285714285714285*G0_0_1_12_1_1 + 0.0622222222222224*G0_0_1_13_1_0 + 1.07936507936508*G0_0_1_13_1_1 + 0.260317460317458*G0_0_1_14_1_0 - 0.452063492063493*G0_0_1_14_1_1 + 0.227301587301586*G0_0_1_15_1_0 + 0.156190476190475*G0_0_1_15_1_1 - 0.260317460317458*G0_0_1_16_1_0 - 0.354285714285712*G0_0_1_16_1_1 + 0.251428571428572*G0_0_1_17_1_0 + 0.322539682539683*G0_0_1_17_1_1 - 0.754285714285715*G0_0_1_18_1_0 - 1.07936507936508*G0_0_1_18_1_1 - 0.289523809523808*G0_0_1_19_1_0 + 0.12952380952381*G0_0_1_19_1_1; + A[504] = -A[500] + 0.41100529100529*G0_0_0_0_0_0 + 0.41100529100529*G0_0_0_0_0_1 - 0.649735449735448*G0_0_0_1_0_0 - 0.309417989417988*G0_0_0_2_0_1 + 0.139682539682539*G0_0_0_3_0_0 - 0.895238095238094*G0_0_0_3_0_1 - 0.370793650793649*G0_0_0_4_0_0 + 0.323809523809523*G0_0_0_4_0_1 + 0.0965079365079358*G0_0_0_5_0_0 - 0.439365079365079*G0_0_0_5_0_1 + 0.370793650793649*G0_0_0_6_0_0 + 0.337777777777778*G0_0_0_6_0_1 - 0.935873015873013*G0_0_0_7_0_0 - 0.399999999999999*G0_0_0_7_0_1 + 1.17460317460317*G0_0_0_8_0_0 + 0.895238095238094*G0_0_0_8_0_1 - 0.236190476190475*G0_0_0_9_0_0 + 0.0761904761904749*G0_0_0_9_0_1 + 0.41100529100529*G0_0_0_10_1_0 + 0.41100529100529*G0_0_0_10_1_1 - 0.649735449735448*G0_0_0_11_1_0 - 0.309417989417988*G0_0_0_12_1_1 + 0.139682539682539*G0_0_0_13_1_0 - 0.895238095238094*G0_0_0_13_1_1 - 0.370793650793649*G0_0_0_14_1_0 + 0.323809523809523*G0_0_0_14_1_1 + 0.0965079365079358*G0_0_0_15_1_0 - 0.439365079365079*G0_0_0_15_1_1 + 0.370793650793649*G0_0_0_16_1_0 + 0.337777777777778*G0_0_0_16_1_1 - 0.935873015873013*G0_0_0_17_1_0 - 0.399999999999999*G0_0_0_17_1_1 + 1.17460317460317*G0_0_0_18_1_0 + 0.895238095238094*G0_0_0_18_1_1 - 0.236190476190475*G0_0_0_19_1_0 + 0.0761904761904749*G0_0_0_19_1_1 + 0.101587301587301*G0_0_1_0_0_0 + 0.1015873015873*G0_0_1_0_0_1 + 0.101587301587301*G0_0_1_2_0_1 - 0.139682539682539*G0_0_1_3_0_0 + 0.165079365079363*G0_0_1_4_0_0 - 0.0761904761904786*G0_0_1_4_0_1 + 0.0634920634920629*G0_0_1_5_0_0 - 0.101587301587301*G0_0_1_5_0_1 - 0.165079365079363*G0_0_1_6_0_0 - 0.101587301587301*G0_0_1_6_0_1 - 0.241269841269838*G0_0_1_7_0_0 - 0.0761904761904739*G0_0_1_7_0_1 + 0.139682539682534*G0_0_1_8_0_0 + 0.0761904761904757*G0_0_1_9_0_0 + 0.152380952380952*G0_0_1_9_0_1 + 0.101587301587301*G0_0_1_10_1_0 + 0.1015873015873*G0_0_1_10_1_1 + 0.101587301587301*G0_0_1_12_1_1 - 0.139682539682539*G0_0_1_13_1_0 + 0.165079365079363*G0_0_1_14_1_0 - 0.0761904761904786*G0_0_1_14_1_1 + 0.0634920634920629*G0_0_1_15_1_0 - 0.101587301587301*G0_0_1_15_1_1 - 0.165079365079363*G0_0_1_16_1_0 - 0.101587301587301*G0_0_1_16_1_1 - 0.241269841269838*G0_0_1_17_1_0 - 0.0761904761904739*G0_0_1_17_1_1 + 0.139682539682534*G0_0_1_18_1_0 + 0.0761904761904757*G0_0_1_19_1_0 + 0.152380952380952*G0_0_1_19_1_1; + A[840] = 0.0; + A[75] = 0.0; + A[152] = A[617]; + A[875] = 0.0; + A[486] = 0.0; + A[189] = A[654]; + A[517] = 0.0; + A[620] = -A[245] + 0.406349206349206*G0_1_0_0_0_0 + 0.406349206349206*G0_1_0_0_0_1 - 0.406349206349206*G0_1_0_1_0_0 - 1.93015873015872*G0_1_0_2_0_1 + 1.93015873015872*G0_1_0_3_0_0 - 0.0507936507936547*G0_1_0_3_0_1 - 2.64126984126983*G0_1_0_4_0_0 + 0.86349206349206*G0_1_0_4_0_1 - 1.93015873015872*G0_1_0_5_0_0 - 1.98095238095238*G0_1_0_5_0_1 + 2.64126984126983*G0_1_0_6_0_0 + 3.50476190476189*G0_1_0_6_0_1 + 0.0507936507936499*G0_1_0_7_0_1 + 0.0507936507936545*G0_1_0_8_0_1 - 0.914285714285711*G0_1_0_9_0_1 + 0.406349206349206*G0_1_0_10_1_0 + 0.406349206349206*G0_1_0_10_1_1 - 0.406349206349206*G0_1_0_11_1_0 - 1.93015873015872*G0_1_0_12_1_1 + 1.93015873015872*G0_1_0_13_1_0 - 0.0507936507936547*G0_1_0_13_1_1 - 2.64126984126983*G0_1_0_14_1_0 + 0.86349206349206*G0_1_0_14_1_1 - 1.93015873015872*G0_1_0_15_1_0 - 1.98095238095238*G0_1_0_15_1_1 + 2.64126984126983*G0_1_0_16_1_0 + 3.50476190476189*G0_1_0_16_1_1 + 0.0507936507936499*G0_1_0_17_1_1 + 0.0507936507936545*G0_1_0_18_1_1 - 0.914285714285711*G0_1_0_19_1_1 - 0.270899470899469*G0_1_1_0_0_0 - 0.270899470899469*G0_1_1_0_0_1 + 0.372486772486775*G0_1_1_1_0_0 + 0.778835978835977*G0_1_1_2_0_1 + 2.28571428571427*G0_1_1_3_0_0 + 1.62539682539682*G0_1_1_3_0_1 + 2.28571428571428*G0_1_1_4_0_0 + 2.53968253968253*G0_1_1_4_0_1 + 0.457142857142852*G0_1_1_5_0_0 + 0.507936507936501*G0_1_1_5_0_1 - 2.28571428571428*G0_1_1_6_0_0 - 1.01587301587301*G0_1_1_6_0_1 - 0.0507936507936492*G0_1_1_7_0_0 - 0.101587301587298*G0_1_1_7_0_1 - 0.0507936507936571*G0_1_1_8_0_0 - 1.62539682539682*G0_1_1_8_0_1 - 2.74285714285713*G0_1_1_9_0_0 - 2.43809523809523*G0_1_1_9_0_1 - 0.270899470899469*G0_1_1_10_1_0 - 0.270899470899469*G0_1_1_10_1_1 + 0.372486772486775*G0_1_1_11_1_0 + 0.778835978835977*G0_1_1_12_1_1 + 2.28571428571427*G0_1_1_13_1_0 + 1.62539682539682*G0_1_1_13_1_1 + 2.28571428571428*G0_1_1_14_1_0 + 2.53968253968253*G0_1_1_14_1_1 + 0.457142857142852*G0_1_1_15_1_0 + 0.507936507936501*G0_1_1_15_1_1 - 2.28571428571428*G0_1_1_16_1_0 - 1.01587301587301*G0_1_1_16_1_1 - 0.0507936507936492*G0_1_1_17_1_0 - 0.101587301587298*G0_1_1_17_1_1 - 0.0507936507936571*G0_1_1_18_1_0 - 1.62539682539682*G0_1_1_18_1_1 - 2.74285714285713*G0_1_1_19_1_0 - 2.43809523809523*G0_1_1_19_1_1; + A[544] = 0.0; + A[508] = A[43]; + A[639] = 0.0; + A[535] = A[70]; + A[666] = 0.0; + A[697] = 0.0; + A[308] = -A[305] - 0.116825396825395*G0_0_1_0_0_0 - 0.116825396825395*G0_0_1_0_0_1 - 0.116825396825392*G0_0_1_1_0_0 - 0.0457142857142883*G0_0_1_3_0_0 - 0.25650793650793*G0_0_1_3_0_1 + 0.0939682539682496*G0_0_1_4_0_1 - 0.0457142857142838*G0_0_1_5_0_0 + 0.210793650793647*G0_0_1_5_0_1 - 0.0939682539682541*G0_0_1_6_0_1 + 0.116825396825398*G0_0_1_7_0_0 - 0.139682539682535*G0_0_1_7_0_1 + 0.11682539682539*G0_0_1_8_0_0 + 0.25650793650793*G0_0_1_8_0_1 + 0.0914285714285721*G0_0_1_9_0_0 + 0.045714285714284*G0_0_1_9_0_1 - 0.116825396825395*G0_0_1_10_1_0 - 0.116825396825395*G0_0_1_10_1_1 - 0.116825396825392*G0_0_1_11_1_0 - 0.0457142857142883*G0_0_1_13_1_0 - 0.25650793650793*G0_0_1_13_1_1 + 0.0939682539682496*G0_0_1_14_1_1 - 0.0457142857142838*G0_0_1_15_1_0 + 0.210793650793647*G0_0_1_15_1_1 - 0.0939682539682541*G0_0_1_16_1_1 + 0.116825396825398*G0_0_1_17_1_0 - 0.139682539682535*G0_0_1_17_1_1 + 0.11682539682539*G0_0_1_18_1_0 + 0.25650793650793*G0_0_1_18_1_1 + 0.0914285714285721*G0_0_1_19_1_0 + 0.045714285714284*G0_0_1_19_1_1 - 0.171005291005289*G0_1_1_0_0_0 - 0.171005291005288*G0_1_1_0_0_1 + 0.0541798941798979*G0_1_1_1_0_0 - 0.245502645502643*G0_1_1_2_0_1 + 0.00253968253968019*G0_1_1_3_0_0 - 0.411428571428564*G0_1_1_3_0_1 + 0.215873015873017*G0_1_1_4_0_0 + 0.929523809523802*G0_1_1_4_0_1 - 0.0482539682539697*G0_1_1_5_0_0 - 0.203174603174606*G0_1_1_5_0_1 - 0.215873015873017*G0_1_1_6_0_0 + 0.619682539682538*G0_1_1_6_0_1 + 1.3231746031746*G0_1_1_7_0_0 + 1.47809523809523*G0_1_1_7_0_1 - 1.2063492063492*G0_1_1_8_0_0 + 0.411428571428564*G0_1_1_8_0_1 + 0.0457142857142894*G0_1_1_9_0_0 - 2.40761904761903*G0_1_1_9_0_1 - 0.171005291005289*G0_1_1_10_1_0 - 0.171005291005288*G0_1_1_10_1_1 + 0.0541798941798979*G0_1_1_11_1_0 - 0.245502645502643*G0_1_1_12_1_1 + 0.00253968253968019*G0_1_1_13_1_0 - 0.411428571428564*G0_1_1_13_1_1 + 0.215873015873017*G0_1_1_14_1_0 + 0.929523809523802*G0_1_1_14_1_1 - 0.0482539682539697*G0_1_1_15_1_0 - 0.203174603174606*G0_1_1_15_1_1 - 0.215873015873017*G0_1_1_16_1_0 + 0.619682539682538*G0_1_1_16_1_1 + 1.3231746031746*G0_1_1_17_1_0 + 1.47809523809523*G0_1_1_17_1_1 - 1.2063492063492*G0_1_1_18_1_0 + 0.411428571428564*G0_1_1_18_1_1 + 0.0457142857142894*G0_1_1_19_1_0 - 2.40761904761903*G0_1_1_19_1_1; + A[306] = A[308] - 1.00571428571428*G0_0_0_0_0_0 - 1.00571428571428*G0_0_0_0_0_1 + 0.416507936507932*G0_0_0_1_0_0 - 0.0203174603174621*G0_0_0_2_0_1 - 1.06666666666666*G0_0_0_3_0_0 - 0.421587301587302*G0_0_0_3_0_1 + 0.030476190476186*G0_0_0_4_0_0 - 0.177777777777778*G0_0_0_4_0_1 - 1.31047619047618*G0_0_0_5_0_0 + 0.634920634920631*G0_0_0_5_0_1 - 0.0304761904761865*G0_0_0_6_0_0 + 0.391111111111111*G0_0_0_6_0_1 + 2.3974603174603*G0_0_0_7_0_0 + 0.452063492063489*G0_0_0_7_0_1 - 1.80825396825396*G0_0_0_8_0_0 + 0.421587301587302*G0_0_0_8_0_1 + 2.37714285714284*G0_0_0_9_0_0 - 0.274285714285712*G0_0_0_9_0_1 - 1.00571428571428*G0_0_0_10_1_0 - 1.00571428571428*G0_0_0_10_1_1 + 0.416507936507932*G0_0_0_11_1_0 - 0.0203174603174621*G0_0_0_12_1_1 - 1.06666666666666*G0_0_0_13_1_0 - 0.421587301587302*G0_0_0_13_1_1 + 0.030476190476186*G0_0_0_14_1_0 - 0.177777777777778*G0_0_0_14_1_1 - 1.31047619047618*G0_0_0_15_1_0 + 0.634920634920631*G0_0_0_15_1_1 - 0.0304761904761865*G0_0_0_16_1_0 + 0.391111111111111*G0_0_0_16_1_1 + 2.3974603174603*G0_0_0_17_1_0 + 0.452063492063489*G0_0_0_17_1_1 - 1.80825396825396*G0_0_0_18_1_0 + 0.421587301587302*G0_0_0_18_1_1 + 2.37714285714284*G0_0_0_19_1_0 - 0.274285714285712*G0_0_0_19_1_1 + 1.44761904761904*G0_0_1_0_0_0 + 1.44761904761904*G0_0_1_0_0_1 - 0.172698412698413*G0_0_1_1_0_0 - 0.147301587301589*G0_0_1_2_0_1 - 0.670476190476183*G0_0_1_3_0_0 - 0.172698412698413*G0_0_1_3_0_1 + 0.106666666666663*G0_0_1_4_0_0 - 0.416507936507932*G0_0_1_4_0_1 - 0.15238095238095*G0_0_1_5_0_0 - 2.46349206349206*G0_0_1_5_0_1 - 0.106666666666664*G0_0_1_6_0_0 + 1.1631746031746*G0_0_1_6_0_1 - 2.26031746031745*G0_0_1_7_0_0 + 0.0507936507936516*G0_0_1_7_0_1 + 0.985396825396822*G0_0_1_8_0_0 + 0.172698412698414*G0_0_1_8_0_1 + 0.822857142857133*G0_0_1_9_0_0 + 0.36571428571428*G0_0_1_9_0_1 + 1.44761904761904*G0_0_1_10_1_0 + 1.44761904761904*G0_0_1_10_1_1 - 0.172698412698413*G0_0_1_11_1_0 - 0.147301587301589*G0_0_1_12_1_1 - 0.670476190476183*G0_0_1_13_1_0 - 0.172698412698413*G0_0_1_13_1_1 + 0.106666666666663*G0_0_1_14_1_0 - 0.416507936507932*G0_0_1_14_1_1 - 0.15238095238095*G0_0_1_15_1_0 - 2.46349206349206*G0_0_1_15_1_1 - 0.106666666666664*G0_0_1_16_1_0 + 1.1631746031746*G0_0_1_16_1_1 - 2.26031746031745*G0_0_1_17_1_0 + 0.0507936507936516*G0_0_1_17_1_1 + 0.985396825396822*G0_0_1_18_1_0 + 0.172698412698414*G0_0_1_18_1_1 + 0.822857142857133*G0_0_1_19_1_0 + 0.36571428571428*G0_0_1_19_1_1 + 0.370793650793649*G0_1_0_0_0_0 + 0.370793650793649*G0_1_0_0_0_1 - 0.193015873015873*G0_1_0_1_0_0 + 0.0457142857142872*G0_1_0_2_0_1 - 0.452063492063491*G0_1_0_3_0_0 - 0.396190476190477*G0_1_0_3_0_1 + 0.0203174603174631*G0_1_0_4_0_0 - 0.274285714285711*G0_1_0_4_0_1 + 0.452063492063493*G0_1_0_5_0_0 - 0.299682539682536*G0_1_0_5_0_1 - 0.0203174603174632*G0_1_0_6_0_0 - 0.1168253968254*G0_1_0_6_0_1 - 0.599365079365077*G0_1_0_7_0_0 + 0.152380952380952*G0_1_0_7_0_1 + 0.421587301587302*G0_1_0_8_0_0 + 0.396190476190477*G0_1_0_8_0_1 + 0.12190476190476*G0_1_0_9_0_1 + 0.370793650793649*G0_1_0_10_1_0 + 0.370793650793649*G0_1_0_10_1_1 - 0.193015873015873*G0_1_0_11_1_0 + 0.0457142857142872*G0_1_0_12_1_1 - 0.452063492063491*G0_1_0_13_1_0 - 0.396190476190477*G0_1_0_13_1_1 + 0.0203174603174631*G0_1_0_14_1_0 - 0.274285714285711*G0_1_0_14_1_1 + 0.452063492063493*G0_1_0_15_1_0 - 0.299682539682536*G0_1_0_15_1_1 - 0.0203174603174632*G0_1_0_16_1_0 - 0.1168253968254*G0_1_0_16_1_1 - 0.599365079365077*G0_1_0_17_1_0 + 0.152380952380952*G0_1_0_17_1_1 + 0.421587301587302*G0_1_0_18_1_0 + 0.396190476190477*G0_1_0_18_1_1 + 0.12190476190476*G0_1_0_19_1_1 - 0.223492063492061*G0_1_1_0_0_0 - 0.223492063492061*G0_1_1_0_0_1 + 0.264126984126982*G0_1_1_2_0_1 - 0.446984126984122*G0_1_1_3_0_0 - 0.142222222222222*G0_1_1_4_0_0 - 0.853333333333327*G0_1_1_4_0_1 + 0.0812698412698451*G0_1_1_5_0_0 + 0.711111111111107*G0_1_1_5_0_1 + 0.142222222222222*G0_1_1_6_0_0 - 0.751746031746029*G0_1_1_6_0_1 - 0.223492063492065*G0_1_1_7_0_0 - 0.853333333333327*G0_1_1_7_0_1 + 0.446984126984128*G0_1_1_8_0_0 + 0.365714285714277*G0_1_1_9_0_0 + 1.70666666666665*G0_1_1_9_0_1 - 0.223492063492061*G0_1_1_10_1_0 - 0.223492063492061*G0_1_1_10_1_1 + 0.264126984126982*G0_1_1_12_1_1 - 0.446984126984122*G0_1_1_13_1_0 - 0.142222222222222*G0_1_1_14_1_0 - 0.853333333333327*G0_1_1_14_1_1 + 0.0812698412698451*G0_1_1_15_1_0 + 0.711111111111107*G0_1_1_15_1_1 + 0.142222222222222*G0_1_1_16_1_0 - 0.751746031746029*G0_1_1_16_1_1 - 0.223492063492065*G0_1_1_17_1_0 - 0.853333333333327*G0_1_1_17_1_1 + 0.446984126984128*G0_1_1_18_1_0 + 0.365714285714277*G0_1_1_19_1_0 + 1.70666666666665*G0_1_1_19_1_1; + A[264] = 0.0; + A[335] = -A[803] + 0.142222222222221*G0_0_1_0_0_0 + 0.142222222222221*G0_0_1_0_0_1 - 0.528253968253972*G0_0_1_1_0_0 - 0.121904761904762*G0_0_1_3_0_0 - 0.782222222222228*G0_0_1_3_0_1 + 0.132063492063496*G0_0_1_4_0_1 - 0.121904761904762*G0_0_1_5_0_0 - 0.010158730158728*G0_0_1_5_0_1 - 0.132063492063492*G0_0_1_6_0_1 - 0.812698412698411*G0_0_1_7_0_0 - 0.924444444444444*G0_0_1_7_0_1 + 1.19873015873016*G0_0_1_8_0_0 + 0.782222222222229*G0_0_1_8_0_1 + 0.243809523809524*G0_0_1_9_0_0 + 0.792380952380949*G0_0_1_9_0_1 + 0.142222222222221*G0_0_1_10_1_0 + 0.142222222222221*G0_0_1_10_1_1 - 0.528253968253972*G0_0_1_11_1_0 - 0.121904761904762*G0_0_1_13_1_0 - 0.782222222222228*G0_0_1_13_1_1 + 0.132063492063496*G0_0_1_14_1_1 - 0.121904761904762*G0_0_1_15_1_0 - 0.010158730158728*G0_0_1_15_1_1 - 0.132063492063492*G0_0_1_16_1_1 - 0.812698412698411*G0_0_1_17_1_0 - 0.924444444444444*G0_0_1_17_1_1 + 1.19873015873016*G0_0_1_18_1_0 + 0.782222222222229*G0_0_1_18_1_1 + 0.243809523809524*G0_0_1_19_1_0 + 0.792380952380949*G0_0_1_19_1_1 + 0.0135449735449753*G0_1_1_0_0_0 + 0.0135449735449749*G0_1_1_0_0_1 - 1.35449735449736*G0_1_1_1_0_0 - 0.440211640211639*G0_1_1_2_0_1 + 0.375873015873015*G0_1_1_3_0_0 - 2.33650793650794*G0_1_1_3_0_1 - 0.0507936507936489*G0_1_1_4_0_0 + 1.74730158730159*G0_1_1_4_0_1 + 0.172698412698414*G0_1_1_5_0_0 + 0.243809523809522*G0_1_1_5_0_1 + 0.0507936507936492*G0_1_1_6_0_0 + 0.182857142857143*G0_1_1_6_0_1 - 0.213333333333337*G0_1_1_7_0_0 - 0.284444444444445*G0_1_1_7_0_1 + 1.55428571428572*G0_1_1_8_0_0 + 2.33650793650794*G0_1_1_8_0_1 - 0.548571428571428*G0_1_1_9_0_0 - 1.46285714285714*G0_1_1_9_0_1 + 0.0135449735449753*G0_1_1_10_1_0 + 0.0135449735449749*G0_1_1_10_1_1 - 1.35449735449736*G0_1_1_11_1_0 - 0.440211640211639*G0_1_1_12_1_1 + 0.375873015873015*G0_1_1_13_1_0 - 2.33650793650794*G0_1_1_13_1_1 - 0.0507936507936489*G0_1_1_14_1_0 + 1.74730158730159*G0_1_1_14_1_1 + 0.172698412698414*G0_1_1_15_1_0 + 0.243809523809522*G0_1_1_15_1_1 + 0.0507936507936492*G0_1_1_16_1_0 + 0.182857142857143*G0_1_1_16_1_1 - 0.213333333333337*G0_1_1_17_1_0 - 0.284444444444445*G0_1_1_17_1_1 + 1.55428571428572*G0_1_1_18_1_0 + 2.33650793650794*G0_1_1_18_1_1 - 0.548571428571428*G0_1_1_19_1_0 - 1.46285714285714*G0_1_1_19_1_1; + A[291] = 0.0; + A[438] = 0.0; + A[318] = 0.0; + A[461] = 0.0; + A[357] = 0.0; + A[721] = 0.0; + A[388] = 0.0; + A[31] = -0.213888888888888*G0_0_0_0_0_0 - 0.213888888888888*G0_0_0_0_0_1 + 1.2329365079365*G0_0_0_1_0_0 + 0.213888888888888*G0_0_0_2_0_1 + 0.30674603174603*G0_0_0_3_0_0 + 2.19722222222221*G0_0_0_3_0_1 + 0.0115079365079359*G0_0_0_4_0_0 - 0.85992063492063*G0_0_0_4_0_1 - 0.0115079365079374*G0_0_0_5_0_0 - 0.0115079365079359*G0_0_0_6_0_0 + 0.871428571428567*G0_0_0_7_0_0 + 0.85992063492063*G0_0_0_7_0_1 - 1.89047619047618*G0_0_0_8_0_0 - 2.19722222222221*G0_0_0_8_0_1 - 0.295238095238092*G0_0_0_9_0_0 - 0.213888888888888*G0_0_0_10_1_0 - 0.213888888888888*G0_0_0_10_1_1 + 1.2329365079365*G0_0_0_11_1_0 + 0.213888888888888*G0_0_0_12_1_1 + 0.30674603174603*G0_0_0_13_1_0 + 2.19722222222221*G0_0_0_13_1_1 + 0.0115079365079359*G0_0_0_14_1_0 - 0.85992063492063*G0_0_0_14_1_1 - 0.0115079365079374*G0_0_0_15_1_0 - 0.0115079365079359*G0_0_0_16_1_0 + 0.871428571428567*G0_0_0_17_1_0 + 0.85992063492063*G0_0_0_17_1_1 - 1.89047619047618*G0_0_0_18_1_0 - 2.19722222222221*G0_0_0_18_1_1 - 0.295238095238092*G0_0_0_19_1_0; + A[130] = A[769] - 0.0304761904761934*G0_0_1_0_0_0 - 0.0304761904761933*G0_0_1_0_0_1 + 0.133333333333338*G0_0_1_1_0_0 + 0.0304761904761898*G0_0_1_2_0_1 - 0.276190476190473*G0_0_1_3_0_0 + 0.0380952380952461*G0_0_1_3_0_1 + 0.0780952380952355*G0_0_1_4_0_0 - 0.133333333333335*G0_0_1_4_0_1 - 0.215238095238094*G0_0_1_5_0_0 - 0.137142857142854*G0_0_1_5_0_1 - 0.0780952380952355*G0_0_1_6_0_0 + 0.137142857142857*G0_0_1_6_0_1 + 0.211428571428581*G0_0_1_7_0_0 + 0.13333333333334*G0_0_1_7_0_1 - 0.314285714285725*G0_0_1_8_0_0 - 0.0380952380952459*G0_0_1_8_0_1 + 0.491428571428566*G0_0_1_9_0_0 - 0.0304761904761934*G0_0_1_10_1_0 - 0.0304761904761933*G0_0_1_10_1_1 + 0.133333333333338*G0_0_1_11_1_0 + 0.0304761904761898*G0_0_1_12_1_1 - 0.276190476190473*G0_0_1_13_1_0 + 0.0380952380952461*G0_0_1_13_1_1 + 0.0780952380952355*G0_0_1_14_1_0 - 0.133333333333335*G0_0_1_14_1_1 - 0.215238095238094*G0_0_1_15_1_0 - 0.137142857142854*G0_0_1_15_1_1 - 0.0780952380952355*G0_0_1_16_1_0 + 0.137142857142857*G0_0_1_16_1_1 + 0.211428571428581*G0_0_1_17_1_0 + 0.13333333333334*G0_0_1_17_1_1 - 0.314285714285725*G0_0_1_18_1_0 - 0.0380952380952459*G0_0_1_18_1_1 + 0.491428571428566*G0_0_1_19_1_0 + 0.0304761904761933*G0_1_0_0_0_0 + 0.0304761904761931*G0_1_0_0_0_1 - 0.133333333333338*G0_1_0_1_0_0 - 0.0304761904761898*G0_1_0_2_0_1 + 0.276190476190473*G0_1_0_3_0_0 - 0.0380952380952455*G0_1_0_3_0_1 - 0.0780952380952354*G0_1_0_4_0_0 + 0.133333333333334*G0_1_0_4_0_1 + 0.215238095238094*G0_1_0_5_0_0 + 0.137142857142854*G0_1_0_5_0_1 + 0.0780952380952355*G0_1_0_6_0_0 - 0.137142857142857*G0_1_0_6_0_1 - 0.211428571428581*G0_1_0_7_0_0 - 0.13333333333334*G0_1_0_7_0_1 + 0.314285714285724*G0_1_0_8_0_0 + 0.0380952380952453*G0_1_0_8_0_1 - 0.491428571428567*G0_1_0_9_0_0 + 0.0304761904761933*G0_1_0_10_1_0 + 0.0304761904761931*G0_1_0_10_1_1 - 0.133333333333338*G0_1_0_11_1_0 - 0.0304761904761898*G0_1_0_12_1_1 + 0.276190476190473*G0_1_0_13_1_0 - 0.0380952380952455*G0_1_0_13_1_1 - 0.0780952380952354*G0_1_0_14_1_0 + 0.133333333333334*G0_1_0_14_1_1 + 0.215238095238094*G0_1_0_15_1_0 + 0.137142857142854*G0_1_0_15_1_1 + 0.0780952380952355*G0_1_0_16_1_0 - 0.137142857142857*G0_1_0_16_1_1 - 0.211428571428581*G0_1_0_17_1_0 - 0.13333333333334*G0_1_0_17_1_1 + 0.314285714285724*G0_1_0_18_1_0 + 0.0380952380952453*G0_1_0_18_1_1 - 0.491428571428567*G0_1_0_19_1_0; + A[161] = -A[716] + 0.142222222222221*G0_1_0_0_0_0 + 0.142222222222221*G0_1_0_0_0_1 - 0.528253968253972*G0_1_0_1_0_0 - 0.121904761904762*G0_1_0_3_0_0 - 0.782222222222228*G0_1_0_3_0_1 + 0.132063492063496*G0_1_0_4_0_1 - 0.121904761904762*G0_1_0_5_0_0 - 0.0101587301587281*G0_1_0_5_0_1 - 0.132063492063492*G0_1_0_6_0_1 - 0.812698412698411*G0_1_0_7_0_0 - 0.924444444444444*G0_1_0_7_0_1 + 1.19873015873016*G0_1_0_8_0_0 + 0.782222222222229*G0_1_0_8_0_1 + 0.243809523809524*G0_1_0_9_0_0 + 0.792380952380949*G0_1_0_9_0_1 + 0.142222222222221*G0_1_0_10_1_0 + 0.142222222222221*G0_1_0_10_1_1 - 0.528253968253972*G0_1_0_11_1_0 - 0.121904761904762*G0_1_0_13_1_0 - 0.782222222222228*G0_1_0_13_1_1 + 0.132063492063496*G0_1_0_14_1_1 - 0.121904761904762*G0_1_0_15_1_0 - 0.0101587301587281*G0_1_0_15_1_1 - 0.132063492063492*G0_1_0_16_1_1 - 0.812698412698411*G0_1_0_17_1_0 - 0.924444444444444*G0_1_0_17_1_1 + 1.19873015873016*G0_1_0_18_1_0 + 0.782222222222229*G0_1_0_18_1_1 + 0.243809523809524*G0_1_0_19_1_0 + 0.792380952380949*G0_1_0_19_1_1 + 0.0135449735449752*G0_1_1_0_0_0 + 0.0135449735449749*G0_1_1_0_0_1 - 1.35449735449736*G0_1_1_1_0_0 - 0.440211640211639*G0_1_1_2_0_1 + 0.375873015873015*G0_1_1_3_0_0 - 2.33650793650794*G0_1_1_3_0_1 - 0.050793650793649*G0_1_1_4_0_0 + 1.74730158730159*G0_1_1_4_0_1 + 0.172698412698414*G0_1_1_5_0_0 + 0.243809523809522*G0_1_1_5_0_1 + 0.0507936507936492*G0_1_1_6_0_0 + 0.182857142857143*G0_1_1_6_0_1 - 0.213333333333336*G0_1_1_7_0_0 - 0.284444444444445*G0_1_1_7_0_1 + 1.55428571428572*G0_1_1_8_0_0 + 2.33650793650794*G0_1_1_8_0_1 - 0.548571428571428*G0_1_1_9_0_0 - 1.46285714285714*G0_1_1_9_0_1 + 0.0135449735449752*G0_1_1_10_1_0 + 0.0135449735449749*G0_1_1_10_1_1 - 1.35449735449736*G0_1_1_11_1_0 - 0.440211640211639*G0_1_1_12_1_1 + 0.375873015873015*G0_1_1_13_1_0 - 2.33650793650794*G0_1_1_13_1_1 - 0.050793650793649*G0_1_1_14_1_0 + 1.74730158730159*G0_1_1_14_1_1 + 0.172698412698414*G0_1_1_15_1_0 + 0.243809523809522*G0_1_1_15_1_1 + 0.0507936507936492*G0_1_1_16_1_0 + 0.182857142857143*G0_1_1_16_1_1 - 0.213333333333336*G0_1_1_17_1_0 - 0.284444444444445*G0_1_1_17_1_1 + 1.55428571428572*G0_1_1_18_1_0 + 2.33650793650794*G0_1_1_18_1_1 - 0.548571428571428*G0_1_1_19_1_0 - 1.46285714285714*G0_1_1_19_1_1; + A[113] = 0.0; + A[180] = A[645]; + A[136] = 0.0; + A[171] = 0.0; + A[499] = A[34]; + A[206] = 0.0; + A[648] = -A[656] + 0.826243386243381*G0_0_0_0_0_0 + 0.826243386243381*G0_0_0_0_0_1 - 0.440211640211637*G0_0_0_1_0_0 + 0.128677248677249*G0_0_0_2_0_1 + 0.264126984126979*G0_0_0_3_0_0 - 0.0507936507936511*G0_0_0_3_0_1 - 0.040634920634919*G0_0_0_4_0_0 - 0.294603174603175*G0_0_0_4_0_1 + 1.19873015873015*G0_0_0_5_0_0 - 0.355555555555556*G0_0_0_5_0_1 + 0.0406349206349191*G0_0_0_6_0_0 - 0.599365079365075*G0_0_0_6_0_1 - 2.05206349206348*G0_0_0_7_0_0 - 0.497777777777778*G0_0_0_7_0_1 + 1.66603174603174*G0_0_0_8_0_0 + 0.0507936507936508*G0_0_0_8_0_1 - 1.46285714285713*G0_0_0_9_0_0 + 0.792380952380954*G0_0_0_9_0_1 + 0.826243386243381*G0_0_0_10_1_0 + 0.826243386243381*G0_0_0_10_1_1 - 0.440211640211637*G0_0_0_11_1_0 + 0.128677248677249*G0_0_0_12_1_1 + 0.264126984126979*G0_0_0_13_1_0 - 0.0507936507936511*G0_0_0_13_1_1 - 0.040634920634919*G0_0_0_14_1_0 - 0.294603174603175*G0_0_0_14_1_1 + 1.19873015873015*G0_0_0_15_1_0 - 0.355555555555556*G0_0_0_15_1_1 + 0.0406349206349191*G0_0_0_16_1_0 - 0.599365079365075*G0_0_0_16_1_1 - 2.05206349206348*G0_0_0_17_1_0 - 0.497777777777778*G0_0_0_17_1_1 + 1.66603174603174*G0_0_0_18_1_0 + 0.0507936507936508*G0_0_0_18_1_1 - 1.46285714285713*G0_0_0_19_1_0 + 0.792380952380954*G0_0_0_19_1_1 - 0.528253968253971*G0_1_0_0_0_0 - 0.528253968253971*G0_1_0_0_0_1 + 0.142222222222221*G0_1_0_2_0_1 + 0.13206349206349*G0_1_0_3_0_0 - 0.111746031746033*G0_1_0_4_0_0 - 0.121904761904763*G0_1_0_4_0_1 + 0.41650793650793*G0_1_0_5_0_0 + 1.19873015873016*G0_1_0_5_0_1 + 0.111746031746033*G0_1_0_6_0_0 - 0.81269841269841*G0_1_0_6_0_1 + 0.660317460317464*G0_1_0_7_0_0 - 0.121904761904764*G0_1_0_7_0_1 - 0.132063492063494*G0_1_0_8_0_0 - 0.54857142857142*G0_1_0_9_0_0 + 0.243809523809528*G0_1_0_9_0_1 - 0.528253968253971*G0_1_0_10_1_0 - 0.528253968253971*G0_1_0_10_1_1 + 0.142222222222221*G0_1_0_12_1_1 + 0.13206349206349*G0_1_0_13_1_0 - 0.111746031746033*G0_1_0_14_1_0 - 0.121904761904763*G0_1_0_14_1_1 + 0.41650793650793*G0_1_0_15_1_0 + 1.19873015873016*G0_1_0_15_1_1 + 0.111746031746033*G0_1_0_16_1_0 - 0.81269841269841*G0_1_0_16_1_1 + 0.660317460317464*G0_1_0_17_1_0 - 0.121904761904764*G0_1_0_17_1_1 - 0.132063492063494*G0_1_0_18_1_0 - 0.54857142857142*G0_1_0_19_1_0 + 0.243809523809528*G0_1_0_19_1_1; + A[96] = A[648] - 0.0203174603174619*G0_0_1_0_0_0 - 0.0203174603174618*G0_0_1_0_0_1 + 0.02031746031746*G0_0_1_1_0_0 + 0.0203174603174585*G0_0_1_2_0_1 - 0.0203174603174596*G0_0_1_3_0_0 + 0.0711111111111095*G0_0_1_3_0_1 - 0.0812698412698433*G0_0_1_4_0_0 - 0.172698412698411*G0_0_1_4_0_1 + 0.0203174603174572*G0_0_1_5_0_0 + 0.0914285714285715*G0_0_1_5_0_1 + 0.0812698412698434*G0_0_1_6_0_0 - 0.0914285714285684*G0_0_1_6_0_1 - 0.060952380952377*G0_0_1_7_0_0 - 0.132063492063491*G0_0_1_7_0_1 + 0.060952380952379*G0_0_1_8_0_0 - 0.0711111111111097*G0_0_1_8_0_1 + 0.304761904761903*G0_0_1_9_0_1 - 0.0203174603174619*G0_0_1_10_1_0 - 0.0203174603174618*G0_0_1_10_1_1 + 0.02031746031746*G0_0_1_11_1_0 + 0.0203174603174585*G0_0_1_12_1_1 - 0.0203174603174596*G0_0_1_13_1_0 + 0.0711111111111095*G0_0_1_13_1_1 - 0.0812698412698433*G0_0_1_14_1_0 - 0.172698412698411*G0_0_1_14_1_1 + 0.0203174603174572*G0_0_1_15_1_0 + 0.0914285714285715*G0_0_1_15_1_1 + 0.0812698412698434*G0_0_1_16_1_0 - 0.0914285714285684*G0_0_1_16_1_1 - 0.060952380952377*G0_0_1_17_1_0 - 0.132063492063491*G0_0_1_17_1_1 + 0.060952380952379*G0_0_1_18_1_0 - 0.0711111111111097*G0_0_1_18_1_1 + 0.304761904761903*G0_0_1_19_1_1 + 0.0203174603174619*G0_1_0_0_0_0 + 0.0203174603174619*G0_1_0_0_0_1 - 0.02031746031746*G0_1_0_1_0_0 - 0.0203174603174585*G0_1_0_2_0_1 + 0.0203174603174595*G0_1_0_3_0_0 - 0.0711111111111095*G0_1_0_3_0_1 + 0.0812698412698434*G0_1_0_4_0_0 + 0.172698412698411*G0_1_0_4_0_1 - 0.0203174603174571*G0_1_0_5_0_0 - 0.0914285714285716*G0_1_0_5_0_1 - 0.0812698412698434*G0_1_0_6_0_0 + 0.0914285714285683*G0_1_0_6_0_1 + 0.060952380952377*G0_1_0_7_0_0 + 0.132063492063491*G0_1_0_7_0_1 - 0.0609523809523789*G0_1_0_8_0_0 + 0.0711111111111097*G0_1_0_8_0_1 - 0.304761904761903*G0_1_0_9_0_1 + 0.0203174603174619*G0_1_0_10_1_0 + 0.0203174603174619*G0_1_0_10_1_1 - 0.02031746031746*G0_1_0_11_1_0 - 0.0203174603174585*G0_1_0_12_1_1 + 0.0203174603174595*G0_1_0_13_1_0 - 0.0711111111111095*G0_1_0_13_1_1 + 0.0812698412698434*G0_1_0_14_1_0 + 0.172698412698411*G0_1_0_14_1_1 - 0.0203174603174571*G0_1_0_15_1_0 - 0.0914285714285716*G0_1_0_15_1_1 - 0.0812698412698434*G0_1_0_16_1_0 + 0.0914285714285683*G0_1_0_16_1_1 + 0.060952380952377*G0_1_0_17_1_0 + 0.132063492063491*G0_1_0_17_1_1 - 0.0609523809523789*G0_1_0_18_1_0 + 0.0711111111111097*G0_1_0_18_1_1 - 0.304761904761903*G0_1_0_19_1_1; + A[801] = -A[96] + 0.826243386243382*G0_0_0_0_0_0 + 0.826243386243381*G0_0_0_0_0_1 - 0.440211640211637*G0_0_0_1_0_0 + 0.128677248677249*G0_0_0_2_0_1 + 0.264126984126979*G0_0_0_3_0_0 - 0.0507936507936511*G0_0_0_3_0_1 - 0.0406349206349189*G0_0_0_4_0_0 - 0.294603174603175*G0_0_0_4_0_1 + 1.19873015873015*G0_0_0_5_0_0 - 0.355555555555556*G0_0_0_5_0_1 + 0.0406349206349191*G0_0_0_6_0_0 - 0.599365079365075*G0_0_0_6_0_1 - 2.05206349206348*G0_0_0_7_0_0 - 0.497777777777778*G0_0_0_7_0_1 + 1.66603174603174*G0_0_0_8_0_0 + 0.0507936507936508*G0_0_0_8_0_1 - 1.46285714285713*G0_0_0_9_0_0 + 0.792380952380954*G0_0_0_9_0_1 + 0.826243386243382*G0_0_0_10_1_0 + 0.826243386243381*G0_0_0_10_1_1 - 0.440211640211637*G0_0_0_11_1_0 + 0.128677248677249*G0_0_0_12_1_1 + 0.264126984126979*G0_0_0_13_1_0 - 0.0507936507936511*G0_0_0_13_1_1 - 0.0406349206349189*G0_0_0_14_1_0 - 0.294603174603175*G0_0_0_14_1_1 + 1.19873015873015*G0_0_0_15_1_0 - 0.355555555555556*G0_0_0_15_1_1 + 0.0406349206349191*G0_0_0_16_1_0 - 0.599365079365075*G0_0_0_16_1_1 - 2.05206349206348*G0_0_0_17_1_0 - 0.497777777777778*G0_0_0_17_1_1 + 1.66603174603174*G0_0_0_18_1_0 + 0.0507936507936508*G0_0_0_18_1_1 - 1.46285714285713*G0_0_0_19_1_0 + 0.792380952380954*G0_0_0_19_1_1 - 0.528253968253971*G0_0_1_0_0_0 - 0.528253968253971*G0_0_1_0_0_1 + 0.142222222222221*G0_0_1_2_0_1 + 0.13206349206349*G0_0_1_3_0_0 - 0.111746031746033*G0_0_1_4_0_0 - 0.121904761904763*G0_0_1_4_0_1 + 0.41650793650793*G0_0_1_5_0_0 + 1.19873015873016*G0_0_1_5_0_1 + 0.111746031746033*G0_0_1_6_0_0 - 0.81269841269841*G0_0_1_6_0_1 + 0.660317460317464*G0_0_1_7_0_0 - 0.121904761904764*G0_0_1_7_0_1 - 0.132063492063494*G0_0_1_8_0_0 - 0.54857142857142*G0_0_1_9_0_0 + 0.243809523809528*G0_0_1_9_0_1 - 0.528253968253971*G0_0_1_10_1_0 - 0.528253968253971*G0_0_1_10_1_1 + 0.142222222222221*G0_0_1_12_1_1 + 0.13206349206349*G0_0_1_13_1_0 - 0.111746031746033*G0_0_1_14_1_0 - 0.121904761904763*G0_0_1_14_1_1 + 0.41650793650793*G0_0_1_15_1_0 + 1.19873015873016*G0_0_1_15_1_1 + 0.111746031746033*G0_0_1_16_1_0 - 0.81269841269841*G0_0_1_16_1_1 + 0.660317460317464*G0_0_1_17_1_0 - 0.121904761904764*G0_0_1_17_1_1 - 0.132063492063494*G0_0_1_18_1_0 - 0.54857142857142*G0_0_1_19_1_0 + 0.243809523809528*G0_0_1_19_1_1; + A[336] = A[801]; + A[685] = A[307] + 0.133333333333336*G0_0_1_0_0_0 + 0.133333333333335*G0_0_1_0_0_1 - 0.0304761904761916*G0_0_1_1_0_0 - 0.0304761904761894*G0_0_1_2_0_1 - 0.215238095238092*G0_0_1_3_0_0 - 0.0780952380952386*G0_0_1_3_0_1 - 0.0780952380952362*G0_0_1_4_0_0 - 0.215238095238093*G0_0_1_4_0_1 - 0.276190476190467*G0_0_1_5_0_0 - 0.314285714285712*G0_0_1_5_0_1 + 0.0780952380952361*G0_0_1_6_0_0 + 0.211428571428567*G0_0_1_6_0_1 - 0.314285714285718*G0_0_1_7_0_0 - 0.276190476190472*G0_0_1_7_0_1 + 0.211428571428573*G0_0_1_8_0_0 + 0.0780952380952389*G0_0_1_8_0_1 + 0.491428571428559*G0_0_1_9_0_0 + 0.491428571428564*G0_0_1_9_0_1 + 0.133333333333336*G0_0_1_10_1_0 + 0.133333333333335*G0_0_1_10_1_1 - 0.0304761904761916*G0_0_1_11_1_0 - 0.0304761904761894*G0_0_1_12_1_1 - 0.215238095238092*G0_0_1_13_1_0 - 0.0780952380952386*G0_0_1_13_1_1 - 0.0780952380952362*G0_0_1_14_1_0 - 0.215238095238093*G0_0_1_14_1_1 - 0.276190476190467*G0_0_1_15_1_0 - 0.314285714285712*G0_0_1_15_1_1 + 0.0780952380952361*G0_0_1_16_1_0 + 0.211428571428567*G0_0_1_16_1_1 - 0.314285714285718*G0_0_1_17_1_0 - 0.276190476190472*G0_0_1_17_1_1 + 0.211428571428573*G0_0_1_18_1_0 + 0.0780952380952389*G0_0_1_18_1_1 + 0.491428571428559*G0_0_1_19_1_0 + 0.491428571428564*G0_0_1_19_1_1 - 0.133333333333336*G0_1_0_0_0_0 - 0.133333333333336*G0_1_0_0_0_1 + 0.0304761904761916*G0_1_0_1_0_0 + 0.0304761904761894*G0_1_0_2_0_1 + 0.215238095238092*G0_1_0_3_0_0 + 0.0780952380952386*G0_1_0_3_0_1 + 0.0780952380952362*G0_1_0_4_0_0 + 0.215238095238093*G0_1_0_4_0_1 + 0.276190476190466*G0_1_0_5_0_0 + 0.314285714285712*G0_1_0_5_0_1 - 0.078095238095236*G0_1_0_6_0_0 - 0.211428571428567*G0_1_0_6_0_1 + 0.314285714285718*G0_1_0_7_0_0 + 0.276190476190472*G0_1_0_7_0_1 - 0.211428571428573*G0_1_0_8_0_0 - 0.0780952380952388*G0_1_0_8_0_1 - 0.491428571428559*G0_1_0_9_0_0 - 0.491428571428564*G0_1_0_9_0_1 - 0.133333333333336*G0_1_0_10_1_0 - 0.133333333333336*G0_1_0_10_1_1 + 0.0304761904761916*G0_1_0_11_1_0 + 0.0304761904761894*G0_1_0_12_1_1 + 0.215238095238092*G0_1_0_13_1_0 + 0.0780952380952386*G0_1_0_13_1_1 + 0.0780952380952362*G0_1_0_14_1_0 + 0.215238095238093*G0_1_0_14_1_1 + 0.276190476190466*G0_1_0_15_1_0 + 0.314285714285712*G0_1_0_15_1_1 - 0.078095238095236*G0_1_0_16_1_0 - 0.211428571428567*G0_1_0_16_1_1 + 0.314285714285718*G0_1_0_17_1_0 + 0.276190476190472*G0_1_0_17_1_1 - 0.211428571428573*G0_1_0_18_1_0 - 0.0780952380952388*G0_1_0_18_1_1 - 0.491428571428559*G0_1_0_19_1_0 - 0.491428571428564*G0_1_0_19_1_1; + A[718] = -A[628] - 0.345396825396824*G0_1_0_0_0_0 - 0.345396825396824*G0_1_0_0_0_1 + 0.14222222222222*G0_1_0_1_0_0 + 1.21904761904762*G0_1_0_3_0_0 + 0.650158730158728*G0_1_0_3_0_1 + 0.711111111111115*G0_1_0_4_0_1 + 1.21904761904762*G0_1_0_5_0_0 + 1.05650793650794*G0_1_0_5_0_1 - 0.711111111111113*G0_1_0_6_0_1 + 0.833015873015871*G0_1_0_7_0_0 + 0.995555555555556*G0_1_0_7_0_1 - 0.629841269841266*G0_1_0_8_0_0 - 0.650158730158729*G0_1_0_8_0_1 - 2.43809523809524*G0_1_0_9_0_0 - 1.70666666666667*G0_1_0_9_0_1 - 0.345396825396824*G0_1_0_10_1_0 - 0.345396825396824*G0_1_0_10_1_1 + 0.14222222222222*G0_1_0_11_1_0 + 1.21904761904762*G0_1_0_13_1_0 + 0.650158730158728*G0_1_0_13_1_1 + 0.711111111111115*G0_1_0_14_1_1 + 1.21904761904762*G0_1_0_15_1_0 + 1.05650793650794*G0_1_0_15_1_1 - 0.711111111111113*G0_1_0_16_1_1 + 0.833015873015871*G0_1_0_17_1_0 + 0.995555555555556*G0_1_0_17_1_1 - 0.629841269841266*G0_1_0_18_1_0 - 0.650158730158729*G0_1_0_18_1_1 - 2.43809523809524*G0_1_0_19_1_0 - 1.70666666666667*G0_1_0_19_1_1 + 0.352169312169308*G0_1_1_0_0_0 + 0.352169312169307*G0_1_1_0_0_1 + 1.61862433862433*G0_1_1_1_0_0 + 0.54179894179894*G0_1_1_2_0_1 + 0.162539682539685*G0_1_1_3_0_0 + 3.71809523809523*G0_1_1_3_0_1 - 0.507936507936506*G0_1_1_4_0_0 - 2.98666666666665*G0_1_1_4_0_1 - 0.650158730158724*G0_1_1_5_0_0 - 0.629841269841261*G0_1_1_5_0_1 + 0.507936507936506*G0_1_1_6_0_0 - 0.264126984126987*G0_1_1_6_0_1 - 1.62539682539681*G0_1_1_7_0_0 - 1.64571428571427*G0_1_1_7_0_1 - 0.345396825396828*G0_1_1_8_0_0 - 3.71809523809523*G0_1_1_8_0_1 + 0.48761904761904*G0_1_1_9_0_0 + 4.63238095238093*G0_1_1_9_0_1 + 0.352169312169308*G0_1_1_10_1_0 + 0.352169312169307*G0_1_1_10_1_1 + 1.61862433862433*G0_1_1_11_1_0 + 0.54179894179894*G0_1_1_12_1_1 + 0.162539682539685*G0_1_1_13_1_0 + 3.71809523809523*G0_1_1_13_1_1 - 0.507936507936506*G0_1_1_14_1_0 - 2.98666666666665*G0_1_1_14_1_1 - 0.650158730158724*G0_1_1_15_1_0 - 0.629841269841261*G0_1_1_15_1_1 + 0.507936507936506*G0_1_1_16_1_0 - 0.264126984126987*G0_1_1_16_1_1 - 1.62539682539681*G0_1_1_17_1_0 - 1.64571428571427*G0_1_1_17_1_1 - 0.345396825396828*G0_1_1_18_1_0 - 3.71809523809523*G0_1_1_18_1_1 + 0.48761904761904*G0_1_1_19_1_0 + 4.63238095238093*G0_1_1_19_1_1; + A[428] = -A[718] - 0.568888888888889*G0_0_0_0_0_0 - 0.568888888888889*G0_0_0_0_0_1 - 0.446984126984123*G0_0_0_1_0_0 + 1.82857142857141*G0_0_0_3_0_0 - 0.0406349206349229*G0_0_0_3_0_1 + 1.42222222222222*G0_0_0_4_0_1 + 1.82857142857143*G0_0_0_5_0_0 + 1.99111111111111*G0_0_0_5_0_1 - 1.42222222222224*G0_0_0_6_0_1 + 0.690793650793648*G0_0_0_7_0_0 + 0.528253968253965*G0_0_0_7_0_1 + 0.325079365079365*G0_0_0_8_0_0 + 0.0406349206349227*G0_0_0_8_0_1 - 3.65714285714284*G0_0_0_9_0_0 - 1.95047619047619*G0_0_0_9_0_1 - 0.568888888888889*G0_0_0_10_1_0 - 0.568888888888889*G0_0_0_10_1_1 - 0.446984126984123*G0_0_0_11_1_0 + 1.82857142857141*G0_0_0_13_1_0 - 0.0406349206349229*G0_0_0_13_1_1 + 1.42222222222222*G0_0_0_14_1_1 + 1.82857142857143*G0_0_0_15_1_0 + 1.99111111111111*G0_0_0_15_1_1 - 1.42222222222224*G0_0_0_16_1_1 + 0.690793650793648*G0_0_0_17_1_0 + 0.528253968253965*G0_0_0_17_1_1 + 0.325079365079365*G0_0_0_18_1_0 + 0.0406349206349227*G0_0_0_18_1_1 - 3.65714285714284*G0_0_0_19_1_0 - 1.95047619047619*G0_0_0_19_1_1 + 0.0677248677248679*G0_0_1_0_0_0 + 0.067724867724868*G0_0_1_0_0_1 + 0.297989417989422*G0_0_1_1_0_0 + 0.846560846560863*G0_0_1_2_0_1 - 1.17841269841271*G0_0_1_3_0_0 - 0.446984126984121*G0_0_1_3_0_1 + 2.84444444444447*G0_0_1_4_0_0 + 1.56444444444444*G0_0_1_4_0_1 - 1.38158730158729*G0_0_1_5_0_0 - 1.27999999999999*G0_0_1_5_0_1 - 2.84444444444447*G0_0_1_6_0_0 + 0.365714285714261*G0_0_1_6_0_1 + 0.36571428571428*G0_0_1_7_0_0 + 0.264126984126985*G0_0_1_7_0_1 - 0.731428571428572*G0_0_1_8_0_0 + 0.446984126984121*G0_0_1_8_0_1 + 2.56*G0_0_1_9_0_0 - 1.82857142857143*G0_0_1_9_0_1 + 0.0677248677248679*G0_0_1_10_1_0 + 0.067724867724868*G0_0_1_10_1_1 + 0.297989417989422*G0_0_1_11_1_0 + 0.846560846560863*G0_0_1_12_1_1 - 1.17841269841271*G0_0_1_13_1_0 - 0.446984126984121*G0_0_1_13_1_1 + 2.84444444444447*G0_0_1_14_1_0 + 1.56444444444444*G0_0_1_14_1_1 - 1.38158730158729*G0_0_1_15_1_0 - 1.27999999999999*G0_0_1_15_1_1 - 2.84444444444447*G0_0_1_16_1_0 + 0.365714285714261*G0_0_1_16_1_1 + 0.36571428571428*G0_0_1_17_1_0 + 0.264126984126985*G0_0_1_17_1_1 - 0.731428571428572*G0_0_1_18_1_0 + 0.446984126984121*G0_0_1_18_1_1 + 2.56*G0_0_1_19_1_0 - 1.82857142857143*G0_0_1_19_1_1 - 0.907513227513225*G0_1_0_0_0_0 - 0.907513227513225*G0_1_0_0_0_1 - 0.0677248677248676*G0_1_0_1_0_0 + 2.67513227513227*G0_1_0_2_0_1 + 0.162539682539686*G0_1_0_3_0_0 - 0.203174603174602*G0_1_0_3_0_1 + 5.28253968253966*G0_1_0_4_0_0 + 2.90539682539682*G0_1_0_4_0_1 + 3.61650793650793*G0_1_0_5_0_0 + 3.4742857142857*G0_1_0_5_0_1 - 5.28253968253967*G0_1_0_6_0_0 - 5.24190476190474*G0_1_0_6_0_1 + 0.731428571428571*G0_1_0_7_0_0 + 0.873650793650795*G0_1_0_7_0_1 + 0.24380952380952*G0_1_0_8_0_0 + 0.203174603174602*G0_1_0_8_0_1 - 3.77904761904761*G0_1_0_9_0_0 - 3.77904761904762*G0_1_0_9_0_1 - 0.907513227513225*G0_1_0_10_1_0 - 0.907513227513225*G0_1_0_10_1_1 - 0.0677248677248676*G0_1_0_11_1_0 + 2.67513227513227*G0_1_0_12_1_1 + 0.162539682539686*G0_1_0_13_1_0 - 0.203174603174602*G0_1_0_13_1_1 + 5.28253968253966*G0_1_0_14_1_0 + 2.90539682539682*G0_1_0_14_1_1 + 3.61650793650793*G0_1_0_15_1_0 + 3.4742857142857*G0_1_0_15_1_1 - 5.28253968253967*G0_1_0_16_1_0 - 5.24190476190474*G0_1_0_16_1_1 + 0.731428571428571*G0_1_0_17_1_0 + 0.873650793650795*G0_1_0_17_1_1 + 0.24380952380952*G0_1_0_18_1_0 + 0.203174603174602*G0_1_0_18_1_1 - 3.77904761904761*G0_1_0_19_1_0 - 3.77904761904762*G0_1_0_19_1_1 + 0.135449735449733*G0_1_1_0_0_0 + 0.135449735449733*G0_1_1_0_0_1 + 0.270899470899472*G0_1_1_1_0_0 + 1.65248677248677*G0_1_1_2_0_1 - 0.772063492063487*G0_1_1_3_0_0 + 3.61650793650793*G0_1_1_4_0_0 + 1.46285714285714*G0_1_1_4_0_1 + 1.99111111111111*G0_1_1_5_0_0 + 0.568888888888892*G0_1_1_5_0_1 - 3.61650793650793*G0_1_1_6_0_0 - 2.3568253968254*G0_1_1_6_0_1 + 0.0406349206349227*G0_1_1_7_0_0 + 1.46285714285714*G0_1_1_7_0_1 - 0.446984126984129*G0_1_1_8_0_0 - 1.21904761904762*G0_1_1_9_0_0 - 2.92571428571428*G0_1_1_9_0_1 + 0.135449735449733*G0_1_1_10_1_0 + 0.135449735449733*G0_1_1_10_1_1 + 0.270899470899472*G0_1_1_11_1_0 + 1.65248677248677*G0_1_1_12_1_1 - 0.772063492063487*G0_1_1_13_1_0 + 3.61650793650793*G0_1_1_14_1_0 + 1.46285714285714*G0_1_1_14_1_1 + 1.99111111111111*G0_1_1_15_1_0 + 0.568888888888892*G0_1_1_15_1_1 - 3.61650793650793*G0_1_1_16_1_0 - 2.3568253968254*G0_1_1_16_1_1 + 0.0406349206349227*G0_1_1_17_1_0 + 1.46285714285714*G0_1_1_17_1_1 - 0.446984126984129*G0_1_1_18_1_0 - 1.21904761904762*G0_1_1_19_1_0 - 2.92571428571428*G0_1_1_19_1_1; + A[863] = A[718] - 0.243809523809523*G0_0_1_0_0_0 - 0.243809523809523*G0_0_1_0_0_1 + 0.0203174603174572*G0_0_1_1_0_0 + 0.406349206349198*G0_0_1_2_0_1 + 0.325079365079372*G0_0_1_3_0_0 + 0.22349206349206*G0_0_1_3_0_1 + 0.507936507936494*G0_0_1_4_0_0 + 0.223492063492066*G0_0_1_4_0_1 + 1.13777777777778*G0_0_1_5_0_0 + 1.07682539682539*G0_0_1_5_0_1 - 0.507936507936495*G0_0_1_6_0_0 - 1.23936507936507*G0_0_1_6_0_1 + 0.203174603174605*G0_0_1_7_0_0 + 0.264126984126988*G0_0_1_7_0_1 + 0.0203174603174606*G0_0_1_8_0_0 - 0.22349206349206*G0_0_1_8_0_1 - 1.46285714285715*G0_0_1_9_0_0 - 0.487619047619053*G0_0_1_9_0_1 - 0.243809523809523*G0_0_1_10_1_0 - 0.243809523809523*G0_0_1_10_1_1 + 0.0203174603174572*G0_0_1_11_1_0 + 0.406349206349198*G0_0_1_12_1_1 + 0.325079365079372*G0_0_1_13_1_0 + 0.22349206349206*G0_0_1_13_1_1 + 0.507936507936494*G0_0_1_14_1_0 + 0.223492063492066*G0_0_1_14_1_1 + 1.13777777777778*G0_0_1_15_1_0 + 1.07682539682539*G0_0_1_15_1_1 - 0.507936507936495*G0_0_1_16_1_0 - 1.23936507936507*G0_0_1_16_1_1 + 0.203174603174605*G0_0_1_17_1_0 + 0.264126984126988*G0_0_1_17_1_1 + 0.0203174603174606*G0_0_1_18_1_0 - 0.22349206349206*G0_0_1_18_1_1 - 1.46285714285715*G0_0_1_19_1_0 - 0.487619047619053*G0_0_1_19_1_1 + 0.243809523809523*G0_1_0_0_0_0 + 0.243809523809523*G0_1_0_0_0_1 - 0.0203174603174572*G0_1_0_1_0_0 - 0.406349206349198*G0_1_0_2_0_1 - 0.325079365079371*G0_1_0_3_0_0 - 0.22349206349206*G0_1_0_3_0_1 - 0.507936507936494*G0_1_0_4_0_0 - 0.223492063492066*G0_1_0_4_0_1 - 1.13777777777778*G0_1_0_5_0_0 - 1.07682539682539*G0_1_0_5_0_1 + 0.507936507936495*G0_1_0_6_0_0 + 1.23936507936507*G0_1_0_6_0_1 - 0.203174603174605*G0_1_0_7_0_0 - 0.264126984126988*G0_1_0_7_0_1 - 0.0203174603174604*G0_1_0_8_0_0 + 0.22349206349206*G0_1_0_8_0_1 + 1.46285714285715*G0_1_0_9_0_0 + 0.487619047619054*G0_1_0_9_0_1 + 0.243809523809523*G0_1_0_10_1_0 + 0.243809523809523*G0_1_0_10_1_1 - 0.0203174603174572*G0_1_0_11_1_0 - 0.406349206349198*G0_1_0_12_1_1 - 0.325079365079371*G0_1_0_13_1_0 - 0.22349206349206*G0_1_0_13_1_1 - 0.507936507936494*G0_1_0_14_1_0 - 0.223492063492066*G0_1_0_14_1_1 - 1.13777777777778*G0_1_0_15_1_0 - 1.07682539682539*G0_1_0_15_1_1 + 0.507936507936495*G0_1_0_16_1_0 + 1.23936507936507*G0_1_0_16_1_1 - 0.203174603174605*G0_1_0_17_1_0 - 0.264126984126988*G0_1_0_17_1_1 - 0.0203174603174604*G0_1_0_18_1_0 + 0.22349206349206*G0_1_0_18_1_1 + 1.46285714285715*G0_1_0_19_1_0 + 0.487619047619054*G0_1_0_19_1_1; + A[254] = A[428] - 0.73142857142857*G0_0_1_0_0_0 - 0.73142857142857*G0_0_1_0_0_1 - 0.386031746031747*G0_0_1_1_0_0 + 1.4222222222222*G0_0_1_2_0_1 + 1.01587301587302*G0_0_1_3_0_0 + 0.0203174603174593*G0_0_1_3_0_1 + 1.9301587301587*G0_0_1_4_0_0 + 1.11746031746031*G0_0_1_4_0_1 + 3.86031746031744*G0_0_1_5_0_0 + 3.6774603174603*G0_0_1_5_0_1 - 1.9301587301587*G0_0_1_6_0_0 - 4.36825396825394*G0_0_1_6_0_1 + 0.162539682539685*G0_0_1_7_0_0 + 0.345396825396822*G0_0_1_7_0_1 + 0.954920634920631*G0_0_1_8_0_0 - 0.0203174603174596*G0_0_1_8_0_1 - 4.87619047619046*G0_0_1_9_0_0 - 1.46285714285713*G0_0_1_9_0_1 - 0.73142857142857*G0_0_1_10_1_0 - 0.73142857142857*G0_0_1_10_1_1 - 0.386031746031747*G0_0_1_11_1_0 + 1.4222222222222*G0_0_1_12_1_1 + 1.01587301587302*G0_0_1_13_1_0 + 0.0203174603174593*G0_0_1_13_1_1 + 1.9301587301587*G0_0_1_14_1_0 + 1.11746031746031*G0_0_1_14_1_1 + 3.86031746031744*G0_0_1_15_1_0 + 3.6774603174603*G0_0_1_15_1_1 - 1.9301587301587*G0_0_1_16_1_0 - 4.36825396825394*G0_0_1_16_1_1 + 0.162539682539685*G0_0_1_17_1_0 + 0.345396825396822*G0_0_1_17_1_1 + 0.954920634920631*G0_0_1_18_1_0 - 0.0203174603174596*G0_0_1_18_1_1 - 4.87619047619046*G0_0_1_19_1_0 - 1.46285714285713*G0_0_1_19_1_1 + 0.73142857142857*G0_1_0_0_0_0 + 0.73142857142857*G0_1_0_0_0_1 + 0.386031746031747*G0_1_0_1_0_0 - 1.4222222222222*G0_1_0_2_0_1 - 1.01587301587302*G0_1_0_3_0_0 - 0.0203174603174593*G0_1_0_3_0_1 - 1.9301587301587*G0_1_0_4_0_0 - 1.11746031746031*G0_1_0_4_0_1 - 3.86031746031744*G0_1_0_5_0_0 - 3.6774603174603*G0_1_0_5_0_1 + 1.9301587301587*G0_1_0_6_0_0 + 4.36825396825394*G0_1_0_6_0_1 - 0.162539682539685*G0_1_0_7_0_0 - 0.345396825396822*G0_1_0_7_0_1 - 0.954920634920632*G0_1_0_8_0_0 + 0.0203174603174596*G0_1_0_8_0_1 + 4.87619047619046*G0_1_0_9_0_0 + 1.46285714285713*G0_1_0_9_0_1 + 0.73142857142857*G0_1_0_10_1_0 + 0.73142857142857*G0_1_0_10_1_1 + 0.386031746031747*G0_1_0_11_1_0 - 1.4222222222222*G0_1_0_12_1_1 - 1.01587301587302*G0_1_0_13_1_0 - 0.0203174603174593*G0_1_0_13_1_1 - 1.9301587301587*G0_1_0_14_1_0 - 1.11746031746031*G0_1_0_14_1_1 - 3.86031746031744*G0_1_0_15_1_0 - 3.6774603174603*G0_1_0_15_1_1 + 1.9301587301587*G0_1_0_16_1_0 + 4.36825396825394*G0_1_0_16_1_1 - 0.162539682539685*G0_1_0_17_1_0 - 0.345396825396822*G0_1_0_17_1_1 - 0.954920634920632*G0_1_0_18_1_0 + 0.0203174603174596*G0_1_0_18_1_1 + 4.87619047619046*G0_1_0_19_1_0 + 1.46285714285713*G0_1_0_19_1_1; + A[890] = -A[428] + 1.11746031746031*G0_0_1_0_0_0 + 1.11746031746031*G0_0_1_0_0_1 + 1.11746031746032*G0_0_1_1_0_0 - 4.87619047619046*G0_0_1_3_0_0 - 0.203174603174598*G0_0_1_3_0_1 - 3.55555555555554*G0_0_1_4_0_1 - 4.87619047619045*G0_0_1_5_0_0 - 4.67301587301586*G0_0_1_5_0_1 + 3.55555555555554*G0_0_1_6_0_1 - 1.11746031746031*G0_0_1_7_0_0 - 1.32063492063491*G0_0_1_7_0_1 - 1.11746031746032*G0_0_1_8_0_0 + 0.203174603174599*G0_0_1_8_0_1 + 9.75238095238092*G0_0_1_9_0_0 + 4.87619047619045*G0_0_1_9_0_1 + 1.11746031746031*G0_0_1_10_1_0 + 1.11746031746031*G0_0_1_10_1_1 + 1.11746031746032*G0_0_1_11_1_0 - 4.87619047619046*G0_0_1_13_1_0 - 0.203174603174598*G0_0_1_13_1_1 - 3.55555555555554*G0_0_1_14_1_1 - 4.87619047619045*G0_0_1_15_1_0 - 4.67301587301586*G0_0_1_15_1_1 + 3.55555555555554*G0_0_1_16_1_1 - 1.11746031746031*G0_0_1_17_1_0 - 1.32063492063491*G0_0_1_17_1_1 - 1.11746031746032*G0_0_1_18_1_0 + 0.203174603174599*G0_0_1_18_1_1 + 9.75238095238092*G0_0_1_19_1_0 + 4.87619047619045*G0_0_1_19_1_1 + 0.921058201058197*G0_1_1_0_0_0 + 0.921058201058198*G0_1_1_0_0_1 + 0.196402116402115*G0_1_1_1_0_0 - 0.880423280423275*G0_1_1_2_0_1 - 3.86031746031744*G0_1_1_3_0_0 - 1.76761904761904*G0_1_1_3_0_1 - 1.72698412698412*G0_1_1_4_0_0 - 2.74285714285713*G0_1_1_4_0_1 - 1.01587301587301*G0_1_1_5_0_0 - 2.58031746031745*G0_1_1_5_0_1 + 1.72698412698412*G0_1_1_6_0_0 + 2.53968253968252*G0_1_1_6_0_1 + 0.690793650793646*G0_1_1_7_0_0 + 2.25523809523809*G0_1_1_7_0_1 - 1.80825396825396*G0_1_1_8_0_0 + 1.76761904761904*G0_1_1_8_0_1 + 4.87619047619045*G0_1_1_9_0_0 + 0.487619047619044*G0_1_1_9_0_1 + 0.921058201058197*G0_1_1_10_1_0 + 0.921058201058198*G0_1_1_10_1_1 + 0.196402116402115*G0_1_1_11_1_0 - 0.880423280423275*G0_1_1_12_1_1 - 3.86031746031744*G0_1_1_13_1_0 - 1.76761904761904*G0_1_1_13_1_1 - 1.72698412698412*G0_1_1_14_1_0 - 2.74285714285713*G0_1_1_14_1_1 - 1.01587301587301*G0_1_1_15_1_0 - 2.58031746031745*G0_1_1_15_1_1 + 1.72698412698412*G0_1_1_16_1_0 + 2.53968253968252*G0_1_1_16_1_1 + 0.690793650793646*G0_1_1_17_1_0 + 2.25523809523809*G0_1_1_17_1_1 - 1.80825396825396*G0_1_1_18_1_0 + 1.76761904761904*G0_1_1_18_1_1 + 4.87619047619045*G0_1_1_19_1_0 + 0.487619047619044*G0_1_1_19_1_1; + A[425] = A[890]; + A[860] = -A[863] - 0.345396825396824*G0_0_1_0_0_0 - 0.345396825396825*G0_0_1_0_0_1 + 0.14222222222222*G0_0_1_1_0_0 + 1.21904761904762*G0_0_1_3_0_0 + 0.650158730158728*G0_0_1_3_0_1 + 0.711111111111115*G0_0_1_4_0_1 + 1.21904761904762*G0_0_1_5_0_0 + 1.05650793650794*G0_0_1_5_0_1 - 0.711111111111113*G0_0_1_6_0_1 + 0.833015873015871*G0_0_1_7_0_0 + 0.995555555555557*G0_0_1_7_0_1 - 0.629841269841267*G0_0_1_8_0_0 - 0.650158730158729*G0_0_1_8_0_1 - 2.43809523809524*G0_0_1_9_0_0 - 1.70666666666667*G0_0_1_9_0_1 - 0.345396825396824*G0_0_1_10_1_0 - 0.345396825396825*G0_0_1_10_1_1 + 0.14222222222222*G0_0_1_11_1_0 + 1.21904761904762*G0_0_1_13_1_0 + 0.650158730158728*G0_0_1_13_1_1 + 0.711111111111115*G0_0_1_14_1_1 + 1.21904761904762*G0_0_1_15_1_0 + 1.05650793650794*G0_0_1_15_1_1 - 0.711111111111113*G0_0_1_16_1_1 + 0.833015873015871*G0_0_1_17_1_0 + 0.995555555555557*G0_0_1_17_1_1 - 0.629841269841267*G0_0_1_18_1_0 - 0.650158730158729*G0_0_1_18_1_1 - 2.43809523809524*G0_0_1_19_1_0 - 1.70666666666667*G0_0_1_19_1_1 + 0.352169312169308*G0_1_1_0_0_0 + 0.352169312169307*G0_1_1_0_0_1 + 1.61862433862433*G0_1_1_1_0_0 + 0.54179894179894*G0_1_1_2_0_1 + 0.162539682539685*G0_1_1_3_0_0 + 3.71809523809523*G0_1_1_3_0_1 - 0.507936507936505*G0_1_1_4_0_0 - 2.98666666666665*G0_1_1_4_0_1 - 0.650158730158724*G0_1_1_5_0_0 - 0.629841269841261*G0_1_1_5_0_1 + 0.507936507936505*G0_1_1_6_0_0 - 0.264126984126987*G0_1_1_6_0_1 - 1.62539682539681*G0_1_1_7_0_0 - 1.64571428571427*G0_1_1_7_0_1 - 0.345396825396828*G0_1_1_8_0_0 - 3.71809523809523*G0_1_1_8_0_1 + 0.48761904761904*G0_1_1_9_0_0 + 4.63238095238093*G0_1_1_9_0_1 + 0.352169312169308*G0_1_1_10_1_0 + 0.352169312169307*G0_1_1_10_1_1 + 1.61862433862433*G0_1_1_11_1_0 + 0.54179894179894*G0_1_1_12_1_1 + 0.162539682539685*G0_1_1_13_1_0 + 3.71809523809523*G0_1_1_13_1_1 - 0.507936507936505*G0_1_1_14_1_0 - 2.98666666666665*G0_1_1_14_1_1 - 0.650158730158724*G0_1_1_15_1_0 - 0.629841269841261*G0_1_1_15_1_1 + 0.507936507936505*G0_1_1_16_1_0 - 0.264126984126987*G0_1_1_16_1_1 - 1.62539682539681*G0_1_1_17_1_0 - 1.64571428571427*G0_1_1_17_1_1 - 0.345396825396828*G0_1_1_18_1_0 - 3.71809523809523*G0_1_1_18_1_1 + 0.48761904761904*G0_1_1_19_1_0 + 4.63238095238093*G0_1_1_19_1_1; + A[431] = A[718] + 0.108359788359789*G0_0_0_0_0_0 + 0.108359788359789*G0_0_0_0_0_1 - 0.474074074074073*G0_0_0_1_0_0 + 0.196402116402109*G0_0_0_2_0_1 - 0.304761904761901*G0_0_0_3_0_0 - 0.914285714285711*G0_0_0_3_0_1 + 0.670476190476175*G0_0_0_4_0_0 + 0.609523809523802*G0_0_0_4_0_1 - 0.182857142857145*G0_0_0_5_0_0 - 0.121904761904765*G0_0_0_5_0_1 - 0.670476190476175*G0_0_0_6_0_0 - 0.182857142857133*G0_0_0_6_0_1 - 0.548571428571427*G0_0_0_7_0_0 - 0.609523809523807*G0_0_0_7_0_1 + 0.91428571428571*G0_0_0_8_0_0 + 0.914285714285711*G0_0_0_8_0_1 + 0.487619047619047*G0_0_0_9_0_0 + 0.108359788359789*G0_0_0_10_1_0 + 0.108359788359789*G0_0_0_10_1_1 - 0.474074074074073*G0_0_0_11_1_0 + 0.196402116402109*G0_0_0_12_1_1 - 0.304761904761901*G0_0_0_13_1_0 - 0.914285714285711*G0_0_0_13_1_1 + 0.670476190476175*G0_0_0_14_1_0 + 0.609523809523802*G0_0_0_14_1_1 - 0.182857142857145*G0_0_0_15_1_0 - 0.121904761904765*G0_0_0_15_1_1 - 0.670476190476175*G0_0_0_16_1_0 - 0.182857142857133*G0_0_0_16_1_1 - 0.548571428571427*G0_0_0_17_1_0 - 0.609523809523807*G0_0_0_17_1_1 + 0.91428571428571*G0_0_0_18_1_0 + 0.914285714285711*G0_0_0_18_1_1 + 0.487619047619047*G0_0_0_19_1_0 - 0.650158730158729*G0_0_1_1_0_0 + 0.650158730158718*G0_0_1_2_0_1 - 0.711111111111103*G0_0_1_3_0_0 - 1.36126984126984*G0_0_1_3_0_1 + 1.36126984126982*G0_0_1_4_0_0 + 0.711111111111106*G0_0_1_4_0_1 + 0.589206349206341*G0_0_1_5_0_0 + 0.589206349206342*G0_0_1_5_0_1 - 1.36126984126982*G0_0_1_6_0_0 - 1.23936507936506*G0_0_1_6_0_1 - 0.589206349206344*G0_0_1_7_0_0 - 0.589206349206345*G0_0_1_7_0_1 + 1.23936507936507*G0_0_1_8_0_0 + 1.36126984126984*G0_0_1_8_0_1 + 0.121904761904762*G0_0_1_9_0_0 - 0.121904761904762*G0_0_1_9_0_1 - 0.650158730158729*G0_0_1_11_1_0 + 0.650158730158718*G0_0_1_12_1_1 - 0.711111111111103*G0_0_1_13_1_0 - 1.36126984126984*G0_0_1_13_1_1 + 1.36126984126982*G0_0_1_14_1_0 + 0.711111111111106*G0_0_1_14_1_1 + 0.589206349206341*G0_0_1_15_1_0 + 0.589206349206342*G0_0_1_15_1_1 - 1.36126984126982*G0_0_1_16_1_0 - 1.23936507936506*G0_0_1_16_1_1 - 0.589206349206344*G0_0_1_17_1_0 - 0.589206349206345*G0_0_1_17_1_1 + 1.23936507936507*G0_0_1_18_1_0 + 1.36126984126984*G0_0_1_18_1_1 + 0.121904761904762*G0_0_1_19_1_0 - 0.121904761904762*G0_0_1_19_1_1 - 0.26412698412698*G0_1_0_1_0_0 + 0.264126984126981*G0_1_0_2_0_1 - 0.812698412698412*G0_1_0_3_0_0 - 1.07682539682539*G0_1_0_3_0_1 + 1.07682539682539*G0_1_0_4_0_0 + 0.812698412698402*G0_1_0_4_0_1 - 0.284444444444451*G0_1_0_5_0_0 - 0.284444444444451*G0_1_0_5_0_1 - 1.07682539682539*G0_1_0_6_0_0 + 0.0203174603174683*G0_1_0_6_0_1 + 0.284444444444441*G0_1_0_7_0_0 + 0.284444444444442*G0_1_0_7_0_1 - 0.0203174603174634*G0_1_0_8_0_0 + 1.07682539682539*G0_1_0_8_0_1 + 1.09714285714286*G0_1_0_9_0_0 - 1.09714285714284*G0_1_0_9_0_1 - 0.26412698412698*G0_1_0_11_1_0 + 0.264126984126981*G0_1_0_12_1_1 - 0.812698412698412*G0_1_0_13_1_0 - 1.07682539682539*G0_1_0_13_1_1 + 1.07682539682539*G0_1_0_14_1_0 + 0.812698412698402*G0_1_0_14_1_1 - 0.284444444444451*G0_1_0_15_1_0 - 0.284444444444451*G0_1_0_15_1_1 - 1.07682539682539*G0_1_0_16_1_0 + 0.0203174603174683*G0_1_0_16_1_1 + 0.284444444444441*G0_1_0_17_1_0 + 0.284444444444442*G0_1_0_17_1_1 - 0.0203174603174634*G0_1_0_18_1_0 + 1.07682539682539*G0_1_0_18_1_1 + 1.09714285714286*G0_1_0_19_1_0 - 1.09714285714284*G0_1_0_19_1_1 - 0.108359788359785*G0_1_1_0_0_0 - 0.108359788359785*G0_1_1_0_0_1 - 0.196402116402116*G0_1_1_1_0_0 + 0.474074074074067*G0_1_1_2_0_1 - 0.609523809523806*G0_1_1_3_0_0 - 0.670476190476187*G0_1_1_3_0_1 + 0.914285714285702*G0_1_1_4_0_0 + 0.304761904761899*G0_1_1_4_0_1 + 0.609523809523799*G0_1_1_5_0_0 + 0.548571428571418*G0_1_1_5_0_1 - 0.914285714285702*G0_1_1_6_0_0 - 0.9142857142857*G0_1_1_6_0_1 + 0.121904761904758*G0_1_1_7_0_0 + 0.182857142857139*G0_1_1_7_0_1 + 0.182857142857143*G0_1_1_8_0_0 + 0.670476190476187*G0_1_1_8_0_1 - 0.487619047619038*G0_1_1_9_0_1 - 0.108359788359785*G0_1_1_10_1_0 - 0.108359788359785*G0_1_1_10_1_1 - 0.196402116402116*G0_1_1_11_1_0 + 0.474074074074067*G0_1_1_12_1_1 - 0.609523809523806*G0_1_1_13_1_0 - 0.670476190476187*G0_1_1_13_1_1 + 0.914285714285702*G0_1_1_14_1_0 + 0.304761904761899*G0_1_1_14_1_1 + 0.609523809523799*G0_1_1_15_1_0 + 0.548571428571418*G0_1_1_15_1_1 - 0.914285714285702*G0_1_1_16_1_0 - 0.9142857142857*G0_1_1_16_1_1 + 0.121904761904758*G0_1_1_17_1_0 + 0.182857142857139*G0_1_1_17_1_1 + 0.182857142857143*G0_1_1_18_1_0 + 0.670476190476187*G0_1_1_18_1_1 - 0.487619047619038*G0_1_1_19_1_1; + A[401] = -A[431] + 0.135449735449736*G0_0_0_0_0_0 + 0.135449735449736*G0_0_0_0_0_1 + 1.65248677248676*G0_0_0_1_0_0 + 0.270899470899469*G0_0_0_2_0_1 + 1.46285714285713*G0_0_0_3_0_0 + 3.61650793650791*G0_0_0_3_0_1 - 0.772063492063489*G0_0_0_4_0_1 + 1.46285714285713*G0_0_0_5_0_0 + 0.0406349206349189*G0_0_0_5_0_1 - 0.446984126984125*G0_0_0_6_0_1 + 0.568888888888881*G0_0_0_7_0_0 + 1.9911111111111*G0_0_0_7_0_1 - 2.35682539682538*G0_0_0_8_0_0 - 3.61650793650791*G0_0_0_8_0_1 - 2.92571428571426*G0_0_0_9_0_0 - 1.2190476190476*G0_0_0_9_0_1 + 0.135449735449736*G0_0_0_10_1_0 + 0.135449735449736*G0_0_0_10_1_1 + 1.65248677248676*G0_0_0_11_1_0 + 0.270899470899469*G0_0_0_12_1_1 + 1.46285714285713*G0_0_0_13_1_0 + 3.61650793650791*G0_0_0_13_1_1 - 0.772063492063489*G0_0_0_14_1_1 + 1.46285714285713*G0_0_0_15_1_0 + 0.0406349206349189*G0_0_0_15_1_1 - 0.446984126984125*G0_0_0_16_1_1 + 0.568888888888881*G0_0_0_17_1_0 + 1.9911111111111*G0_0_0_17_1_1 - 2.35682539682538*G0_0_0_18_1_0 - 3.61650793650791*G0_0_0_18_1_1 - 2.92571428571426*G0_0_0_19_1_0 - 1.2190476190476*G0_0_0_19_1_1 - 0.6637037037037*G0_0_1_0_0_0 - 0.663703703703699*G0_0_1_0_0_1 + 2.26878306878305*G0_0_1_1_0_0 - 0.0880423280423279*G0_0_1_2_0_1 + 2.68190476190475*G0_0_1_3_0_0 + 4.77460317460315*G0_0_1_3_0_1 - 0.426666666666662*G0_0_1_4_0_0 - 0.162539682539676*G0_0_1_4_0_1 + 0.609523809523804*G0_0_1_5_0_0 + 0.528253968253964*G0_0_1_5_0_1 + 0.426666666666663*G0_0_1_6_0_0 + 0.223492063492063*G0_0_1_6_0_1 + 2.3974603174603*G0_0_1_7_0_0 + 2.47873015873014*G0_0_1_7_0_1 - 4.00253968253966*G0_0_1_8_0_0 - 4.77460317460315*G0_0_1_8_0_1 - 3.29142857142855*G0_0_1_9_0_0 - 2.31619047619046*G0_0_1_9_0_1 - 0.6637037037037*G0_0_1_10_1_0 - 0.663703703703699*G0_0_1_10_1_1 + 2.26878306878305*G0_0_1_11_1_0 - 0.0880423280423279*G0_0_1_12_1_1 + 2.68190476190475*G0_0_1_13_1_0 + 4.77460317460315*G0_0_1_13_1_1 - 0.426666666666662*G0_0_1_14_1_0 - 0.162539682539676*G0_0_1_14_1_1 + 0.609523809523804*G0_0_1_15_1_0 + 0.528253968253964*G0_0_1_15_1_1 + 0.426666666666663*G0_0_1_16_1_0 + 0.223492063492063*G0_0_1_16_1_1 + 2.3974603174603*G0_0_1_17_1_0 + 2.47873015873014*G0_0_1_17_1_1 - 4.00253968253966*G0_0_1_18_1_0 - 4.77460317460315*G0_0_1_18_1_1 - 3.29142857142855*G0_0_1_19_1_0 - 2.31619047619046*G0_0_1_19_1_1 - 0.176084656084653*G0_1_0_0_0_0 - 0.176084656084654*G0_1_0_0_0_1 + 1.25291005291005*G0_1_0_1_0_0 + 0.318306878306877*G0_1_0_2_0_1 + 1.7879365079365*G0_1_0_3_0_0 + 3.35238095238094*G0_1_0_3_0_1 - 0.223492063492063*G0_1_0_4_0_0 - 0.853333333333334*G0_1_0_4_0_1 + 0.528253968253966*G0_1_0_5_0_0 + 0.568888888888885*G0_1_0_5_0_1 + 0.223492063492064*G0_1_0_6_0_0 - 0.711111111111109*G0_1_0_6_0_1 - 0.203174603174609*G0_1_0_7_0_0 - 0.243809523809526*G0_1_0_7_0_1 - 0.873650793650786*G0_1_0_8_0_0 - 3.35238095238094*G0_1_0_8_0_1 - 2.31619047619046*G0_1_0_9_0_0 + 1.09714285714286*G0_1_0_9_0_1 - 0.176084656084653*G0_1_0_10_1_0 - 0.176084656084654*G0_1_0_10_1_1 + 1.25291005291005*G0_1_0_11_1_0 + 0.318306878306877*G0_1_0_12_1_1 + 1.7879365079365*G0_1_0_13_1_0 + 3.35238095238094*G0_1_0_13_1_1 - 0.223492063492063*G0_1_0_14_1_0 - 0.853333333333334*G0_1_0_14_1_1 + 0.528253968253966*G0_1_0_15_1_0 + 0.568888888888885*G0_1_0_15_1_1 + 0.223492063492064*G0_1_0_16_1_0 - 0.711111111111109*G0_1_0_16_1_1 - 0.203174603174609*G0_1_0_17_1_0 - 0.243809523809526*G0_1_0_17_1_1 - 0.873650793650786*G0_1_0_18_1_0 - 3.35238095238094*G0_1_0_18_1_1 - 2.31619047619046*G0_1_0_19_1_0 + 1.09714285714286*G0_1_0_19_1_1 - 0.568888888888886*G0_1_1_0_0_0 - 0.568888888888886*G0_1_1_0_0_1 - 0.446984126984124*G0_1_1_2_0_1 + 1.42222222222222*G0_1_1_3_0_0 - 0.0406349206349184*G0_1_1_4_0_0 + 1.82857142857142*G0_1_1_4_0_1 + 0.528253968253965*G0_1_1_5_0_0 + 0.690793650793646*G0_1_1_5_0_1 + 0.0406349206349189*G0_1_1_6_0_0 + 0.325079365079364*G0_1_1_6_0_1 + 1.9911111111111*G0_1_1_7_0_0 + 1.82857142857142*G0_1_1_7_0_1 - 1.42222222222222*G0_1_1_8_0_0 - 1.95047619047618*G0_1_1_9_0_0 - 3.65714285714284*G0_1_1_9_0_1 - 0.568888888888886*G0_1_1_10_1_0 - 0.568888888888886*G0_1_1_10_1_1 - 0.446984126984124*G0_1_1_12_1_1 + 1.42222222222222*G0_1_1_13_1_0 - 0.0406349206349184*G0_1_1_14_1_0 + 1.82857142857142*G0_1_1_14_1_1 + 0.528253968253965*G0_1_1_15_1_0 + 0.690793650793646*G0_1_1_15_1_1 + 0.0406349206349189*G0_1_1_16_1_0 + 0.325079365079364*G0_1_1_16_1_1 + 1.9911111111111*G0_1_1_17_1_0 + 1.82857142857142*G0_1_1_17_1_1 - 1.42222222222222*G0_1_1_18_1_0 - 1.95047619047618*G0_1_1_19_1_0 - 3.65714285714284*G0_1_1_19_1_1; + A[866] = A[401]; + A[888] = -A[431] + 0.352169312169311*G0_0_0_0_0_0 + 0.352169312169311*G0_0_0_0_0_1 + 0.541798941798937*G0_0_0_1_0_0 + 1.61862433862433*G0_0_0_2_0_1 - 2.98666666666665*G0_0_0_3_0_0 - 0.507936507936508*G0_0_0_3_0_1 + 3.71809523809521*G0_0_0_4_0_0 + 0.162539682539682*G0_0_0_4_0_1 - 1.64571428571428*G0_0_0_5_0_0 - 1.62539682539682*G0_0_0_5_0_1 - 3.71809523809522*G0_0_0_6_0_0 - 0.345396825396824*G0_0_0_6_0_1 - 0.629841269841268*G0_0_0_7_0_0 - 0.650158730158726*G0_0_0_7_0_1 - 0.26412698412698*G0_0_0_8_0_0 + 0.507936507936508*G0_0_0_8_0_1 + 4.63238095238092*G0_0_0_9_0_0 + 0.487619047619044*G0_0_0_9_0_1 + 0.352169312169311*G0_0_0_10_1_0 + 0.352169312169311*G0_0_0_10_1_1 + 0.541798941798937*G0_0_0_11_1_0 + 1.61862433862433*G0_0_0_12_1_1 - 2.98666666666665*G0_0_0_13_1_0 - 0.507936507936508*G0_0_0_13_1_1 + 3.71809523809521*G0_0_0_14_1_0 + 0.162539682539682*G0_0_0_14_1_1 - 1.64571428571428*G0_0_0_15_1_0 - 1.62539682539682*G0_0_0_15_1_1 - 3.71809523809522*G0_0_0_16_1_0 - 0.345396825396824*G0_0_0_16_1_1 - 0.629841269841268*G0_0_0_17_1_0 - 0.650158730158726*G0_0_0_17_1_1 - 0.26412698412698*G0_0_0_18_1_0 + 0.507936507936508*G0_0_0_18_1_1 + 4.63238095238092*G0_0_0_19_1_0 + 0.487619047619044*G0_0_0_19_1_1 - 0.345396825396823*G0_1_0_0_0_0 - 0.345396825396823*G0_1_0_0_0_1 + 0.142222222222223*G0_1_0_2_0_1 + 0.71111111111111*G0_1_0_3_0_0 + 0.65015873015873*G0_1_0_4_0_0 + 1.21904761904762*G0_1_0_4_0_1 + 0.995555555555555*G0_1_0_5_0_0 + 0.833015873015868*G0_1_0_5_0_1 - 0.65015873015873*G0_1_0_6_0_0 - 0.629841269841268*G0_1_0_6_0_1 + 1.05650793650793*G0_1_0_7_0_0 + 1.21904761904762*G0_1_0_7_0_1 - 0.711111111111111*G0_1_0_8_0_0 - 1.70666666666666*G0_1_0_9_0_0 - 2.43809523809523*G0_1_0_9_0_1 - 0.345396825396823*G0_1_0_10_1_0 - 0.345396825396823*G0_1_0_10_1_1 + 0.142222222222223*G0_1_0_12_1_1 + 0.71111111111111*G0_1_0_13_1_0 + 0.65015873015873*G0_1_0_14_1_0 + 1.21904761904762*G0_1_0_14_1_1 + 0.995555555555555*G0_1_0_15_1_0 + 0.833015873015868*G0_1_0_15_1_1 - 0.65015873015873*G0_1_0_16_1_0 - 0.629841269841268*G0_1_0_16_1_1 + 1.05650793650793*G0_1_0_17_1_0 + 1.21904761904762*G0_1_0_17_1_1 - 0.711111111111111*G0_1_0_18_1_0 - 1.70666666666666*G0_1_0_19_1_0 - 2.43809523809523*G0_1_0_19_1_1; + A[569] = A[888] - 0.101587301587301*G0_0_1_0_0_0 - 0.101587301587301*G0_0_1_0_0_1 - 0.406349206349204*G0_0_1_1_0_0 + 0.121904761904762*G0_0_1_2_0_1 + 0.487619047619048*G0_0_1_3_0_0 - 0.507936507936503*G0_0_1_3_0_1 + 0.426666666666666*G0_0_1_4_0_0 + 0.893968253968251*G0_0_1_4_0_1 + 0.731428571428571*G0_0_1_5_0_0 + 0.629841269841268*G0_0_1_5_0_1 - 0.426666666666666*G0_0_1_6_0_0 - 0.650158730158729*G0_0_1_6_0_1 - 0.0203174603174602*G0_0_1_7_0_0 + 0.081269841269842*G0_0_1_7_0_1 + 0.528253968253965*G0_0_1_8_0_0 + 0.507936507936503*G0_0_1_8_0_1 - 1.21904761904762*G0_0_1_9_0_0 - 0.975238095238092*G0_0_1_9_0_1 - 0.101587301587301*G0_0_1_10_1_0 - 0.101587301587301*G0_0_1_10_1_1 - 0.406349206349204*G0_0_1_11_1_0 + 0.121904761904762*G0_0_1_12_1_1 + 0.487619047619048*G0_0_1_13_1_0 - 0.507936507936503*G0_0_1_13_1_1 + 0.426666666666666*G0_0_1_14_1_0 + 0.893968253968251*G0_0_1_14_1_1 + 0.731428571428571*G0_0_1_15_1_0 + 0.629841269841268*G0_0_1_15_1_1 - 0.426666666666666*G0_0_1_16_1_0 - 0.650158730158729*G0_0_1_16_1_1 - 0.0203174603174602*G0_0_1_17_1_0 + 0.081269841269842*G0_0_1_17_1_1 + 0.528253968253965*G0_0_1_18_1_0 + 0.507936507936503*G0_0_1_18_1_1 - 1.21904761904762*G0_0_1_19_1_0 - 0.975238095238092*G0_0_1_19_1_1 + 0.101587301587301*G0_1_0_0_0_0 + 0.101587301587301*G0_1_0_0_0_1 + 0.406349206349204*G0_1_0_1_0_0 - 0.121904761904762*G0_1_0_2_0_1 - 0.487619047619047*G0_1_0_3_0_0 + 0.507936507936503*G0_1_0_3_0_1 - 0.426666666666666*G0_1_0_4_0_0 - 0.893968253968251*G0_1_0_4_0_1 - 0.73142857142857*G0_1_0_5_0_0 - 0.629841269841268*G0_1_0_5_0_1 + 0.426666666666666*G0_1_0_6_0_0 + 0.650158730158729*G0_1_0_6_0_1 + 0.0203174603174602*G0_1_0_7_0_0 - 0.0812698412698419*G0_1_0_7_0_1 - 0.528253968253965*G0_1_0_8_0_0 - 0.507936507936503*G0_1_0_8_0_1 + 1.21904761904762*G0_1_0_9_0_0 + 0.975238095238092*G0_1_0_9_0_1 + 0.101587301587301*G0_1_0_10_1_0 + 0.101587301587301*G0_1_0_10_1_1 + 0.406349206349204*G0_1_0_11_1_0 - 0.121904761904762*G0_1_0_12_1_1 - 0.487619047619047*G0_1_0_13_1_0 + 0.507936507936503*G0_1_0_13_1_1 - 0.426666666666666*G0_1_0_14_1_0 - 0.893968253968251*G0_1_0_14_1_1 - 0.73142857142857*G0_1_0_15_1_0 - 0.629841269841268*G0_1_0_15_1_1 + 0.426666666666666*G0_1_0_16_1_0 + 0.650158730158729*G0_1_0_16_1_1 + 0.0203174603174602*G0_1_0_17_1_0 - 0.0812698412698419*G0_1_0_17_1_1 - 0.528253968253965*G0_1_0_18_1_0 - 0.507936507936503*G0_1_0_18_1_1 + 1.21904761904762*G0_1_0_19_1_0 + 0.975238095238092*G0_1_0_19_1_1; + A[836] = -A[888] - 0.74497354497354*G0_0_0_0_0_0 - 0.74497354497354*G0_0_0_0_0_1 + 0.419894179894173*G0_0_0_1_0_0 + 1.25291005291004*G0_0_0_2_0_1 - 3.83999999999998*G0_0_0_3_0_0 - 1.84888888888888*G0_0_0_3_0_1 + 3.35238095238093*G0_0_0_4_0_0 + 0.528253968253969*G0_0_0_4_0_1 - 3.23047619047617*G0_0_0_5_0_0 - 0.893968253968247*G0_0_0_5_0_1 - 3.35238095238093*G0_0_0_6_0_0 + 0.386031746031743*G0_0_0_6_0_1 + 1.80825396825396*G0_0_0_7_0_0 - 0.528253968253964*G0_0_0_7_0_1 - 1.48317460317459*G0_0_0_8_0_0 + 1.84888888888889*G0_0_0_8_0_1 + 7.07047619047615*G0_0_0_9_0_0 - 0.74497354497354*G0_0_0_10_1_0 - 0.74497354497354*G0_0_0_10_1_1 + 0.419894179894173*G0_0_0_11_1_0 + 1.25291005291004*G0_0_0_12_1_1 - 3.83999999999998*G0_0_0_13_1_0 - 1.84888888888888*G0_0_0_13_1_1 + 3.35238095238093*G0_0_0_14_1_0 + 0.528253968253969*G0_0_0_14_1_1 - 3.23047619047617*G0_0_0_15_1_0 - 0.893968253968247*G0_0_0_15_1_1 - 3.35238095238093*G0_0_0_16_1_0 + 0.386031746031743*G0_0_0_16_1_1 + 1.80825396825396*G0_0_0_17_1_0 - 0.528253968253964*G0_0_0_17_1_1 - 1.48317460317459*G0_0_0_18_1_0 + 1.84888888888889*G0_0_0_18_1_1 + 7.07047619047615*G0_0_0_19_1_0 + 0.304761904761904*G0_0_1_0_0_0 + 0.304761904761904*G0_0_1_0_0_1 + 0.182857142857142*G0_0_1_2_0_1 - 0.487619047619046*G0_0_1_3_0_0 + 0.182857142857142*G0_0_1_4_0_0 - 0.487619047619043*G0_0_1_4_0_1 - 0.12190476190476*G0_0_1_5_0_0 - 0.426666666666664*G0_0_1_5_0_1 - 0.182857142857142*G0_0_1_6_0_0 - 0.0609523809523813*G0_0_1_6_0_1 - 0.792380952380949*G0_0_1_7_0_0 - 0.487619047619045*G0_0_1_7_0_1 + 0.487619047619049*G0_0_1_8_0_0 + 0.609523809523806*G0_0_1_9_0_0 + 0.975238095238087*G0_0_1_9_0_1 + 0.304761904761904*G0_0_1_10_1_0 + 0.304761904761904*G0_0_1_10_1_1 + 0.182857142857142*G0_0_1_12_1_1 - 0.487619047619046*G0_0_1_13_1_0 + 0.182857142857142*G0_0_1_14_1_0 - 0.487619047619043*G0_0_1_14_1_1 - 0.12190476190476*G0_0_1_15_1_0 - 0.426666666666664*G0_0_1_15_1_1 - 0.182857142857142*G0_0_1_16_1_0 - 0.0609523809523813*G0_0_1_16_1_1 - 0.792380952380949*G0_0_1_17_1_0 - 0.487619047619045*G0_0_1_17_1_1 + 0.487619047619049*G0_0_1_18_1_0 + 0.609523809523806*G0_0_1_19_1_0 + 0.975238095238087*G0_0_1_19_1_1 + 0.325079365079361*G0_1_0_0_0_0 + 0.325079365079362*G0_1_0_0_0_1 + 0.203174603174604*G0_1_0_2_0_1 - 0.0203174603174574*G0_1_0_3_0_0 + 0.711111111111111*G0_1_0_4_0_0 + 0.487619047619049*G0_1_0_4_0_1 + 0.386031746031746*G0_1_0_5_0_0 - 0.44698412698412*G0_1_0_5_0_1 - 0.711111111111111*G0_1_0_6_0_0 - 0.0812698412698444*G0_1_0_6_0_1 - 0.345396825396822*G0_1_0_7_0_0 + 0.487619047619044*G0_1_0_7_0_1 + 0.0203174603174605*G0_1_0_8_0_0 - 0.365714285714288*G0_1_0_9_0_0 - 0.975238095238094*G0_1_0_9_0_1 + 0.325079365079361*G0_1_0_10_1_0 + 0.325079365079362*G0_1_0_10_1_1 + 0.203174603174604*G0_1_0_12_1_1 - 0.0203174603174574*G0_1_0_13_1_0 + 0.711111111111111*G0_1_0_14_1_0 + 0.487619047619049*G0_1_0_14_1_1 + 0.386031746031746*G0_1_0_15_1_0 - 0.44698412698412*G0_1_0_15_1_1 - 0.711111111111111*G0_1_0_16_1_0 - 0.0812698412698444*G0_1_0_16_1_1 - 0.345396825396822*G0_1_0_17_1_0 + 0.487619047619044*G0_1_0_17_1_1 + 0.0203174603174605*G0_1_0_18_1_0 - 0.365714285714288*G0_1_0_19_1_0 - 0.975238095238094*G0_1_0_19_1_1 + 0.121904761904761*G0_1_1_0_0_0 + 0.121904761904761*G0_1_1_0_0_1 - 0.12190476190476*G0_1_1_2_0_1 - 0.121904761904758*G0_1_1_4_0_0 - 0.243809523809518*G0_1_1_5_0_0 - 0.365714285714281*G0_1_1_5_0_1 + 0.121904761904758*G0_1_1_6_0_0 + 0.36571428571428*G0_1_1_6_0_1 - 0.121904761904762*G0_1_1_7_0_0 + 0.243809523809521*G0_1_1_9_0_0 + 0.121904761904761*G0_1_1_10_1_0 + 0.121904761904761*G0_1_1_10_1_1 - 0.12190476190476*G0_1_1_12_1_1 - 0.121904761904758*G0_1_1_14_1_0 - 0.243809523809518*G0_1_1_15_1_0 - 0.365714285714281*G0_1_1_15_1_1 + 0.121904761904758*G0_1_1_16_1_0 + 0.36571428571428*G0_1_1_16_1_1 - 0.121904761904762*G0_1_1_17_1_0 + 0.243809523809521*G0_1_1_19_1_0; + A[363] = -A[836] - 1.47640211640211*G0_0_0_0_0_0 - 1.47640211640211*G0_0_0_0_0_1 + 0.541798941798935*G0_0_0_1_0_0 - 0.697566137566133*G0_0_0_2_0_1 - 0.0609523809523815*G0_0_0_3_0_0 - 0.50793650793651*G0_0_0_3_0_1 + 0.182857142857146*G0_0_0_4_0_0 + 1.86920634920634*G0_0_0_4_0_1 - 3.35238095238093*G0_0_0_5_0_0 - 0.284444444444443*G0_0_0_5_0_1 - 0.182857142857146*G0_0_0_6_0_0 + 2.45841269841268*G0_0_0_6_0_1 + 4.12444444444442*G0_0_0_7_0_0 + 1.05650793650793*G0_0_0_7_0_1 - 3.18984126984125*G0_0_0_8_0_0 + 0.507936507936511*G0_0_0_8_0_1 + 3.41333333333331*G0_0_0_9_0_0 - 2.92571428571428*G0_0_0_9_0_1 - 1.47640211640211*G0_0_0_10_1_0 - 1.47640211640211*G0_0_0_10_1_1 + 0.541798941798935*G0_0_0_11_1_0 - 0.697566137566133*G0_0_0_12_1_1 - 0.0609523809523815*G0_0_0_13_1_0 - 0.50793650793651*G0_0_0_13_1_1 + 0.182857142857146*G0_0_0_14_1_0 + 1.86920634920634*G0_0_0_14_1_1 - 3.35238095238093*G0_0_0_15_1_0 - 0.284444444444443*G0_0_0_15_1_1 - 0.182857142857146*G0_0_0_16_1_0 + 2.45841269841268*G0_0_0_16_1_1 + 4.12444444444442*G0_0_0_17_1_0 + 1.05650793650793*G0_0_0_17_1_1 - 3.18984126984125*G0_0_0_18_1_0 + 0.507936507936511*G0_0_0_18_1_1 + 3.41333333333331*G0_0_0_19_1_0 - 2.92571428571428*G0_0_0_19_1_1 + 0.14222222222222*G0_1_0_0_0_0 + 0.14222222222222*G0_1_0_0_0_1 - 0.345396825396823*G0_1_0_2_0_1 + 0.711111111111108*G0_1_0_3_0_0 + 0.162539682539683*G0_1_0_4_0_0 + 1.21904761904761*G0_1_0_4_0_1 + 0.020317460317457*G0_1_0_5_0_0 - 0.629841269841266*G0_1_0_5_0_1 - 0.162539682539683*G0_1_0_6_0_0 + 0.833015873015869*G0_1_0_6_0_1 + 0.568888888888886*G0_1_0_7_0_0 + 1.21904761904761*G0_1_0_7_0_1 - 0.711111111111109*G0_1_0_8_0_0 - 0.731428571428565*G0_1_0_9_0_0 - 2.43809523809522*G0_1_0_9_0_1 + 0.14222222222222*G0_1_0_10_1_0 + 0.14222222222222*G0_1_0_10_1_1 - 0.345396825396823*G0_1_0_12_1_1 + 0.711111111111108*G0_1_0_13_1_0 + 0.162539682539683*G0_1_0_14_1_0 + 1.21904761904761*G0_1_0_14_1_1 + 0.020317460317457*G0_1_0_15_1_0 - 0.629841269841266*G0_1_0_15_1_1 - 0.162539682539683*G0_1_0_16_1_0 + 0.833015873015869*G0_1_0_16_1_1 + 0.568888888888886*G0_1_0_17_1_0 + 1.21904761904761*G0_1_0_17_1_1 - 0.711111111111109*G0_1_0_18_1_0 - 0.731428571428565*G0_1_0_19_1_0 - 2.43809523809522*G0_1_0_19_1_1; + A[567] = A[363] + 0.020317460317461*G0_0_1_0_0_0 + 0.0203174603174609*G0_0_1_0_0_1 - 0.406349206349206*G0_0_1_1_0_0 - 0.243809523809523*G0_0_1_2_0_1 + 0.731428571428568*G0_0_1_3_0_0 - 0.507936507936508*G0_0_1_3_0_1 + 0.0609523809523816*G0_0_1_4_0_0 + 1.13777777777777*G0_0_1_4_0_1 + 0.243809523809524*G0_0_1_5_0_0 + 0.0203174603174601*G0_0_1_5_0_1 - 0.0609523809523813*G0_0_1_6_0_0 + 0.203174603174602*G0_0_1_6_0_1 + 0.1015873015873*G0_0_1_7_0_0 + 0.325079365079364*G0_0_1_7_0_1 + 0.284444444444445*G0_0_1_8_0_0 + 0.507936507936508*G0_0_1_8_0_1 - 0.975238095238092*G0_0_1_9_0_0 - 1.46285714285714*G0_0_1_9_0_1 + 0.020317460317461*G0_0_1_10_1_0 + 0.0203174603174609*G0_0_1_10_1_1 - 0.406349206349206*G0_0_1_11_1_0 - 0.243809523809523*G0_0_1_12_1_1 + 0.731428571428568*G0_0_1_13_1_0 - 0.507936507936508*G0_0_1_13_1_1 + 0.0609523809523816*G0_0_1_14_1_0 + 1.13777777777777*G0_0_1_14_1_1 + 0.243809523809524*G0_0_1_15_1_0 + 0.0203174603174601*G0_0_1_15_1_1 - 0.0609523809523813*G0_0_1_16_1_0 + 0.203174603174602*G0_0_1_16_1_1 + 0.1015873015873*G0_0_1_17_1_0 + 0.325079365079364*G0_0_1_17_1_1 + 0.284444444444445*G0_0_1_18_1_0 + 0.507936507936508*G0_0_1_18_1_1 - 0.975238095238092*G0_0_1_19_1_0 - 1.46285714285714*G0_0_1_19_1_1 - 0.020317460317461*G0_1_0_0_0_0 - 0.0203174603174609*G0_1_0_0_0_1 + 0.406349206349206*G0_1_0_1_0_0 + 0.243809523809523*G0_1_0_2_0_1 - 0.731428571428568*G0_1_0_3_0_0 + 0.507936507936508*G0_1_0_3_0_1 - 0.0609523809523816*G0_1_0_4_0_0 - 1.13777777777777*G0_1_0_4_0_1 - 0.243809523809524*G0_1_0_5_0_0 - 0.0203174603174601*G0_1_0_5_0_1 + 0.0609523809523814*G0_1_0_6_0_0 - 0.203174603174602*G0_1_0_6_0_1 - 0.1015873015873*G0_1_0_7_0_0 - 0.325079365079363*G0_1_0_7_0_1 - 0.284444444444445*G0_1_0_8_0_0 - 0.507936507936508*G0_1_0_8_0_1 + 0.975238095238092*G0_1_0_9_0_0 + 1.46285714285714*G0_1_0_9_0_1 - 0.020317460317461*G0_1_0_10_1_0 - 0.0203174603174609*G0_1_0_10_1_1 + 0.406349206349206*G0_1_0_11_1_0 + 0.243809523809523*G0_1_0_12_1_1 - 0.731428571428568*G0_1_0_13_1_0 + 0.507936507936508*G0_1_0_13_1_1 - 0.0609523809523816*G0_1_0_14_1_0 - 1.13777777777777*G0_1_0_14_1_1 - 0.243809523809524*G0_1_0_15_1_0 - 0.0203174603174601*G0_1_0_15_1_1 + 0.0609523809523814*G0_1_0_16_1_0 - 0.203174603174602*G0_1_0_16_1_1 - 0.1015873015873*G0_1_0_17_1_0 - 0.325079365079363*G0_1_0_17_1_1 - 0.284444444444445*G0_1_0_18_1_0 - 0.507936507936508*G0_1_0_18_1_1 + 0.975238095238092*G0_1_0_19_1_0 + 1.46285714285714*G0_1_0_19_1_1; + A[658] = A[567] - 0.243809523809524*G0_0_0_0_0_0 - 0.243809523809524*G0_0_0_0_0_1 - 0.243809523809522*G0_0_0_1_0_0 - 0.731428571428565*G0_0_0_3_0_0 - 0.853333333333326*G0_0_0_3_0_1 - 0.12190476190476*G0_0_0_4_0_1 - 0.731428571428567*G0_0_0_5_0_0 + 0.121904761904764*G0_0_0_5_0_1 + 0.121904761904763*G0_0_0_6_0_1 + 0.243809523809527*G0_0_0_7_0_0 - 0.609523809523805*G0_0_0_7_0_1 + 0.24380952380952*G0_0_0_8_0_0 + 0.853333333333327*G0_0_0_8_0_1 + 1.46285714285713*G0_0_0_9_0_0 + 0.731428571428564*G0_0_0_9_0_1 - 0.243809523809524*G0_0_0_10_1_0 - 0.243809523809524*G0_0_0_10_1_1 - 0.243809523809522*G0_0_0_11_1_0 - 0.731428571428565*G0_0_0_13_1_0 - 0.853333333333326*G0_0_0_13_1_1 - 0.12190476190476*G0_0_0_14_1_1 - 0.731428571428567*G0_0_0_15_1_0 + 0.121904761904764*G0_0_0_15_1_1 + 0.121904761904763*G0_0_0_16_1_1 + 0.243809523809527*G0_0_0_17_1_0 - 0.609523809523805*G0_0_0_17_1_1 + 0.24380952380952*G0_0_0_18_1_0 + 0.853333333333327*G0_0_0_18_1_1 + 1.46285714285713*G0_0_0_19_1_0 + 0.731428571428564*G0_0_0_19_1_1 - 0.196402116402115*G0_0_1_0_0_0 - 0.196402116402115*G0_0_1_0_0_1 - 0.0474074074074055*G0_0_1_1_0_0 + 0.135449735449737*G0_0_1_2_0_1 - 0.365714285714283*G0_0_1_3_0_0 - 0.182857142857138*G0_0_1_3_0_1 - 0.365714285714286*G0_0_1_4_0_1 - 0.365714285714281*G0_0_1_5_0_0 + 0.304761904761904*G0_0_1_5_0_1 - 0.243809523809526*G0_0_1_6_0_1 - 0.0609523809523831*G0_0_1_7_0_0 - 0.731428571428568*G0_0_1_7_0_1 + 0.304761904761904*G0_0_1_8_0_0 + 0.182857142857138*G0_0_1_8_0_1 + 0.731428571428564*G0_0_1_9_0_0 + 1.09714285714285*G0_0_1_9_0_1 - 0.196402116402115*G0_0_1_10_1_0 - 0.196402116402115*G0_0_1_10_1_1 - 0.0474074074074055*G0_0_1_11_1_0 + 0.135449735449737*G0_0_1_12_1_1 - 0.365714285714283*G0_0_1_13_1_0 - 0.182857142857138*G0_0_1_13_1_1 - 0.365714285714286*G0_0_1_14_1_1 - 0.365714285714281*G0_0_1_15_1_0 + 0.304761904761904*G0_0_1_15_1_1 - 0.243809523809526*G0_0_1_16_1_1 - 0.0609523809523831*G0_0_1_17_1_0 - 0.731428571428568*G0_0_1_17_1_1 + 0.304761904761904*G0_0_1_18_1_0 + 0.182857142857138*G0_0_1_18_1_1 + 0.731428571428564*G0_0_1_19_1_0 + 1.09714285714285*G0_0_1_19_1_1 + 0.230264550264551*G0_1_0_0_0_0 + 0.230264550264551*G0_1_0_0_0_1 - 0.474074074074076*G0_1_0_1_0_0 - 0.35216931216931*G0_1_0_2_0_1 + 0.121904761904759*G0_1_0_3_0_0 - 0.914285714285717*G0_1_0_3_0_1 + 0.121904761904764*G0_1_0_4_0_0 + 1.03619047619047*G0_1_0_4_0_1 - 0.853333333333326*G0_1_0_5_0_0 - 0.91428571428571*G0_1_0_5_0_1 - 0.121904761904764*G0_1_0_6_0_0 + 1.03619047619047*G0_1_0_6_0_1 - 0.243809523809527*G0_1_0_7_0_0 - 0.182857142857142*G0_1_0_7_0_1 + 0.48761904761905*G0_1_0_8_0_0 + 0.914285714285718*G0_1_0_8_0_1 + 0.731428571428567*G0_1_0_9_0_0 - 0.853333333333333*G0_1_0_9_0_1 + 0.230264550264551*G0_1_0_10_1_0 + 0.230264550264551*G0_1_0_10_1_1 - 0.474074074074076*G0_1_0_11_1_0 - 0.35216931216931*G0_1_0_12_1_1 + 0.121904761904759*G0_1_0_13_1_0 - 0.914285714285717*G0_1_0_13_1_1 + 0.121904761904764*G0_1_0_14_1_0 + 1.03619047619047*G0_1_0_14_1_1 - 0.853333333333326*G0_1_0_15_1_0 - 0.91428571428571*G0_1_0_15_1_1 - 0.121904761904764*G0_1_0_16_1_0 + 1.03619047619047*G0_1_0_16_1_1 - 0.243809523809527*G0_1_0_17_1_0 - 0.182857142857142*G0_1_0_17_1_1 + 0.48761904761905*G0_1_0_18_1_0 + 0.914285714285718*G0_1_0_18_1_1 + 0.731428571428567*G0_1_0_19_1_0 - 0.853333333333333*G0_1_0_19_1_1 + 0.474074074074068*G0_1_1_0_0_0 + 0.474074074074068*G0_1_1_0_0_1 + 0.196402116402114*G0_1_1_1_0_0 - 0.108359788359786*G0_1_1_2_0_1 + 0.487619047619041*G0_1_1_3_0_0 + 0.670476190476182*G0_1_1_3_0_1 + 0.0609523809523833*G0_1_1_4_0_0 + 0.182857142857141*G0_1_1_4_0_1 - 0.914285714285702*G0_1_1_5_0_1 - 0.0609523809523831*G0_1_1_6_0_0 + 0.54857142857142*G0_1_1_6_0_1 - 0.609523809523801*G0_1_1_7_0_0 + 0.3047619047619*G0_1_1_7_0_1 - 0.0609523809523806*G0_1_1_8_0_0 - 0.670476190476182*G0_1_1_8_0_1 - 0.487619047619041*G0_1_1_9_0_0 - 0.487619047619042*G0_1_1_9_0_1 + 0.474074074074068*G0_1_1_10_1_0 + 0.474074074074068*G0_1_1_10_1_1 + 0.196402116402114*G0_1_1_11_1_0 - 0.108359788359786*G0_1_1_12_1_1 + 0.487619047619041*G0_1_1_13_1_0 + 0.670476190476182*G0_1_1_13_1_1 + 0.0609523809523833*G0_1_1_14_1_0 + 0.182857142857141*G0_1_1_14_1_1 - 0.914285714285702*G0_1_1_15_1_1 - 0.0609523809523831*G0_1_1_16_1_0 + 0.54857142857142*G0_1_1_16_1_1 - 0.609523809523801*G0_1_1_17_1_0 + 0.3047619047619*G0_1_1_17_1_1 - 0.0609523809523806*G0_1_1_18_1_0 - 0.670476190476182*G0_1_1_18_1_1 - 0.487619047619041*G0_1_1_19_1_0 - 0.487619047619042*G0_1_1_19_1_1; + A[396] = A[658] + 0.406349206349205*G0_0_1_0_0_0 + 0.406349206349205*G0_0_1_0_0_1 - 0.0203174603174637*G0_0_1_1_0_0 - 0.243809523809524*G0_0_1_2_0_1 - 0.243809523809526*G0_0_1_3_0_0 - 0.223492063492071*G0_0_1_3_0_1 + 0.0609523809523802*G0_0_1_4_0_0 + 0.264126984126985*G0_0_1_4_0_1 - 0.731428571428569*G0_0_1_5_0_0 - 1.23936507936507*G0_0_1_5_0_1 - 0.0609523809523804*G0_0_1_6_0_0 + 1.07682539682539*G0_0_1_6_0_1 - 0.284444444444443*G0_0_1_7_0_0 + 0.223492063492063*G0_0_1_7_0_1 - 0.101587301587298*G0_0_1_8_0_0 + 0.223492063492071*G0_0_1_8_0_1 + 0.975238095238096*G0_0_1_9_0_0 - 0.487619047619048*G0_0_1_9_0_1 + 0.406349206349205*G0_0_1_10_1_0 + 0.406349206349205*G0_0_1_10_1_1 - 0.0203174603174637*G0_0_1_11_1_0 - 0.243809523809524*G0_0_1_12_1_1 - 0.243809523809526*G0_0_1_13_1_0 - 0.223492063492071*G0_0_1_13_1_1 + 0.0609523809523802*G0_0_1_14_1_0 + 0.264126984126985*G0_0_1_14_1_1 - 0.731428571428569*G0_0_1_15_1_0 - 1.23936507936507*G0_0_1_15_1_1 - 0.0609523809523804*G0_0_1_16_1_0 + 1.07682539682539*G0_0_1_16_1_1 - 0.284444444444443*G0_0_1_17_1_0 + 0.223492063492063*G0_0_1_17_1_1 - 0.101587301587298*G0_0_1_18_1_0 + 0.223492063492071*G0_0_1_18_1_1 + 0.975238095238096*G0_0_1_19_1_0 - 0.487619047619048*G0_0_1_19_1_1 - 0.406349206349205*G0_1_0_0_0_0 - 0.406349206349205*G0_1_0_0_0_1 + 0.0203174603174638*G0_1_0_1_0_0 + 0.243809523809524*G0_1_0_2_0_1 + 0.243809523809526*G0_1_0_3_0_0 + 0.223492063492071*G0_1_0_3_0_1 - 0.0609523809523801*G0_1_0_4_0_0 - 0.264126984126985*G0_1_0_4_0_1 + 0.731428571428569*G0_1_0_5_0_0 + 1.23936507936507*G0_1_0_5_0_1 + 0.0609523809523802*G0_1_0_6_0_0 - 1.07682539682539*G0_1_0_6_0_1 + 0.284444444444443*G0_1_0_7_0_0 - 0.223492063492063*G0_1_0_7_0_1 + 0.101587301587298*G0_1_0_8_0_0 - 0.223492063492071*G0_1_0_8_0_1 - 0.975238095238096*G0_1_0_9_0_0 + 0.487619047619048*G0_1_0_9_0_1 - 0.406349206349205*G0_1_0_10_1_0 - 0.406349206349205*G0_1_0_10_1_1 + 0.0203174603174638*G0_1_0_11_1_0 + 0.243809523809524*G0_1_0_12_1_1 + 0.243809523809526*G0_1_0_13_1_0 + 0.223492063492071*G0_1_0_13_1_1 - 0.0609523809523801*G0_1_0_14_1_0 - 0.264126984126985*G0_1_0_14_1_1 + 0.731428571428569*G0_1_0_15_1_0 + 1.23936507936507*G0_1_0_15_1_1 + 0.0609523809523802*G0_1_0_16_1_0 - 1.07682539682539*G0_1_0_16_1_1 + 0.284444444444443*G0_1_0_17_1_0 - 0.223492063492063*G0_1_0_17_1_1 + 0.101587301587298*G0_1_0_18_1_0 - 0.223492063492071*G0_1_0_18_1_1 - 0.975238095238096*G0_1_0_19_1_0 + 0.487619047619048*G0_1_0_19_1_1; + A[342] = -A[567] - 1.47640211640211*G0_0_0_0_0_0 - 1.47640211640211*G0_0_0_0_0_1 + 0.541798941798935*G0_0_0_1_0_0 - 0.697566137566133*G0_0_0_2_0_1 - 0.0609523809523811*G0_0_0_3_0_0 - 0.50793650793651*G0_0_0_3_0_1 + 0.182857142857146*G0_0_0_4_0_0 + 1.86920634920634*G0_0_0_4_0_1 - 3.35238095238093*G0_0_0_5_0_0 - 0.284444444444443*G0_0_0_5_0_1 - 0.182857142857146*G0_0_0_6_0_0 + 2.45841269841268*G0_0_0_6_0_1 + 4.12444444444442*G0_0_0_7_0_0 + 1.05650793650793*G0_0_0_7_0_1 - 3.18984126984125*G0_0_0_8_0_0 + 0.50793650793651*G0_0_0_8_0_1 + 3.41333333333331*G0_0_0_9_0_0 - 2.92571428571428*G0_0_0_9_0_1 - 1.47640211640211*G0_0_0_10_1_0 - 1.47640211640211*G0_0_0_10_1_1 + 0.541798941798935*G0_0_0_11_1_0 - 0.697566137566133*G0_0_0_12_1_1 - 0.0609523809523811*G0_0_0_13_1_0 - 0.50793650793651*G0_0_0_13_1_1 + 0.182857142857146*G0_0_0_14_1_0 + 1.86920634920634*G0_0_0_14_1_1 - 3.35238095238093*G0_0_0_15_1_0 - 0.284444444444443*G0_0_0_15_1_1 - 0.182857142857146*G0_0_0_16_1_0 + 2.45841269841268*G0_0_0_16_1_1 + 4.12444444444442*G0_0_0_17_1_0 + 1.05650793650793*G0_0_0_17_1_1 - 3.18984126984125*G0_0_0_18_1_0 + 0.50793650793651*G0_0_0_18_1_1 + 3.41333333333331*G0_0_0_19_1_0 - 2.92571428571428*G0_0_0_19_1_1 + 0.14222222222222*G0_0_1_0_0_0 + 0.14222222222222*G0_0_1_0_0_1 - 0.345396825396823*G0_0_1_2_0_1 + 0.711111111111108*G0_0_1_3_0_0 + 0.162539682539683*G0_0_1_4_0_0 + 1.21904761904761*G0_0_1_4_0_1 + 0.0203174603174571*G0_0_1_5_0_0 - 0.629841269841266*G0_0_1_5_0_1 - 0.162539682539683*G0_0_1_6_0_0 + 0.833015873015869*G0_0_1_6_0_1 + 0.568888888888887*G0_0_1_7_0_0 + 1.21904761904761*G0_0_1_7_0_1 - 0.711111111111109*G0_0_1_8_0_0 - 0.731428571428566*G0_0_1_9_0_0 - 2.43809523809522*G0_0_1_9_0_1 + 0.14222222222222*G0_0_1_10_1_0 + 0.14222222222222*G0_0_1_10_1_1 - 0.345396825396823*G0_0_1_12_1_1 + 0.711111111111108*G0_0_1_13_1_0 + 0.162539682539683*G0_0_1_14_1_0 + 1.21904761904761*G0_0_1_14_1_1 + 0.0203174603174571*G0_0_1_15_1_0 - 0.629841269841266*G0_0_1_15_1_1 - 0.162539682539683*G0_0_1_16_1_0 + 0.833015873015869*G0_0_1_16_1_1 + 0.568888888888887*G0_0_1_17_1_0 + 1.21904761904761*G0_0_1_17_1_1 - 0.711111111111109*G0_0_1_18_1_0 - 0.731428571428566*G0_0_1_19_1_0 - 2.43809523809522*G0_0_1_19_1_1; + A[441] = 0.0; + A[329] = 0.0; + A[390] = A[855]; + A[346] = 0.0; + A[804] = A[363] - 1.01587301587302*G0_0_0_0_0_0 - 1.01587301587302*G0_0_0_0_0_1 + 0.77206349206349*G0_0_0_1_0_0 + 0.772063492063487*G0_0_0_2_0_1 - 0.934603174603169*G0_0_0_3_0_0 + 1.07682539682539*G0_0_0_3_0_1 - 0.142222222222226*G0_0_0_4_0_0 - 2.15365079365079*G0_0_0_4_0_1 + 0.203174603174601*G0_0_0_5_0_0 + 2.13333333333333*G0_0_0_5_0_1 + 0.142222222222226*G0_0_0_6_0_0 - 1.8895238095238*G0_0_0_6_0_1 + 0.914285714285717*G0_0_0_7_0_0 - 1.01587301587301*G0_0_0_7_0_1 - 0.670476190476191*G0_0_0_8_0_0 - 1.07682539682539*G0_0_0_8_0_1 + 0.731428571428569*G0_0_0_9_0_0 + 3.1695238095238*G0_0_0_9_0_1 - 1.01587301587302*G0_0_0_10_1_0 - 1.01587301587302*G0_0_0_10_1_1 + 0.77206349206349*G0_0_0_11_1_0 + 0.772063492063487*G0_0_0_12_1_1 - 0.934603174603169*G0_0_0_13_1_0 + 1.07682539682539*G0_0_0_13_1_1 - 0.142222222222226*G0_0_0_14_1_0 - 2.15365079365079*G0_0_0_14_1_1 + 0.203174603174601*G0_0_0_15_1_0 + 2.13333333333333*G0_0_0_15_1_1 + 0.142222222222226*G0_0_0_16_1_0 - 1.8895238095238*G0_0_0_16_1_1 + 0.914285714285717*G0_0_0_17_1_0 - 1.01587301587301*G0_0_0_17_1_1 - 0.670476190476191*G0_0_0_18_1_0 - 1.07682539682539*G0_0_0_18_1_1 + 0.731428571428569*G0_0_0_19_1_0 + 3.1695238095238*G0_0_0_19_1_1 - 0.0846560846560828*G0_0_1_0_0_0 - 0.0846560846560827*G0_0_1_0_0_1 + 0.592592592592585*G0_0_1_1_0_0 + 0.308148148148145*G0_0_1_2_0_1 + 0.13206349206349*G0_0_1_3_0_0 + 1.37142857142856*G0_0_1_3_0_1 - 0.0812698412698415*G0_0_1_4_0_0 - 1.03619047619047*G0_0_1_4_0_1 - 0.13206349206349*G0_0_1_5_0_0 + 0.223492063492062*G0_0_1_5_0_1 + 0.0812698412698416*G0_0_1_6_0_0 - 0.446984126984125*G0_0_1_6_0_1 - 0.375873015873018*G0_0_1_7_0_0 - 0.73142857142857*G0_0_1_7_0_1 - 0.132063492063484*G0_0_1_8_0_0 - 1.37142857142856*G0_0_1_8_0_1 + 1.76761904761904*G0_0_1_9_0_1 - 0.0846560846560828*G0_0_1_10_1_0 - 0.0846560846560827*G0_0_1_10_1_1 + 0.592592592592585*G0_0_1_11_1_0 + 0.308148148148145*G0_0_1_12_1_1 + 0.13206349206349*G0_0_1_13_1_0 + 1.37142857142856*G0_0_1_13_1_1 - 0.0812698412698415*G0_0_1_14_1_0 - 1.03619047619047*G0_0_1_14_1_1 - 0.13206349206349*G0_0_1_15_1_0 + 0.223492063492062*G0_0_1_15_1_1 + 0.0812698412698416*G0_0_1_16_1_0 - 0.446984126984125*G0_0_1_16_1_1 - 0.375873015873018*G0_0_1_17_1_0 - 0.73142857142857*G0_0_1_17_1_1 - 0.132063492063484*G0_0_1_18_1_0 - 1.37142857142856*G0_0_1_18_1_1 + 1.76761904761904*G0_0_1_19_1_1 + 0.0304761904761913*G0_1_0_0_0_0 + 0.0304761904761917*G0_1_0_0_0_1 + 0.863492063492059*G0_1_0_1_0_0 + 0.355555555555554*G0_1_0_2_0_1 - 0.9447619047619*G0_1_0_3_0_0 + 1.16825396825396*G0_1_0_3_0_1 - 1.60507936507936*G0_1_0_4_0_1 - 0.0304761904761883*G0_1_0_5_0_0 - 0.162539682539683*G0_1_0_5_0_1 - 0.223492063492063*G0_1_0_6_0_1 + 0.19301587301587*G0_1_0_7_0_0 + 0.325079365079365*G0_1_0_7_0_1 - 1.08698412698412*G0_1_0_8_0_0 - 1.16825396825396*G0_1_0_8_0_1 + 0.975238095238088*G0_1_0_9_0_0 + 1.27999999999999*G0_1_0_9_0_1 + 0.0304761904761913*G0_1_0_10_1_0 + 0.0304761904761917*G0_1_0_10_1_1 + 0.863492063492059*G0_1_0_11_1_0 + 0.355555555555554*G0_1_0_12_1_1 - 0.9447619047619*G0_1_0_13_1_0 + 1.16825396825396*G0_1_0_13_1_1 - 1.60507936507936*G0_1_0_14_1_1 - 0.0304761904761883*G0_1_0_15_1_0 - 0.162539682539683*G0_1_0_15_1_1 - 0.223492063492063*G0_1_0_16_1_1 + 0.19301587301587*G0_1_0_17_1_0 + 0.325079365079365*G0_1_0_17_1_1 - 1.08698412698412*G0_1_0_18_1_0 - 1.16825396825396*G0_1_0_18_1_1 + 0.975238095238088*G0_1_0_19_1_0 + 1.27999999999999*G0_1_0_19_1_1 - 0.196402116402115*G0_1_1_0_0_0 - 0.196402116402115*G0_1_1_0_0_1 + 1.35449735449734*G0_1_1_1_0_0 + 0.196402116402115*G0_1_1_2_0_1 + 0.2031746031746*G0_1_1_3_0_0 + 2.33650793650791*G0_1_1_3_0_1 - 0.0406349206349199*G0_1_1_4_0_0 - 1.01587301587301*G0_1_1_4_0_1 - 0.0812698412698404*G0_1_1_5_0_0 - 0.12190476190476*G0_1_1_5_0_1 + 0.0406349206349199*G0_1_1_6_0_0 + 0.12190476190476*G0_1_1_6_0_1 + 0.975238095238088*G0_1_1_7_0_0 + 1.01587301587301*G0_1_1_7_0_1 - 2.13333333333332*G0_1_1_8_0_0 - 2.33650793650792*G0_1_1_8_0_1 - 0.12190476190476*G0_1_1_9_0_0 - 0.196402116402115*G0_1_1_10_1_0 - 0.196402116402115*G0_1_1_10_1_1 + 1.35449735449734*G0_1_1_11_1_0 + 0.196402116402115*G0_1_1_12_1_1 + 0.2031746031746*G0_1_1_13_1_0 + 2.33650793650791*G0_1_1_13_1_1 - 0.0406349206349199*G0_1_1_14_1_0 - 1.01587301587301*G0_1_1_14_1_1 - 0.0812698412698404*G0_1_1_15_1_0 - 0.12190476190476*G0_1_1_15_1_1 + 0.0406349206349199*G0_1_1_16_1_0 + 0.12190476190476*G0_1_1_16_1_1 + 0.975238095238088*G0_1_1_17_1_0 + 1.01587301587301*G0_1_1_17_1_1 - 2.13333333333332*G0_1_1_18_1_0 - 2.33650793650792*G0_1_1_18_1_1 - 0.12190476190476*G0_1_1_19_1_0; + A[27] = 0.0; + A[728] = 0.0; + A[387] = 0.0; + A[56] = 0.0; + A[755] = 0.0; + A[416] = 0.0; + A[61] = 0.017010582010582*G0_1_0_0_0_0 + 0.017010582010582*G0_1_0_0_0_1 - 0.137962962962963*G0_1_0_1_0_0 - 0.137962962962962*G0_1_0_2_0_1 + 0.109444444444444*G0_1_0_3_0_0 - 0.197222222222223*G0_1_0_3_0_1 - 0.197222222222221*G0_1_0_4_0_0 + 0.109444444444444*G0_1_0_4_0_1 - 0.0532539682539681*G0_1_0_5_0_0 - 0.0366666666666665*G0_1_0_5_0_1 + 0.197222222222221*G0_1_0_6_0_0 + 0.157619047619047*G0_1_0_6_0_1 - 0.0366666666666668*G0_1_0_7_0_0 - 0.0532539682539685*G0_1_0_7_0_1 + 0.157619047619048*G0_1_0_8_0_0 + 0.197222222222223*G0_1_0_8_0_1 - 0.0561904761904756*G0_1_0_9_0_0 - 0.0561904761904759*G0_1_0_9_0_1 + 0.017010582010582*G0_1_0_10_1_0 + 0.017010582010582*G0_1_0_10_1_1 - 0.137962962962963*G0_1_0_11_1_0 - 0.137962962962962*G0_1_0_12_1_1 + 0.109444444444444*G0_1_0_13_1_0 - 0.197222222222223*G0_1_0_13_1_1 - 0.197222222222221*G0_1_0_14_1_0 + 0.109444444444444*G0_1_0_14_1_1 - 0.0532539682539681*G0_1_0_15_1_0 - 0.0366666666666665*G0_1_0_15_1_1 + 0.197222222222221*G0_1_0_16_1_0 + 0.157619047619047*G0_1_0_16_1_1 - 0.0366666666666668*G0_1_0_17_1_0 - 0.0532539682539685*G0_1_0_17_1_1 + 0.157619047619048*G0_1_0_18_1_0 + 0.197222222222223*G0_1_0_18_1_1 - 0.0561904761904756*G0_1_0_19_1_0 - 0.0561904761904759*G0_1_0_19_1_1; + A[466] = -A[61] - 0.137962962962963*G0_0_0_0_0_0 - 0.137962962962963*G0_0_0_0_0_1 + 0.137962962962963*G0_0_0_1_0_0 + 0.017010582010582*G0_0_0_2_0_1 + 0.0396031746031743*G0_0_0_3_0_0 + 0.197222222222222*G0_0_0_3_0_1 - 0.0165873015873017*G0_0_0_4_0_0 - 0.0532539682539684*G0_0_0_4_0_1 - 0.0396031746031746*G0_0_0_5_0_0 + 0.157619047619048*G0_0_0_5_0_1 + 0.0165873015873017*G0_0_0_6_0_0 - 0.0366666666666669*G0_0_0_6_0_1 + 0.306666666666666*G0_0_0_7_0_0 + 0.109444444444444*G0_0_0_7_0_1 - 0.306666666666666*G0_0_0_8_0_0 - 0.197222222222222*G0_0_0_8_0_1 - 0.0561904761904752*G0_0_0_9_0_1 - 0.137962962962963*G0_0_0_10_1_0 - 0.137962962962963*G0_0_0_10_1_1 + 0.137962962962963*G0_0_0_11_1_0 + 0.017010582010582*G0_0_0_12_1_1 + 0.0396031746031743*G0_0_0_13_1_0 + 0.197222222222222*G0_0_0_13_1_1 - 0.0165873015873017*G0_0_0_14_1_0 - 0.0532539682539684*G0_0_0_14_1_1 - 0.0396031746031746*G0_0_0_15_1_0 + 0.157619047619048*G0_0_0_15_1_1 + 0.0165873015873017*G0_0_0_16_1_0 - 0.0366666666666669*G0_0_0_16_1_1 + 0.306666666666666*G0_0_0_17_1_0 + 0.109444444444444*G0_0_0_17_1_1 - 0.306666666666666*G0_0_0_18_1_0 - 0.197222222222222*G0_0_0_18_1_1 - 0.0561904761904752*G0_0_0_19_1_1 - 0.120952380952381*G0_1_0_0_0_0 - 0.120952380952381*G0_1_0_0_0_1 - 0.12095238095238*G0_1_0_2_0_1 + 0.149047619047618*G0_1_0_3_0_0 - 0.213809523809523*G0_1_0_4_0_0 + 0.056190476190476*G0_1_0_4_0_1 - 0.0928571428571427*G0_1_0_5_0_0 + 0.120952380952381*G0_1_0_5_0_1 + 0.213809523809523*G0_1_0_6_0_0 + 0.12095238095238*G0_1_0_6_0_1 + 0.269999999999999*G0_1_0_7_0_0 + 0.0561904761904751*G0_1_0_7_0_1 - 0.149047619047617*G0_1_0_8_0_0 - 0.0561904761904752*G0_1_0_9_0_0 - 0.112380952380951*G0_1_0_9_0_1 - 0.120952380952381*G0_1_0_10_1_0 - 0.120952380952381*G0_1_0_10_1_1 - 0.12095238095238*G0_1_0_12_1_1 + 0.149047619047618*G0_1_0_13_1_0 - 0.213809523809523*G0_1_0_14_1_0 + 0.056190476190476*G0_1_0_14_1_1 - 0.0928571428571427*G0_1_0_15_1_0 + 0.120952380952381*G0_1_0_15_1_1 + 0.213809523809523*G0_1_0_16_1_0 + 0.12095238095238*G0_1_0_16_1_1 + 0.269999999999999*G0_1_0_17_1_0 + 0.0561904761904751*G0_1_0_17_1_1 - 0.149047619047617*G0_1_0_18_1_0 - 0.0561904761904752*G0_1_0_19_1_0 - 0.112380952380951*G0_1_0_19_1_1; + A[782] = 0.0; + A[893] = A[428]; + A[118] = 0.0; + A[821] = 0.0; + A[852] = 0.0; + A[212] = A[677]; + A[626] = A[161]; + A[490] = 0.0; + A[209] = 0.0; + A[577] = 0.0; + A[521] = 0.0; + A[234] = 0.0; + A[676] = A[502] - 0.0244444444444437*G0_0_1_0_0_0 - 0.0244444444444437*G0_0_1_0_0_1 - 0.0244444444444434*G0_0_1_2_0_1 + 0.0258730158730159*G0_0_1_3_0_0 - 0.0474603174603159*G0_0_1_4_0_0 + 0.00285714285714198*G0_0_1_4_0_1 - 0.0230158730158715*G0_0_1_5_0_0 + 0.0244444444444438*G0_0_1_5_0_1 + 0.0474603174603159*G0_0_1_6_0_0 + 0.0244444444444434*G0_0_1_6_0_1 + 0.0503174603174596*G0_0_1_7_0_0 + 0.00285714285714429*G0_0_1_7_0_1 - 0.0258730158730173*G0_0_1_8_0_0 - 0.00285714285714447*G0_0_1_9_0_0 - 0.00571428571428635*G0_0_1_9_0_1 - 0.0244444444444437*G0_0_1_10_1_0 - 0.0244444444444437*G0_0_1_10_1_1 - 0.0244444444444434*G0_0_1_12_1_1 + 0.0258730158730159*G0_0_1_13_1_0 - 0.0474603174603159*G0_0_1_14_1_0 + 0.00285714285714198*G0_0_1_14_1_1 - 0.0230158730158715*G0_0_1_15_1_0 + 0.0244444444444438*G0_0_1_15_1_1 + 0.0474603174603159*G0_0_1_16_1_0 + 0.0244444444444434*G0_0_1_16_1_1 + 0.0503174603174596*G0_0_1_17_1_0 + 0.00285714285714429*G0_0_1_17_1_1 - 0.0258730158730173*G0_0_1_18_1_0 - 0.00285714285714447*G0_0_1_19_1_0 - 0.00571428571428635*G0_0_1_19_1_1 + 0.0244444444444437*G0_1_0_0_0_0 + 0.0244444444444437*G0_1_0_0_0_1 + 0.0244444444444434*G0_1_0_2_0_1 - 0.0258730158730159*G0_1_0_3_0_0 + 0.0474603174603159*G0_1_0_4_0_0 - 0.002857142857142*G0_1_0_4_0_1 + 0.0230158730158715*G0_1_0_5_0_0 - 0.0244444444444438*G0_1_0_5_0_1 - 0.0474603174603159*G0_1_0_6_0_0 - 0.0244444444444434*G0_1_0_6_0_1 - 0.0503174603174596*G0_1_0_7_0_0 - 0.00285714285714431*G0_1_0_7_0_1 + 0.0258730158730173*G0_1_0_8_0_0 + 0.00285714285714444*G0_1_0_9_0_0 + 0.00571428571428638*G0_1_0_9_0_1 + 0.0244444444444437*G0_1_0_10_1_0 + 0.0244444444444437*G0_1_0_10_1_1 + 0.0244444444444434*G0_1_0_12_1_1 - 0.0258730158730159*G0_1_0_13_1_0 + 0.0474603174603159*G0_1_0_14_1_0 - 0.002857142857142*G0_1_0_14_1_1 + 0.0230158730158715*G0_1_0_15_1_0 - 0.0244444444444438*G0_1_0_15_1_1 - 0.0474603174603159*G0_1_0_16_1_0 - 0.0244444444444434*G0_1_0_16_1_1 - 0.0503174603174596*G0_1_0_17_1_0 - 0.00285714285714431*G0_1_0_17_1_1 + 0.0258730158730173*G0_1_0_18_1_0 + 0.00285714285714444*G0_1_0_19_1_0 + 0.00571428571428638*G0_1_0_19_1_1; + A[600] = 0.0; + A[556] = A[91]; + A[635] = 0.0; + A[670] = 0.0; + A[277] = A[219] + 1.09206349206349*G0_0_1_0_0_0 + 1.09206349206349*G0_0_1_0_0_1 - 0.213333333333332*G0_0_1_1_0_0 - 0.11174603174603*G0_0_1_2_0_1 - 0.0939682539682516*G0_0_1_3_0_0 + 0.0533333333333321*G0_0_1_3_0_1 + 0.0279365079365104*G0_0_1_4_0_0 - 0.220952380952377*G0_0_1_4_0_1 - 0.317460317460313*G0_0_1_5_0_0 - 1.815873015873*G0_0_1_5_0_1 - 0.0279365079365104*G0_0_1_6_0_0 + 0.83555555555555*G0_0_1_6_0_1 - 2.14603174603173*G0_0_1_7_0_0 - 0.647619047619043*G0_0_1_7_0_1 + 1.26730158730158*G0_0_1_8_0_0 - 0.0533333333333317*G0_0_1_8_0_1 + 0.411428571428565*G0_0_1_9_0_0 + 0.868571428571419*G0_0_1_9_0_1 + 1.09206349206349*G0_0_1_10_1_0 + 1.09206349206349*G0_0_1_10_1_1 - 0.213333333333332*G0_0_1_11_1_0 - 0.11174603174603*G0_0_1_12_1_1 - 0.0939682539682516*G0_0_1_13_1_0 + 0.0533333333333321*G0_0_1_13_1_1 + 0.0279365079365104*G0_0_1_14_1_0 - 0.220952380952377*G0_0_1_14_1_1 - 0.317460317460313*G0_0_1_15_1_0 - 1.815873015873*G0_0_1_15_1_1 - 0.0279365079365104*G0_0_1_16_1_0 + 0.83555555555555*G0_0_1_16_1_1 - 2.14603174603173*G0_0_1_17_1_0 - 0.647619047619043*G0_0_1_17_1_1 + 1.26730158730158*G0_0_1_18_1_0 - 0.0533333333333317*G0_0_1_18_1_1 + 0.411428571428565*G0_0_1_19_1_0 + 0.868571428571419*G0_0_1_19_1_1 - 1.09206349206349*G0_1_0_0_0_0 - 1.09206349206349*G0_1_0_0_0_1 + 0.213333333333332*G0_1_0_1_0_0 + 0.11174603174603*G0_1_0_2_0_1 + 0.0939682539682516*G0_1_0_3_0_0 - 0.0533333333333321*G0_1_0_3_0_1 - 0.0279365079365104*G0_1_0_4_0_0 + 0.220952380952377*G0_1_0_4_0_1 + 0.317460317460313*G0_1_0_5_0_0 + 1.815873015873*G0_1_0_5_0_1 + 0.0279365079365104*G0_1_0_6_0_0 - 0.83555555555555*G0_1_0_6_0_1 + 2.14603174603173*G0_1_0_7_0_0 + 0.647619047619043*G0_1_0_7_0_1 - 1.26730158730158*G0_1_0_8_0_0 + 0.0533333333333317*G0_1_0_8_0_1 - 0.411428571428565*G0_1_0_9_0_0 - 0.868571428571419*G0_1_0_9_0_1 - 1.09206349206349*G0_1_0_10_1_0 - 1.09206349206349*G0_1_0_10_1_1 + 0.213333333333332*G0_1_0_11_1_0 + 0.11174603174603*G0_1_0_12_1_1 + 0.0939682539682516*G0_1_0_13_1_0 - 0.0533333333333321*G0_1_0_13_1_1 - 0.0279365079365104*G0_1_0_14_1_0 + 0.220952380952377*G0_1_0_14_1_1 + 0.317460317460313*G0_1_0_15_1_0 + 1.815873015873*G0_1_0_15_1_1 + 0.0279365079365104*G0_1_0_16_1_0 - 0.83555555555555*G0_1_0_16_1_1 + 2.14603174603173*G0_1_0_17_1_0 + 0.647619047619043*G0_1_0_17_1_1 - 1.26730158730158*G0_1_0_18_1_0 + 0.0533333333333317*G0_1_0_18_1_1 - 0.411428571428565*G0_1_0_19_1_0 - 0.868571428571419*G0_1_0_19_1_1; + A[367] = -A[277] - 0.877037037037036*G0_0_0_0_0_0 - 0.877037037037036*G0_0_0_0_0_1 - 0.35216931216931*G0_0_0_1_0_0 + 0.612910052910055*G0_0_0_2_0_1 + 1.53904761904761*G0_0_0_3_0_0 - 0.0939682539682523*G0_0_0_3_0_1 + 1.18857142857143*G0_0_0_4_0_0 + 1.85650793650793*G0_0_0_4_0_1 + 2.08761904761905*G0_0_0_5_0_0 + 2.63873015873016*G0_0_0_5_0_1 - 1.18857142857143*G0_0_0_6_0_0 - 2.37460317460318*G0_0_0_6_0_1 + 1.02603174603174*G0_0_0_7_0_0 + 0.474920634920632*G0_0_0_7_0_1 + 0.203174603174603*G0_0_0_8_0_0 + 0.0939682539682522*G0_0_0_8_0_1 - 3.62666666666666*G0_0_0_9_0_0 - 2.33142857142856*G0_0_0_9_0_1 - 0.877037037037036*G0_0_0_10_1_0 - 0.877037037037036*G0_0_0_10_1_1 - 0.35216931216931*G0_0_0_11_1_0 + 0.612910052910055*G0_0_0_12_1_1 + 1.53904761904761*G0_0_0_13_1_0 - 0.0939682539682523*G0_0_0_13_1_1 + 1.18857142857143*G0_0_0_14_1_0 + 1.85650793650793*G0_0_0_14_1_1 + 2.08761904761905*G0_0_0_15_1_0 + 2.63873015873016*G0_0_0_15_1_1 - 1.18857142857143*G0_0_0_16_1_0 - 2.37460317460318*G0_0_0_16_1_1 + 1.02603174603174*G0_0_0_17_1_0 + 0.474920634920632*G0_0_0_17_1_1 + 0.203174603174603*G0_0_0_18_1_0 + 0.0939682539682522*G0_0_0_18_1_1 - 3.62666666666666*G0_0_0_19_1_0 - 2.33142857142856*G0_0_0_19_1_1 + 0.422433862433857*G0_0_1_0_0_0 + 0.422433862433857*G0_0_1_0_0_1 + 0.334391534391533*G0_0_1_1_0_0 - 0.112592592592589*G0_0_1_2_0_1 - 0.551111111111108*G0_0_1_3_0_0 - 0.152380952380953*G0_0_1_3_0_1 + 1.55936507936508*G0_0_1_4_0_0 + 1.60761904761904*G0_0_1_4_0_1 - 3.1974603174603*G0_0_1_5_0_0 - 2.98920634920633*G0_0_1_5_0_1 - 1.55936507936508*G0_0_1_6_0_0 + 2.67936507936506*G0_0_1_6_0_1 + 0.0634920634920682*G0_0_1_7_0_0 - 0.144761904761905*G0_0_1_7_0_1 - 0.82031746031746*G0_0_1_8_0_0 + 0.152380952380955*G0_0_1_8_0_1 + 3.74857142857141*G0_0_1_9_0_0 - 1.46285714285714*G0_0_1_9_0_1 + 0.422433862433857*G0_0_1_10_1_0 + 0.422433862433857*G0_0_1_10_1_1 + 0.334391534391533*G0_0_1_11_1_0 - 0.112592592592589*G0_0_1_12_1_1 - 0.551111111111108*G0_0_1_13_1_0 - 0.152380952380953*G0_0_1_13_1_1 + 1.55936507936508*G0_0_1_14_1_0 + 1.60761904761904*G0_0_1_14_1_1 - 3.1974603174603*G0_0_1_15_1_0 - 2.98920634920633*G0_0_1_15_1_1 - 1.55936507936508*G0_0_1_16_1_0 + 2.67936507936506*G0_0_1_16_1_1 + 0.0634920634920682*G0_0_1_17_1_0 - 0.144761904761905*G0_0_1_17_1_1 - 0.82031746031746*G0_0_1_18_1_0 + 0.152380952380955*G0_0_1_18_1_1 + 3.74857142857141*G0_0_1_19_1_0 - 1.46285714285714*G0_0_1_19_1_1 - 0.0601058201058204*G0_1_0_0_0_0 - 0.0601058201058205*G0_1_0_0_0_1 - 0.0313227513227496*G0_1_0_1_0_0 + 0.639153439153439*G0_1_0_2_0_1 + 0.319999999999997*G0_1_0_3_0_0 - 0.175238095238092*G0_1_0_3_0_1 + 2.4*G0_1_0_4_0_0 + 2.2247619047619*G0_1_0_4_0_1 - 0.822857142857138*G0_1_0_5_0_0 - 0.56380952380952*G0_1_0_5_0_1 - 2.4*G0_1_0_6_0_0 - 0.015238095238099*G0_1_0_6_0_1 - 0.259047619047618*G0_1_0_7_0_1 + 0.0914285714285686*G0_1_0_8_0_0 + 0.175238095238093*G0_1_0_8_0_1 + 0.50285714285714*G0_1_0_9_0_0 - 1.96571428571428*G0_1_0_9_0_1 - 0.0601058201058204*G0_1_0_10_1_0 - 0.0601058201058205*G0_1_0_10_1_1 - 0.0313227513227496*G0_1_0_11_1_0 + 0.639153439153439*G0_1_0_12_1_1 + 0.319999999999997*G0_1_0_13_1_0 - 0.175238095238092*G0_1_0_13_1_1 + 2.4*G0_1_0_14_1_0 + 2.2247619047619*G0_1_0_14_1_1 - 0.822857142857138*G0_1_0_15_1_0 - 0.56380952380952*G0_1_0_15_1_1 - 2.4*G0_1_0_16_1_0 - 0.015238095238099*G0_1_0_16_1_1 - 0.259047619047618*G0_1_0_17_1_1 + 0.0914285714285686*G0_1_0_18_1_0 + 0.175238095238093*G0_1_0_18_1_1 + 0.50285714285714*G0_1_0_19_1_0 - 1.96571428571428*G0_1_0_19_1_1 + 0.579047619047618*G0_1_1_0_0_0 + 0.579047619047618*G0_1_1_0_0_1 + 0.579047619047619*G0_1_1_2_0_1 + 0.40380952380952*G0_1_1_3_0_0 + 2.14095238095238*G0_1_1_4_0_0 + 1.96571428571428*G0_1_1_4_0_1 + 1.56190476190475*G0_1_1_5_0_0 - 0.579047619047618*G0_1_1_5_0_1 - 2.14095238095238*G0_1_1_6_0_0 - 0.579047619047618*G0_1_1_6_0_1 - 0.175238095238097*G0_1_1_7_0_0 + 1.96571428571428*G0_1_1_7_0_1 - 0.403809523809523*G0_1_1_8_0_0 - 1.96571428571427*G0_1_1_9_0_0 - 3.93142857142856*G0_1_1_9_0_1 + 0.579047619047618*G0_1_1_10_1_0 + 0.579047619047618*G0_1_1_10_1_1 + 0.579047619047619*G0_1_1_12_1_1 + 0.40380952380952*G0_1_1_13_1_0 + 2.14095238095238*G0_1_1_14_1_0 + 1.96571428571428*G0_1_1_14_1_1 + 1.56190476190475*G0_1_1_15_1_0 - 0.579047619047618*G0_1_1_15_1_1 - 2.14095238095238*G0_1_1_16_1_0 - 0.579047619047618*G0_1_1_16_1_1 - 0.175238095238097*G0_1_1_17_1_0 + 1.96571428571428*G0_1_1_17_1_1 - 0.403809523809523*G0_1_1_18_1_0 - 1.96571428571427*G0_1_1_19_1_0 - 3.93142857142856*G0_1_1_19_1_1; + A[132] = A[367] - 0.12190476190476*G0_0_0_0_0_0 - 0.12190476190476*G0_0_0_0_0_1 + 0.426666666666663*G0_0_0_1_0_0 + 0.579047619047612*G0_0_0_3_0_1 - 0.152380952380957*G0_0_0_4_0_1 - 0.0304761904761981*G0_0_0_5_0_1 + 0.152380952380962*G0_0_0_6_0_1 + 0.670476190476186*G0_0_0_7_0_0 + 0.700952380952374*G0_0_0_7_0_1 - 0.97523809523809*G0_0_0_8_0_0 - 0.579047619047612*G0_0_0_8_0_1 - 0.548571428571417*G0_0_0_9_0_1 - 0.12190476190476*G0_0_0_10_1_0 - 0.12190476190476*G0_0_0_10_1_1 + 0.426666666666663*G0_0_0_11_1_0 + 0.579047619047612*G0_0_0_13_1_1 - 0.152380952380957*G0_0_0_14_1_1 - 0.0304761904761981*G0_0_0_15_1_1 + 0.152380952380962*G0_0_0_16_1_1 + 0.670476190476186*G0_0_0_17_1_0 + 0.700952380952374*G0_0_0_17_1_1 - 0.97523809523809*G0_0_0_18_1_0 - 0.579047619047612*G0_0_0_18_1_1 - 0.548571428571417*G0_0_0_19_1_1 + 0.416507936507937*G0_0_1_0_0_0 + 0.416507936507936*G0_0_1_0_0_1 - 0.416507936507936*G0_0_1_1_0_0 + 0.132063492063492*G0_0_1_2_0_1 + 2.1790476190476*G0_0_1_3_0_0 + 0.853333333333325*G0_0_1_3_0_1 - 0.655238095238092*G0_0_1_4_0_0 + 0.121904761904757*G0_0_1_4_0_1 + 4.67809523809522*G0_0_1_5_0_0 + 2.10285714285713*G0_0_1_5_0_1 + 0.655238095238093*G0_0_1_6_0_0 - 2.65142857142856*G0_0_1_6_0_1 - 1.05142857142857*G0_0_1_7_0_0 + 1.52380952380951*G0_0_1_7_0_1 + 1.05142857142857*G0_0_1_8_0_0 - 0.853333333333326*G0_0_1_8_0_1 - 6.85714285714282*G0_0_1_9_0_0 - 1.64571428571427*G0_0_1_9_0_1 + 0.416507936507937*G0_0_1_10_1_0 + 0.416507936507936*G0_0_1_10_1_1 - 0.416507936507936*G0_0_1_11_1_0 + 0.132063492063492*G0_0_1_12_1_1 + 2.1790476190476*G0_0_1_13_1_0 + 0.853333333333325*G0_0_1_13_1_1 - 0.655238095238092*G0_0_1_14_1_0 + 0.121904761904757*G0_0_1_14_1_1 + 4.67809523809522*G0_0_1_15_1_0 + 2.10285714285713*G0_0_1_15_1_1 + 0.655238095238093*G0_0_1_16_1_0 - 2.65142857142856*G0_0_1_16_1_1 - 1.05142857142857*G0_0_1_17_1_0 + 1.52380952380951*G0_0_1_17_1_1 + 1.05142857142857*G0_0_1_18_1_0 - 0.853333333333326*G0_0_1_18_1_1 - 6.85714285714282*G0_0_1_19_1_0 - 1.64571428571427*G0_0_1_19_1_1 - 0.19301587301587*G0_1_0_0_0_0 - 0.19301587301587*G0_1_0_0_0_1 + 0.497777777777771*G0_1_0_1_0_0 - 0.843174603174601*G0_1_0_2_0_1 + 1.78285714285713*G0_1_0_3_0_0 + 1.5390476190476*G0_1_0_3_0_1 - 2.24*G0_1_0_4_0_0 - 0.655238095238095*G0_1_0_4_0_1 + 2.33142857142856*G0_1_0_5_0_0 + 1.20380952380952*G0_1_0_5_0_1 + 2.24*G0_1_0_6_0_0 - 0.167619047619047*G0_1_0_6_0_1 + 1.44761904761903*G0_1_0_7_0_0 + 2.57523809523808*G0_1_0_7_0_1 - 1.75238095238094*G0_1_0_8_0_0 - 1.5390476190476*G0_1_0_8_0_1 - 4.1142857142857*G0_1_0_9_0_0 - 1.91999999999998*G0_1_0_9_0_1 - 0.19301587301587*G0_1_0_10_1_0 - 0.19301587301587*G0_1_0_10_1_1 + 0.497777777777771*G0_1_0_11_1_0 - 0.843174603174601*G0_1_0_12_1_1 + 1.78285714285713*G0_1_0_13_1_0 + 1.5390476190476*G0_1_0_13_1_1 - 2.24*G0_1_0_14_1_0 - 0.655238095238095*G0_1_0_14_1_1 + 2.33142857142856*G0_1_0_15_1_0 + 1.20380952380952*G0_1_0_15_1_1 + 2.24*G0_1_0_16_1_0 - 0.167619047619047*G0_1_0_16_1_1 + 1.44761904761903*G0_1_0_17_1_0 + 2.57523809523808*G0_1_0_17_1_1 - 1.75238095238094*G0_1_0_18_1_0 - 1.5390476190476*G0_1_0_18_1_1 - 4.1142857142857*G0_1_0_19_1_0 - 1.91999999999998*G0_1_0_19_1_1 - 2.30603174603173*G0_1_1_0_0_0 - 2.30603174603174*G0_1_1_0_0_1 + 0.690793650793645*G0_1_1_1_0_0 - 0.284444444444445*G0_1_1_2_0_1 + 1.5695238095238*G0_1_1_3_0_0 + 1.5542857142857*G0_1_1_3_0_1 - 2.08761904761904*G0_1_1_4_0_0 - 1.09714285714285*G0_1_1_4_0_1 - 0.0152380952380942*G0_1_1_5_0_0 + 3.99238095238093*G0_1_1_5_0_1 + 2.08761904761904*G0_1_1_6_0_0 - 1.40190476190476*G0_1_1_6_0_1 + 3.27619047619046*G0_1_1_7_0_0 - 0.731428571428572*G0_1_1_7_0_1 - 1.66095238095237*G0_1_1_8_0_0 - 1.5542857142857*G0_1_1_8_0_1 - 1.55428571428571*G0_1_1_9_0_0 + 1.82857142857143*G0_1_1_9_0_1 - 2.30603174603173*G0_1_1_10_1_0 - 2.30603174603174*G0_1_1_10_1_1 + 0.690793650793645*G0_1_1_11_1_0 - 0.284444444444445*G0_1_1_12_1_1 + 1.5695238095238*G0_1_1_13_1_0 + 1.5542857142857*G0_1_1_13_1_1 - 2.08761904761904*G0_1_1_14_1_0 - 1.09714285714285*G0_1_1_14_1_1 - 0.0152380952380942*G0_1_1_15_1_0 + 3.99238095238093*G0_1_1_15_1_1 + 2.08761904761904*G0_1_1_16_1_0 - 1.40190476190476*G0_1_1_16_1_1 + 3.27619047619046*G0_1_1_17_1_0 - 0.731428571428572*G0_1_1_17_1_1 - 1.66095238095237*G0_1_1_18_1_0 - 1.5542857142857*G0_1_1_18_1_1 - 1.55428571428571*G0_1_1_19_1_0 + 1.82857142857143*G0_1_1_19_1_1; + A[597] = A[132]; + A[892] = -A[277] - 0.0643386243386262*G0_0_0_0_0_0 - 0.0643386243386262*G0_0_0_0_0_1 - 0.646772486772487*G0_0_0_1_0_0 - 2.63788359788359*G0_0_0_2_0_1 + 1.63047619047619*G0_0_0_3_0_0 + 0.424126984126981*G0_0_0_3_0_1 - 7.9542857142857*G0_0_0_4_0_0 - 4.75682539682538*G0_0_0_4_0_1 + 2.17904761904761*G0_0_0_5_0_0 + 2.12063492063492*G0_0_0_5_0_1 + 7.9542857142857*G0_0_0_6_0_0 + 0.581587301587305*G0_0_0_6_0_1 - 0.284444444444439*G0_0_0_7_0_0 - 0.226031746031745*G0_0_0_7_0_1 + 0.995555555555555*G0_0_0_8_0_0 - 0.424126984126982*G0_0_0_8_0_1 - 3.80952380952381*G0_0_0_9_0_0 + 4.98285714285713*G0_0_0_9_0_1 - 0.0643386243386262*G0_0_0_10_1_0 - 0.0643386243386262*G0_0_0_10_1_1 - 0.646772486772487*G0_0_0_11_1_0 - 2.63788359788359*G0_0_0_12_1_1 + 1.63047619047619*G0_0_0_13_1_0 + 0.424126984126981*G0_0_0_13_1_1 - 7.9542857142857*G0_0_0_14_1_0 - 4.75682539682538*G0_0_0_14_1_1 + 2.17904761904761*G0_0_0_15_1_0 + 2.12063492063492*G0_0_0_15_1_1 + 7.9542857142857*G0_0_0_16_1_0 + 0.581587301587305*G0_0_0_16_1_1 - 0.284444444444439*G0_0_0_17_1_0 - 0.226031746031745*G0_0_0_17_1_1 + 0.995555555555555*G0_0_0_18_1_0 - 0.424126984126982*G0_0_0_18_1_1 - 3.80952380952381*G0_0_0_19_1_0 + 4.98285714285713*G0_0_0_19_1_1 + 1.55513227513226*G0_0_1_0_0_0 + 1.55513227513226*G0_0_1_0_0_1 - 0.53925925925926*G0_0_1_1_0_0 - 3.01291005291004*G0_0_1_2_0_1 + 0.97269841269842*G0_0_1_3_0_0 + 0.396190476190472*G0_0_1_3_0_1 - 6.92825396825395*G0_0_1_4_0_0 - 3.87809523809522*G0_0_1_4_0_1 - 0.972698412698403*G0_0_1_5_0_0 - 2.60825396825395*G0_0_1_5_0_1 + 6.92825396825395*G0_0_1_6_0_0 + 4.06603174603173*G0_0_1_6_0_1 - 2.51174603174601*G0_0_1_7_0_0 - 0.876190476190472*G0_0_1_7_0_1 + 1.49587301587301*G0_0_1_8_0_0 - 0.396190476190472*G0_0_1_8_0_1 + 4.75428571428569*G0_0_1_9_0_1 + 1.55513227513226*G0_0_1_10_1_0 + 1.55513227513226*G0_0_1_10_1_1 - 0.53925925925926*G0_0_1_11_1_0 - 3.01291005291004*G0_0_1_12_1_1 + 0.97269841269842*G0_0_1_13_1_0 + 0.396190476190472*G0_0_1_13_1_1 - 6.92825396825395*G0_0_1_14_1_0 - 3.87809523809522*G0_0_1_14_1_1 - 0.972698412698403*G0_0_1_15_1_0 - 2.60825396825395*G0_0_1_15_1_1 + 6.92825396825395*G0_0_1_16_1_0 + 4.06603174603173*G0_0_1_16_1_1 - 2.51174603174601*G0_0_1_17_1_0 - 0.876190476190472*G0_0_1_17_1_1 + 1.49587301587301*G0_0_1_18_1_0 - 0.396190476190472*G0_0_1_18_1_1 + 4.75428571428569*G0_0_1_19_1_1 + 1.10306878306878*G0_1_0_0_0_0 + 1.10306878306878*G0_1_0_0_0_1 + 0.253121693121693*G0_1_0_1_0_0 - 2.2916402116402*G0_1_0_2_0_1 - 1.14285714285714*G0_1_0_3_0_0 + 0.312380952380952*G0_1_0_3_0_1 - 5.5085714285714*G0_1_0_4_0_0 - 4.4190476190476*G0_1_0_4_0_1 - 1.64571428571428*G0_1_0_5_0_0 - 2.65142857142856*G0_1_0_5_0_1 + 5.5085714285714*G0_1_0_6_0_0 + 3.83999999999998*G0_1_0_6_0_1 - 0.838095238095234*G0_1_0_7_0_0 + 0.16761904761905*G0_1_0_7_0_1 - 0.518095238095235*G0_1_0_8_0_0 - 0.312380952380953*G0_1_0_8_0_1 + 2.78857142857141*G0_1_0_9_0_0 + 4.25142857142855*G0_1_0_9_0_1 + 1.10306878306878*G0_1_0_10_1_0 + 1.10306878306878*G0_1_0_10_1_1 + 0.253121693121693*G0_1_0_11_1_0 - 2.2916402116402*G0_1_0_12_1_1 - 1.14285714285714*G0_1_0_13_1_0 + 0.312380952380952*G0_1_0_13_1_1 - 5.5085714285714*G0_1_0_14_1_0 - 4.4190476190476*G0_1_0_14_1_1 - 1.64571428571428*G0_1_0_15_1_0 - 2.65142857142856*G0_1_0_15_1_1 + 5.5085714285714*G0_1_0_16_1_0 + 3.83999999999998*G0_1_0_16_1_1 - 0.838095238095234*G0_1_0_17_1_0 + 0.16761904761905*G0_1_0_17_1_1 - 0.518095238095235*G0_1_0_18_1_0 - 0.312380952380953*G0_1_0_18_1_1 + 2.78857142857141*G0_1_0_19_1_0 + 4.25142857142855*G0_1_0_19_1_1 - 1.18857142857142*G0_1_1_0_0_0 - 1.18857142857142*G0_1_1_0_0_1 - 1.18857142857142*G0_1_1_2_0_1 - 0.937142857142851*G0_1_1_3_0_0 - 4.50285714285712*G0_1_1_4_0_0 - 4.25142857142855*G0_1_1_4_0_1 - 3.31428571428569*G0_1_1_5_0_0 + 1.18857142857143*G0_1_1_5_0_1 + 4.50285714285712*G0_1_1_6_0_0 + 1.18857142857142*G0_1_1_6_0_1 + 0.251428571428573*G0_1_1_7_0_0 - 4.25142857142855*G0_1_1_7_0_1 + 0.937142857142852*G0_1_1_8_0_0 + 4.25142857142854*G0_1_1_9_0_0 + 8.5028571428571*G0_1_1_9_0_1 - 1.18857142857142*G0_1_1_10_1_0 - 1.18857142857142*G0_1_1_10_1_1 - 1.18857142857142*G0_1_1_12_1_1 - 0.937142857142851*G0_1_1_13_1_0 - 4.50285714285712*G0_1_1_14_1_0 - 4.25142857142855*G0_1_1_14_1_1 - 3.31428571428569*G0_1_1_15_1_0 + 1.18857142857143*G0_1_1_15_1_1 + 4.50285714285712*G0_1_1_16_1_0 + 1.18857142857142*G0_1_1_16_1_1 + 0.251428571428573*G0_1_1_17_1_0 - 4.25142857142855*G0_1_1_17_1_1 + 0.937142857142852*G0_1_1_18_1_0 + 4.25142857142854*G0_1_1_19_1_0 + 8.5028571428571*G0_1_1_19_1_1; + A[427] = A[892]; + A[312] = A[132] + 2.30603174603173*G0_0_0_0_0_0 + 2.30603174603173*G0_0_0_0_0_1 + 0.284444444444447*G0_0_0_1_0_0 - 0.690793650793646*G0_0_0_2_0_1 + 1.09714285714285*G0_0_0_3_0_0 + 2.08761904761904*G0_0_0_3_0_1 - 1.5542857142857*G0_0_0_4_0_0 - 1.5695238095238*G0_0_0_4_0_1 + 0.731428571428564*G0_0_0_5_0_0 - 3.27619047619046*G0_0_0_5_0_1 + 1.55428571428571*G0_0_0_6_0_0 + 1.66095238095237*G0_0_0_6_0_1 - 3.99238095238093*G0_0_0_7_0_0 + 0.0152380952380959*G0_0_0_7_0_1 + 1.40190476190475*G0_0_0_8_0_0 - 2.08761904761904*G0_0_0_8_0_1 - 1.82857142857141*G0_0_0_9_0_0 + 1.55428571428571*G0_0_0_9_0_1 + 2.30603174603173*G0_0_0_10_1_0 + 2.30603174603173*G0_0_0_10_1_1 + 0.284444444444447*G0_0_0_11_1_0 - 0.690793650793646*G0_0_0_12_1_1 + 1.09714285714285*G0_0_0_13_1_0 + 2.08761904761904*G0_0_0_13_1_1 - 1.5542857142857*G0_0_0_14_1_0 - 1.5695238095238*G0_0_0_14_1_1 + 0.731428571428564*G0_0_0_15_1_0 - 3.27619047619046*G0_0_0_15_1_1 + 1.55428571428571*G0_0_0_16_1_0 + 1.66095238095237*G0_0_0_16_1_1 - 3.99238095238093*G0_0_0_17_1_0 + 0.0152380952380959*G0_0_0_17_1_1 + 1.40190476190475*G0_0_0_18_1_0 - 2.08761904761904*G0_0_0_18_1_1 - 1.82857142857141*G0_0_0_19_1_0 + 1.55428571428571*G0_0_0_19_1_1 - 0.416507936507929*G0_0_1_0_0_0 - 0.41650793650793*G0_0_1_0_0_1 + 0.203174603174604*G0_0_1_1_0_0 + 0.0812698412698354*G0_0_1_2_0_1 + 0.259047619047621*G0_0_1_3_0_0 + 1.37142857142857*G0_0_1_3_0_1 - 1.56952380952381*G0_0_1_4_0_0 - 2.55999999999999*G0_0_1_4_0_1 - 1.81333333333332*G0_0_1_5_0_0 + 0.761904761904746*G0_0_1_5_0_1 + 1.56952380952381*G0_0_1_6_0_0 - 0.426666666666654*G0_0_1_6_0_1 - 1.81333333333332*G0_0_1_7_0_0 - 4.38857142857139*G0_0_1_7_0_1 + 2.02666666666665*G0_0_1_8_0_0 - 1.37142857142857*G0_0_1_8_0_1 + 1.5542857142857*G0_0_1_9_0_0 + 6.94857142857138*G0_0_1_9_0_1 - 0.416507936507929*G0_0_1_10_1_0 - 0.41650793650793*G0_0_1_10_1_1 + 0.203174603174604*G0_0_1_11_1_0 + 0.0812698412698354*G0_0_1_12_1_1 + 0.259047619047621*G0_0_1_13_1_0 + 1.37142857142857*G0_0_1_13_1_1 - 1.56952380952381*G0_0_1_14_1_0 - 2.55999999999999*G0_0_1_14_1_1 - 1.81333333333332*G0_0_1_15_1_0 + 0.761904761904746*G0_0_1_15_1_1 + 1.56952380952381*G0_0_1_16_1_0 - 0.426666666666654*G0_0_1_16_1_1 - 1.81333333333332*G0_0_1_17_1_0 - 4.38857142857139*G0_0_1_17_1_1 + 2.02666666666665*G0_0_1_18_1_0 - 1.37142857142857*G0_0_1_18_1_1 + 1.5542857142857*G0_0_1_19_1_0 + 6.94857142857138*G0_0_1_19_1_1 + 0.193015873015872*G0_1_0_0_0_0 + 0.193015873015872*G0_1_0_0_0_1 + 0.507936507936511*G0_1_0_1_0_0 - 0.162539682539683*G0_1_0_2_0_1 + 0.27428571428571*G0_1_0_3_0_0 + 1.52380952380952*G0_1_0_3_0_1 - 0.82285714285714*G0_1_0_4_0_0 - 1.40190476190476*G0_1_0_4_0_1 - 2.28571428571429*G0_1_0_5_0_0 - 1.15809523809524*G0_1_0_5_0_1 + 0.822857142857141*G0_1_0_6_0_0 + 1.12761904761905*G0_1_0_6_0_1 - 1.49333333333333*G0_1_0_7_0_0 - 2.62095238095237*G0_1_0_7_0_1 + 0.792380952380942*G0_1_0_8_0_0 - 1.52380952380953*G0_1_0_8_0_1 + 2.01142857142858*G0_1_0_9_0_0 + 4.02285714285713*G0_1_0_9_0_1 + 0.193015873015872*G0_1_0_10_1_0 + 0.193015873015872*G0_1_0_10_1_1 + 0.507936507936511*G0_1_0_11_1_0 - 0.162539682539683*G0_1_0_12_1_1 + 0.27428571428571*G0_1_0_13_1_0 + 1.52380952380952*G0_1_0_13_1_1 - 0.82285714285714*G0_1_0_14_1_0 - 1.40190476190476*G0_1_0_14_1_1 - 2.28571428571429*G0_1_0_15_1_0 - 1.15809523809524*G0_1_0_15_1_1 + 0.822857142857141*G0_1_0_16_1_0 + 1.12761904761905*G0_1_0_16_1_1 - 1.49333333333333*G0_1_0_17_1_0 - 2.62095238095237*G0_1_0_17_1_1 + 0.792380952380942*G0_1_0_18_1_0 - 1.52380952380953*G0_1_0_18_1_1 + 2.01142857142858*G0_1_0_19_1_0 + 4.02285714285713*G0_1_0_19_1_1 + 0.121904761904765*G0_1_1_0_0_0 + 0.121904761904766*G0_1_1_0_0_1 - 0.426666666666667*G0_1_1_2_0_1 + 0.152380952380952*G0_1_1_3_0_0 - 0.579047619047619*G0_1_1_4_0_0 - 0.700952380952376*G0_1_1_5_0_0 - 0.670476190476195*G0_1_1_5_0_1 + 0.579047619047619*G0_1_1_6_0_0 + 0.975238095238097*G0_1_1_6_0_1 + 0.0304761904761883*G0_1_1_7_0_0 - 0.152380952380955*G0_1_1_8_0_0 + 0.548571428571424*G0_1_1_9_0_0 + 0.121904761904765*G0_1_1_10_1_0 + 0.121904761904766*G0_1_1_10_1_1 - 0.426666666666667*G0_1_1_12_1_1 + 0.152380952380952*G0_1_1_13_1_0 - 0.579047619047619*G0_1_1_14_1_0 - 0.700952380952376*G0_1_1_15_1_0 - 0.670476190476195*G0_1_1_15_1_1 + 0.579047619047619*G0_1_1_16_1_0 + 0.975238095238097*G0_1_1_16_1_1 + 0.0304761904761883*G0_1_1_17_1_0 - 0.152380952380955*G0_1_1_18_1_0 + 0.548571428571424*G0_1_1_19_1_0; + A[309] = -A[312] + 4.86264550264548*G0_0_0_0_0_0 + 4.86264550264548*G0_0_0_0_0_1 - 1.55089947089946*G0_0_0_1_0_0 - 0.540105820105817*G0_0_0_2_0_1 + 1.78285714285713*G0_0_0_3_0_0 - 0.23873015873016*G0_0_0_3_0_1 + 0.365714285714286*G0_0_0_4_0_0 + 1.37650793650793*G0_0_0_4_0_1 + 4.79999999999997*G0_0_0_5_0_0 - 5.35365079365077*G0_0_0_5_0_1 - 0.365714285714286*G0_0_0_6_0_0 + 1.03111111111111*G0_0_0_6_0_1 - 7.78158730158727*G0_0_0_7_0_0 + 2.37206349206348*G0_0_0_7_0_1 + 4.46984126984125*G0_0_0_8_0_0 + 0.238730158730158*G0_0_0_8_0_1 - 6.58285714285711*G0_0_0_9_0_0 - 3.74857142857141*G0_0_0_9_0_1 + 4.86264550264548*G0_0_0_10_1_0 + 4.86264550264548*G0_0_0_10_1_1 - 1.55089947089946*G0_0_0_11_1_0 - 0.540105820105817*G0_0_0_12_1_1 + 1.78285714285713*G0_0_0_13_1_0 - 0.23873015873016*G0_0_0_13_1_1 + 0.365714285714286*G0_0_0_14_1_0 + 1.37650793650793*G0_0_0_14_1_1 + 4.79999999999997*G0_0_0_15_1_0 - 5.35365079365077*G0_0_0_15_1_1 - 0.365714285714286*G0_0_0_16_1_0 + 1.03111111111111*G0_0_0_16_1_1 - 7.78158730158727*G0_0_0_17_1_0 + 2.37206349206348*G0_0_0_17_1_1 + 4.46984126984125*G0_0_0_18_1_0 + 0.238730158730158*G0_0_0_18_1_1 - 6.58285714285711*G0_0_0_19_1_0 - 3.74857142857141*G0_0_0_19_1_1 - 0.314074074074071*G0_0_1_0_0_0 - 0.314074074074071*G0_0_1_0_0_1 - 0.737354497354494*G0_0_1_1_0_0 - 0.0211640211640221*G0_0_1_2_0_1 + 0.708571428571425*G0_0_1_3_0_0 - 0.906666666666662*G0_0_1_3_0_1 + 0.899047619047614*G0_0_1_4_0_1 + 0.479999999999999*G0_0_1_5_0_0 + 1.08190476190475*G0_0_1_5_0_1 - 0.746666666666661*G0_0_1_6_0_1 - 0.16*G0_0_1_7_0_0 - 0.761904761904756*G0_0_1_7_0_1 + 1.21142857142856*G0_0_1_8_0_0 + 0.906666666666663*G0_0_1_8_0_1 - 1.18857142857142*G0_0_1_9_0_0 - 0.13714285714286*G0_0_1_9_0_1 - 0.314074074074071*G0_0_1_10_1_0 - 0.314074074074071*G0_0_1_10_1_1 - 0.737354497354494*G0_0_1_11_1_0 - 0.0211640211640221*G0_0_1_12_1_1 + 0.708571428571425*G0_0_1_13_1_0 - 0.906666666666662*G0_0_1_13_1_1 + 0.899047619047614*G0_0_1_14_1_1 + 0.479999999999999*G0_0_1_15_1_0 + 1.08190476190475*G0_0_1_15_1_1 - 0.746666666666661*G0_0_1_16_1_1 - 0.16*G0_0_1_17_1_0 - 0.761904761904756*G0_0_1_17_1_1 + 1.21142857142856*G0_0_1_18_1_0 + 0.906666666666663*G0_0_1_18_1_1 - 1.18857142857142*G0_0_1_19_1_0 - 0.13714285714286*G0_0_1_19_1_1 - 0.568042328042322*G0_1_0_0_0_0 - 0.568042328042323*G0_1_0_0_0_1 - 0.564656084656081*G0_1_0_1_0_0 - 0.0516402116402128*G0_1_0_2_0_1 + 1.35365079365078*G0_1_0_3_0_0 - 0.0990476190476159*G0_1_0_3_0_1 - 0.208253968253967*G0_1_0_4_0_0 + 0.731428571428565*G0_1_0_4_0_1 - 1.17079365079365*G0_1_0_5_0_0 + 0.904126984126971*G0_1_0_5_0_1 + 0.208253968253968*G0_1_0_6_0_0 - 0.284444444444436*G0_1_0_6_0_1 - 0.744126984126985*G0_1_0_7_0_0 - 2.81904761904761*G0_1_0_7_0_1 + 1.87682539682539*G0_1_0_8_0_0 + 0.0990476190476159*G0_1_0_8_0_1 - 0.182857142857133*G0_1_0_9_0_0 + 2.08761904761904*G0_1_0_9_0_1 - 0.568042328042322*G0_1_0_10_1_0 - 0.568042328042323*G0_1_0_10_1_1 - 0.564656084656081*G0_1_0_11_1_0 - 0.0516402116402128*G0_1_0_12_1_1 + 1.35365079365078*G0_1_0_13_1_0 - 0.0990476190476159*G0_1_0_13_1_1 - 0.208253968253967*G0_1_0_14_1_0 + 0.731428571428565*G0_1_0_14_1_1 - 1.17079365079365*G0_1_0_15_1_0 + 0.904126984126971*G0_1_0_15_1_1 + 0.208253968253968*G0_1_0_16_1_0 - 0.284444444444436*G0_1_0_16_1_1 - 0.744126984126985*G0_1_0_17_1_0 - 2.81904761904761*G0_1_0_17_1_1 + 1.87682539682539*G0_1_0_18_1_0 + 0.0990476190476159*G0_1_0_18_1_1 - 0.182857142857133*G0_1_0_19_1_0 + 2.08761904761904*G0_1_0_19_1_1 - 0.00507936507936457*G0_1_1_0_0_0 - 0.00507936507936446*G0_1_1_0_0_1 - 0.863492063492058*G0_1_1_1_0_0 - 0.543492063492061*G0_1_1_2_0_1 + 0.929523809523805*G0_1_1_3_0_0 - 1.44761904761904*G0_1_1_3_0_1 + 0.0152380952380959*G0_1_1_4_0_0 + 2.07238095238094*G0_1_1_4_0_1 + 0.350476190476191*G0_1_1_5_0_0 - 0.0152380952380955*G0_1_1_6_0_0 + 0.548571428571426*G0_1_1_6_0_1 + 0.502857142857142*G0_1_1_7_0_0 + 0.853333333333333*G0_1_1_7_0_1 + 0.365714285714279*G0_1_1_8_0_0 + 1.44761904761904*G0_1_1_8_0_1 - 1.28*G0_1_1_9_0_0 - 2.92571428571427*G0_1_1_9_0_1 - 0.00507936507936457*G0_1_1_10_1_0 - 0.00507936507936446*G0_1_1_10_1_1 - 0.863492063492058*G0_1_1_11_1_0 - 0.543492063492061*G0_1_1_12_1_1 + 0.929523809523805*G0_1_1_13_1_0 - 1.44761904761904*G0_1_1_13_1_1 + 0.0152380952380959*G0_1_1_14_1_0 + 2.07238095238094*G0_1_1_14_1_1 + 0.350476190476191*G0_1_1_15_1_0 - 0.0152380952380955*G0_1_1_16_1_0 + 0.548571428571426*G0_1_1_16_1_1 + 0.502857142857142*G0_1_1_17_1_0 + 0.853333333333333*G0_1_1_17_1_1 + 0.365714285714279*G0_1_1_18_1_0 + 1.44761904761904*G0_1_1_18_1_1 - 1.28*G0_1_1_19_1_0 - 2.92571428571427*G0_1_1_19_1_1; + A[775] = A[312] - 4.7669841269841*G0_0_0_0_0_0 - 4.76698412698411*G0_0_0_0_0_1 + 2.99936507936506*G0_0_0_1_0_0 + 0.85460317460317*G0_0_0_2_0_1 - 0.902857142857138*G0_0_0_3_0_0 + 3.55809523809522*G0_0_0_3_0_1 - 0.548571428571429*G0_0_0_4_0_0 - 2.86476190476189*G0_0_0_4_0_1 - 5.31428571428569*G0_0_0_5_0_0 + 4.88761904761903*G0_0_0_5_0_1 + 0.548571428571428*G0_0_0_6_0_0 - 0.975238095238094*G0_0_0_6_0_1 + 7.21523809523806*G0_0_0_7_0_0 - 2.98666666666665*G0_0_0_7_0_1 - 5.44761904761902*G0_0_0_8_0_0 - 3.55809523809522*G0_0_0_8_0_1 + 6.21714285714282*G0_0_0_9_0_0 + 5.85142857142854*G0_0_0_9_0_1 - 4.7669841269841*G0_0_0_10_1_0 - 4.76698412698411*G0_0_0_10_1_1 + 2.99936507936506*G0_0_0_11_1_0 + 0.85460317460317*G0_0_0_12_1_1 - 0.902857142857138*G0_0_0_13_1_0 + 3.55809523809522*G0_0_0_13_1_1 - 0.548571428571429*G0_0_0_14_1_0 - 2.86476190476189*G0_0_0_14_1_1 - 5.31428571428569*G0_0_0_15_1_0 + 4.88761904761903*G0_0_0_15_1_1 + 0.548571428571428*G0_0_0_16_1_0 - 0.975238095238094*G0_0_0_16_1_1 + 7.21523809523806*G0_0_0_17_1_0 - 2.98666666666665*G0_0_0_17_1_1 - 5.44761904761902*G0_0_0_18_1_0 - 3.55809523809522*G0_0_0_18_1_1 + 6.21714285714282*G0_0_0_19_1_0 + 5.85142857142854*G0_0_0_19_1_1 + 0.9695238095238*G0_0_1_0_0_0 + 0.969523809523802*G0_0_1_0_0_1 + 2.83619047619046*G0_0_1_1_0_0 - 0.00952380952380671*G0_0_1_2_0_1 + 0.108571428571427*G0_0_1_3_0_0 + 4.75999999999998*G0_0_1_3_0_1 - 1.80571428571428*G0_0_1_4_0_1 + 0.279999999999996*G0_0_1_5_0_0 - 2.76571428571426*G0_0_1_5_0_1 + 1.80571428571427*G0_0_1_6_0_1 + 1.01142857142857*G0_0_1_7_0_0 + 4.05714285714283*G0_0_1_7_0_1 - 4.81714285714283*G0_0_1_8_0_0 - 4.75999999999998*G0_0_1_8_0_1 - 0.388571428571423*G0_0_1_9_0_0 - 2.25142857142855*G0_0_1_9_0_1 + 0.9695238095238*G0_0_1_10_1_0 + 0.969523809523802*G0_0_1_10_1_1 + 2.83619047619046*G0_0_1_11_1_0 - 0.00952380952380671*G0_0_1_12_1_1 + 0.108571428571427*G0_0_1_13_1_0 + 4.75999999999998*G0_0_1_13_1_1 - 1.80571428571428*G0_0_1_14_1_1 + 0.279999999999996*G0_0_1_15_1_0 - 2.76571428571426*G0_0_1_15_1_1 + 1.80571428571427*G0_0_1_16_1_1 + 1.01142857142857*G0_0_1_17_1_0 + 4.05714285714283*G0_0_1_17_1_1 - 4.81714285714283*G0_0_1_18_1_0 - 4.75999999999998*G0_0_1_18_1_1 - 0.388571428571423*G0_0_1_19_1_0 - 2.25142857142855*G0_0_1_19_1_1 + 0.359999999999996*G0_1_0_0_0_0 + 0.359999999999997*G0_1_0_0_0_1 + 2.19619047619046*G0_1_0_1_0_0 + 0.569523809523808*G0_1_0_2_0_1 - 0.287619047619043*G0_1_0_3_0_0 + 3.89142857142855*G0_1_0_3_0_1 - 0.0304761904761913*G0_1_0_4_0_0 - 2.58285714285713*G0_1_0_4_0_1 + 1.04190476190476*G0_1_0_5_0_0 - 0.556190476190467*G0_1_0_5_0_1 + 0.0304761904761909*G0_1_0_6_0_0 - 0.373333333333338*G0_1_0_6_0_1 + 0.40190476190476*G0_1_0_7_0_0 + 1.99999999999999*G0_1_0_7_0_1 - 2.95809523809522*G0_1_0_8_0_0 - 3.89142857142855*G0_1_0_8_0_1 - 0.754285714285717*G0_1_0_9_0_0 + 0.582857142857141*G0_1_0_9_0_1 + 0.359999999999996*G0_1_0_10_1_0 + 0.359999999999997*G0_1_0_10_1_1 + 2.19619047619046*G0_1_0_11_1_0 + 0.569523809523808*G0_1_0_12_1_1 - 0.287619047619043*G0_1_0_13_1_0 + 3.89142857142855*G0_1_0_13_1_1 - 0.0304761904761913*G0_1_0_14_1_0 - 2.58285714285713*G0_1_0_14_1_1 + 1.04190476190476*G0_1_0_15_1_0 - 0.556190476190467*G0_1_0_15_1_1 + 0.0304761904761909*G0_1_0_16_1_0 - 0.373333333333338*G0_1_0_16_1_1 + 0.40190476190476*G0_1_0_17_1_0 + 1.99999999999999*G0_1_0_17_1_1 - 2.95809523809522*G0_1_0_18_1_0 - 3.89142857142855*G0_1_0_18_1_1 - 0.754285714285717*G0_1_0_19_1_0 + 0.582857142857141*G0_1_0_19_1_1 + 0.344126984126982*G0_1_1_0_0_0 + 0.344126984126982*G0_1_1_0_0_1 + 2.50158730158729*G0_1_1_1_0_0 + 1.39301587301587*G0_1_1_2_0_1 + 0.662857142857138*G0_1_1_3_0_0 + 6.34285714285711*G0_1_1_3_0_1 - 0.365714285714286*G0_1_1_4_0_0 - 4.93714285714283*G0_1_1_4_0_1 - 0.640000000000002*G0_1_1_5_0_0 + 0.365714285714286*G0_1_1_6_0_0 - 1.73714285714285*G0_1_1_6_0_1 - 3.38285714285713*G0_1_1_7_0_0 - 4.02285714285714*G0_1_1_7_0_1 + 0.537142857142867*G0_1_1_8_0_0 - 6.34285714285711*G0_1_1_8_0_1 - 0.0228571428571369*G0_1_1_9_0_0 + 8.95999999999997*G0_1_1_9_0_1 + 0.344126984126982*G0_1_1_10_1_0 + 0.344126984126982*G0_1_1_10_1_1 + 2.50158730158729*G0_1_1_11_1_0 + 1.39301587301587*G0_1_1_12_1_1 + 0.662857142857138*G0_1_1_13_1_0 + 6.34285714285711*G0_1_1_13_1_1 - 0.365714285714286*G0_1_1_14_1_0 - 4.93714285714283*G0_1_1_14_1_1 - 0.640000000000002*G0_1_1_15_1_0 + 0.365714285714286*G0_1_1_16_1_0 - 1.73714285714285*G0_1_1_16_1_1 - 3.38285714285713*G0_1_1_17_1_0 - 4.02285714285714*G0_1_1_17_1_1 + 0.537142857142867*G0_1_1_18_1_0 - 6.34285714285711*G0_1_1_18_1_1 - 0.0228571428571369*G0_1_1_19_1_0 + 8.95999999999997*G0_1_1_19_1_1; + A[370] = A[312] + 0.609523809523804*G0_0_1_0_0_0 + 0.609523809523805*G0_0_1_0_0_1 + 0.639999999999999*G0_0_1_1_0_0 - 0.579047619047614*G0_0_1_2_0_1 + 0.39619047619047*G0_0_1_3_0_0 + 0.868571428571427*G0_0_1_3_0_1 + 0.0304761904761918*G0_0_1_4_0_0 + 0.777142857142849*G0_0_1_4_0_1 - 0.761904761904765*G0_0_1_5_0_0 - 2.2095238095238*G0_0_1_5_0_1 - 0.0304761904761918*G0_0_1_6_0_0 + 2.17904761904761*G0_0_1_6_0_1 + 0.609523809523806*G0_0_1_7_0_0 + 2.05714285714284*G0_0_1_7_0_1 - 1.85904761904761*G0_0_1_8_0_0 - 0.868571428571428*G0_0_1_8_0_1 + 0.365714285714294*G0_0_1_9_0_0 - 2.83428571428569*G0_0_1_9_0_1 + 0.609523809523804*G0_0_1_10_1_0 + 0.609523809523805*G0_0_1_10_1_1 + 0.639999999999999*G0_0_1_11_1_0 - 0.579047619047614*G0_0_1_12_1_1 + 0.39619047619047*G0_0_1_13_1_0 + 0.868571428571427*G0_0_1_13_1_1 + 0.0304761904761918*G0_0_1_14_1_0 + 0.777142857142849*G0_0_1_14_1_1 - 0.761904761904765*G0_0_1_15_1_0 - 2.2095238095238*G0_0_1_15_1_1 - 0.0304761904761918*G0_0_1_16_1_0 + 2.17904761904761*G0_0_1_16_1_1 + 0.609523809523806*G0_0_1_17_1_0 + 2.05714285714284*G0_0_1_17_1_1 - 1.85904761904761*G0_0_1_18_1_0 - 0.868571428571428*G0_0_1_18_1_1 + 0.365714285714294*G0_0_1_19_1_0 - 2.83428571428569*G0_0_1_19_1_1 - 0.609523809523804*G0_1_0_0_0_0 - 0.609523809523804*G0_1_0_0_0_1 - 0.639999999999999*G0_1_0_1_0_0 + 0.579047619047614*G0_1_0_2_0_1 - 0.39619047619047*G0_1_0_3_0_0 - 0.868571428571427*G0_1_0_3_0_1 - 0.0304761904761917*G0_1_0_4_0_0 - 0.777142857142849*G0_1_0_4_0_1 + 0.761904761904766*G0_1_0_5_0_0 + 2.2095238095238*G0_1_0_5_0_1 + 0.0304761904761918*G0_1_0_6_0_0 - 2.17904761904761*G0_1_0_6_0_1 - 0.609523809523806*G0_1_0_7_0_0 - 2.05714285714284*G0_1_0_7_0_1 + 1.85904761904761*G0_1_0_8_0_0 + 0.868571428571428*G0_1_0_8_0_1 - 0.365714285714295*G0_1_0_9_0_0 + 2.83428571428569*G0_1_0_9_0_1 - 0.609523809523804*G0_1_0_10_1_0 - 0.609523809523804*G0_1_0_10_1_1 - 0.639999999999999*G0_1_0_11_1_0 + 0.579047619047614*G0_1_0_12_1_1 - 0.39619047619047*G0_1_0_13_1_0 - 0.868571428571427*G0_1_0_13_1_1 - 0.0304761904761917*G0_1_0_14_1_0 - 0.777142857142849*G0_1_0_14_1_1 + 0.761904761904766*G0_1_0_15_1_0 + 2.2095238095238*G0_1_0_15_1_1 + 0.0304761904761918*G0_1_0_16_1_0 - 2.17904761904761*G0_1_0_16_1_1 - 0.609523809523806*G0_1_0_17_1_0 - 2.05714285714284*G0_1_0_17_1_1 + 1.85904761904761*G0_1_0_18_1_0 + 0.868571428571428*G0_1_0_18_1_1 - 0.365714285714295*G0_1_0_19_1_0 + 2.83428571428569*G0_1_0_19_1_1; + A[652] = A[309] - 2.68359788359788*G0_0_0_0_0_0 - 2.68359788359788*G0_0_0_0_0_1 + 1.71851851851851*G0_0_0_1_0_0 - 1.01417989417989*G0_0_0_2_0_1 + 1.38666666666666*G0_0_0_3_0_0 + 2.92063492063491*G0_0_0_3_0_1 - 3.36761904761903*G0_0_0_4_0_0 - 2.16888888888888*G0_0_0_4_0_1 - 3.21523809523808*G0_0_0_5_0_0 + 2.54984126984126*G0_0_0_5_0_1 + 3.36761904761903*G0_0_0_6_0_0 + 1.1479365079365*G0_0_0_6_0_1 + 4.45968253968252*G0_0_0_7_0_0 - 1.30539682539682*G0_0_0_7_0_1 - 3.49460317460316*G0_0_0_8_0_0 - 2.92063492063491*G0_0_0_8_0_1 + 1.82857142857142*G0_0_0_9_0_0 + 3.4742857142857*G0_0_0_9_0_1 - 2.68359788359788*G0_0_0_10_1_0 - 2.68359788359788*G0_0_0_10_1_1 + 1.71851851851851*G0_0_0_11_1_0 - 1.01417989417989*G0_0_0_12_1_1 + 1.38666666666666*G0_0_0_13_1_0 + 2.92063492063491*G0_0_0_13_1_1 - 3.36761904761903*G0_0_0_14_1_0 - 2.16888888888888*G0_0_0_14_1_1 - 3.21523809523808*G0_0_0_15_1_0 + 2.54984126984126*G0_0_0_15_1_1 + 3.36761904761903*G0_0_0_16_1_0 + 1.1479365079365*G0_0_0_16_1_1 + 4.45968253968252*G0_0_0_17_1_0 - 1.30539682539682*G0_0_0_17_1_1 - 3.49460317460316*G0_0_0_18_1_0 - 2.92063492063491*G0_0_0_18_1_1 + 1.82857142857142*G0_0_0_19_1_0 + 3.4742857142857*G0_0_0_19_1_1 + 0.50285714285714*G0_0_1_1_0_0 - 0.502857142857141*G0_0_1_2_0_1 + 2.62857142857142*G0_0_1_3_0_0 + 3.13142857142856*G0_0_1_3_0_1 - 3.13142857142856*G0_0_1_4_0_0 - 2.62857142857141*G0_0_1_4_0_1 + 1.62285714285714*G0_0_1_5_0_0 + 1.62285714285713*G0_0_1_5_0_1 + 3.13142857142856*G0_0_1_6_0_0 - 1.11999999999999*G0_0_1_6_0_1 - 1.62285714285714*G0_0_1_7_0_0 - 1.62285714285713*G0_0_1_7_0_1 + 1.12*G0_0_1_8_0_0 - 3.13142857142856*G0_0_1_8_0_1 - 4.25142857142855*G0_0_1_9_0_0 + 4.25142857142855*G0_0_1_9_0_1 + 0.50285714285714*G0_0_1_11_1_0 - 0.502857142857141*G0_0_1_12_1_1 + 2.62857142857142*G0_0_1_13_1_0 + 3.13142857142856*G0_0_1_13_1_1 - 3.13142857142856*G0_0_1_14_1_0 - 2.62857142857141*G0_0_1_14_1_1 + 1.62285714285714*G0_0_1_15_1_0 + 1.62285714285713*G0_0_1_15_1_1 + 3.13142857142856*G0_0_1_16_1_0 - 1.11999999999999*G0_0_1_16_1_1 - 1.62285714285714*G0_0_1_17_1_0 - 1.62285714285713*G0_0_1_17_1_1 + 1.12*G0_0_1_18_1_0 - 3.13142857142856*G0_0_1_18_1_1 - 4.25142857142855*G0_0_1_19_1_0 + 4.25142857142855*G0_0_1_19_1_1 + 1.51873015873015*G0_1_0_1_0_0 - 1.51873015873015*G0_1_0_2_0_1 + 1.43492063492063*G0_1_0_3_0_0 + 2.95365079365078*G0_1_0_3_0_1 - 2.95365079365078*G0_1_0_4_0_0 - 1.43492063492063*G0_1_0_4_0_1 - 1.60253968253968*G0_1_0_5_0_0 - 1.60253968253967*G0_1_0_5_0_1 + 2.95365079365078*G0_1_0_6_0_0 + 3.12126984126982*G0_1_0_6_0_1 + 1.60253968253968*G0_1_0_7_0_0 + 1.60253968253967*G0_1_0_7_0_1 - 3.12126984126983*G0_1_0_8_0_0 - 2.95365079365078*G0_1_0_8_0_1 + 0.167619047619047*G0_1_0_9_0_0 - 0.16761904761904*G0_1_0_9_0_1 + 1.51873015873015*G0_1_0_11_1_0 - 1.51873015873015*G0_1_0_12_1_1 + 1.43492063492063*G0_1_0_13_1_0 + 2.95365079365078*G0_1_0_13_1_1 - 2.95365079365078*G0_1_0_14_1_0 - 1.43492063492063*G0_1_0_14_1_1 - 1.60253968253968*G0_1_0_15_1_0 - 1.60253968253967*G0_1_0_15_1_1 + 2.95365079365078*G0_1_0_16_1_0 + 3.12126984126982*G0_1_0_16_1_1 + 1.60253968253968*G0_1_0_17_1_0 + 1.60253968253967*G0_1_0_17_1_1 - 3.12126984126983*G0_1_0_18_1_0 - 2.95365079365078*G0_1_0_18_1_1 + 0.167619047619047*G0_1_0_19_1_0 - 0.16761904761904*G0_1_0_19_1_1 + 2.68359788359787*G0_1_1_0_0_0 + 2.68359788359787*G0_1_1_0_0_1 + 1.01417989417989*G0_1_1_1_0_0 - 1.71851851851851*G0_1_1_2_0_1 + 2.16888888888888*G0_1_1_3_0_0 + 3.36761904761902*G0_1_1_3_0_1 - 2.92063492063491*G0_1_1_4_0_0 - 1.38666666666666*G0_1_1_4_0_1 + 1.30539682539682*G0_1_1_5_0_0 - 4.45968253968251*G0_1_1_5_0_1 + 2.92063492063491*G0_1_1_6_0_0 + 3.49460317460316*G0_1_1_6_0_1 - 2.54984126984126*G0_1_1_7_0_0 + 3.21523809523808*G0_1_1_7_0_1 - 1.1479365079365*G0_1_1_8_0_0 - 3.36761904761903*G0_1_1_8_0_1 - 3.4742857142857*G0_1_1_9_0_0 - 1.82857142857142*G0_1_1_9_0_1 + 2.68359788359787*G0_1_1_10_1_0 + 2.68359788359787*G0_1_1_10_1_1 + 1.01417989417989*G0_1_1_11_1_0 - 1.71851851851851*G0_1_1_12_1_1 + 2.16888888888888*G0_1_1_13_1_0 + 3.36761904761902*G0_1_1_13_1_1 - 2.92063492063491*G0_1_1_14_1_0 - 1.38666666666666*G0_1_1_14_1_1 + 1.30539682539682*G0_1_1_15_1_0 - 4.45968253968251*G0_1_1_15_1_1 + 2.92063492063491*G0_1_1_16_1_0 + 3.49460317460316*G0_1_1_16_1_1 - 2.54984126984126*G0_1_1_17_1_0 + 3.21523809523808*G0_1_1_17_1_1 - 1.1479365079365*G0_1_1_18_1_0 - 3.36761904761903*G0_1_1_18_1_1 - 3.4742857142857*G0_1_1_19_1_0 - 1.82857142857142*G0_1_1_19_1_1; + A[187] = A[652]; + A[216] = A[652] - 0.863492063492065*G0_0_1_0_0_0 - 0.863492063492064*G0_0_1_0_0_1 + 0.548571428571426*G0_0_1_1_0_0 - 0.467301587301586*G0_0_1_2_0_1 - 0.944761904761899*G0_0_1_3_0_0 - 0.238730158730158*G0_0_1_3_0_1 - 0.0609523809523846*G0_0_1_4_0_0 + 0.248888888888886*G0_0_1_4_0_1 - 4.1142857142857*G0_0_1_5_0_0 - 1.19365079365078*G0_0_1_5_0_1 + 0.0609523809523846*G0_0_1_6_0_0 + 2.52444444444443*G0_0_1_6_0_1 + 2.03174603174603*G0_0_1_7_0_0 - 0.888888888888889*G0_0_1_7_0_1 - 1.71682539682539*G0_0_1_8_0_0 + 0.23873015873016*G0_0_1_8_0_1 + 5.0590476190476*G0_0_1_9_0_0 + 0.640000000000001*G0_0_1_9_0_1 - 0.863492063492065*G0_0_1_10_1_0 - 0.863492063492064*G0_0_1_10_1_1 + 0.548571428571426*G0_0_1_11_1_0 - 0.467301587301586*G0_0_1_12_1_1 - 0.944761904761899*G0_0_1_13_1_0 - 0.238730158730158*G0_0_1_13_1_1 - 0.0609523809523846*G0_0_1_14_1_0 + 0.248888888888886*G0_0_1_14_1_1 - 4.1142857142857*G0_0_1_15_1_0 - 1.19365079365078*G0_0_1_15_1_1 + 0.0609523809523846*G0_0_1_16_1_0 + 2.52444444444443*G0_0_1_16_1_1 + 2.03174603174603*G0_0_1_17_1_0 - 0.888888888888889*G0_0_1_17_1_1 - 1.71682539682539*G0_0_1_18_1_0 + 0.23873015873016*G0_0_1_18_1_1 + 5.0590476190476*G0_0_1_19_1_0 + 0.640000000000001*G0_0_1_19_1_1 + 0.863492063492065*G0_1_0_0_0_0 + 0.863492063492064*G0_1_0_0_0_1 - 0.548571428571426*G0_1_0_1_0_0 + 0.467301587301587*G0_1_0_2_0_1 + 0.944761904761899*G0_1_0_3_0_0 + 0.238730158730158*G0_1_0_3_0_1 + 0.0609523809523851*G0_1_0_4_0_0 - 0.248888888888886*G0_1_0_4_0_1 + 4.1142857142857*G0_1_0_5_0_0 + 1.19365079365078*G0_1_0_5_0_1 - 0.0609523809523846*G0_1_0_6_0_0 - 2.52444444444443*G0_1_0_6_0_1 - 2.03174603174603*G0_1_0_7_0_0 + 0.888888888888889*G0_1_0_7_0_1 + 1.71682539682539*G0_1_0_8_0_0 - 0.238730158730159*G0_1_0_8_0_1 - 5.0590476190476*G0_1_0_9_0_0 - 0.640000000000001*G0_1_0_9_0_1 + 0.863492063492065*G0_1_0_10_1_0 + 0.863492063492064*G0_1_0_10_1_1 - 0.548571428571426*G0_1_0_11_1_0 + 0.467301587301587*G0_1_0_12_1_1 + 0.944761904761899*G0_1_0_13_1_0 + 0.238730158730158*G0_1_0_13_1_1 + 0.0609523809523851*G0_1_0_14_1_0 - 0.248888888888886*G0_1_0_14_1_1 + 4.1142857142857*G0_1_0_15_1_0 + 1.19365079365078*G0_1_0_15_1_1 - 0.0609523809523846*G0_1_0_16_1_0 - 2.52444444444443*G0_1_0_16_1_1 - 2.03174603174603*G0_1_0_17_1_0 + 0.888888888888889*G0_1_0_17_1_1 + 1.71682539682539*G0_1_0_18_1_0 - 0.238730158730159*G0_1_0_18_1_1 - 5.0590476190476*G0_1_0_19_1_0 - 0.640000000000001*G0_1_0_19_1_1; + A[832] = A[367]; + A[274] = A[277] + 0.365714285714285*G0_0_0_0_0_0 + 0.365714285714285*G0_0_0_0_0_1 - 0.121904761904762*G0_0_0_1_0_0 - 0.0914285714285649*G0_0_0_3_0_0 - 0.0457142857142847*G0_0_0_3_0_1 - 0.167619047619042*G0_0_0_4_0_1 - 0.0914285714285707*G0_0_0_5_0_0 - 0.533333333333334*G0_0_0_5_0_1 + 0.167619047619051*G0_0_0_6_0_1 - 0.853333333333329*G0_0_0_7_0_0 - 0.411428571428566*G0_0_0_7_0_1 + 0.609523809523806*G0_0_0_8_0_0 + 0.0457142857142847*G0_0_0_8_0_1 + 0.182857142857136*G0_0_0_9_0_0 + 0.579047619047609*G0_0_0_9_0_1 + 0.365714285714285*G0_0_0_10_1_0 + 0.365714285714285*G0_0_0_10_1_1 - 0.121904761904762*G0_0_0_11_1_0 - 0.0914285714285649*G0_0_0_13_1_0 - 0.0457142857142847*G0_0_0_13_1_1 - 0.167619047619042*G0_0_0_14_1_1 - 0.0914285714285707*G0_0_0_15_1_0 - 0.533333333333334*G0_0_0_15_1_1 + 0.167619047619051*G0_0_0_16_1_1 - 0.853333333333329*G0_0_0_17_1_0 - 0.411428571428566*G0_0_0_17_1_1 + 0.609523809523806*G0_0_0_18_1_0 + 0.0457142857142847*G0_0_0_18_1_1 + 0.182857142857136*G0_0_0_19_1_0 + 0.579047619047609*G0_0_0_19_1_1 - 1.3815873015873*G0_0_1_0_0_0 - 1.3815873015873*G0_0_1_0_0_1 + 0.223492063492064*G0_0_1_1_0_0 + 0.421587301587298*G0_0_1_2_0_1 - 0.457142857142853*G0_0_1_3_0_0 - 0.220952380952375*G0_0_1_3_0_1 + 0.243809523809519*G0_0_1_4_0_0 - 0.19047619047619*G0_0_1_4_0_1 - 0.121904761904765*G0_0_1_5_0_0 + 2.26285714285714*G0_0_1_5_0_1 - 0.243809523809519*G0_0_1_6_0_0 - 1.30285714285714*G0_0_1_6_0_1 + 2.13333333333333*G0_0_1_7_0_0 - 0.25142857142857*G0_0_1_7_0_1 - 0.975238095238094*G0_0_1_8_0_0 + 0.220952380952375*G0_0_1_8_0_1 + 0.579047619047617*G0_0_1_9_0_0 + 0.441904761904761*G0_0_1_9_0_1 - 1.3815873015873*G0_0_1_10_1_0 - 1.3815873015873*G0_0_1_10_1_1 + 0.223492063492064*G0_0_1_11_1_0 + 0.421587301587298*G0_0_1_12_1_1 - 0.457142857142853*G0_0_1_13_1_0 - 0.220952380952375*G0_0_1_13_1_1 + 0.243809523809519*G0_0_1_14_1_0 - 0.19047619047619*G0_0_1_14_1_1 - 0.121904761904765*G0_0_1_15_1_0 + 2.26285714285714*G0_0_1_15_1_1 - 0.243809523809519*G0_0_1_16_1_0 - 1.30285714285714*G0_0_1_16_1_1 + 2.13333333333333*G0_0_1_17_1_0 - 0.25142857142857*G0_0_1_17_1_1 - 0.975238095238094*G0_0_1_18_1_0 + 0.220952380952375*G0_0_1_18_1_1 + 0.579047619047617*G0_0_1_19_1_0 + 0.441904761904761*G0_0_1_19_1_1 - 0.269206349206347*G0_1_0_0_0_0 - 0.269206349206347*G0_1_0_0_0_1 - 0.00507936507936571*G0_1_0_1_0_0 + 0.177777777777774*G0_1_0_2_0_1 - 0.33523809523809*G0_1_0_3_0_0 - 0.106666666666666*G0_1_0_3_0_1 + 0.0761904761904728*G0_1_0_4_0_0 - 0.335238095238091*G0_1_0_4_0_1 - 0.487619047619046*G0_1_0_5_0_0 + 0.36571428571428*G0_1_0_5_0_1 - 0.076190476190473*G0_1_0_6_0_0 - 0.274285714285708*G0_1_0_6_0_1 - 0.853333333333326*G0_1_0_7_0_1 + 0.274285714285713*G0_1_0_8_0_0 + 0.106666666666666*G0_1_0_8_0_1 + 0.822857142857137*G0_1_0_9_0_0 + 1.18857142857142*G0_1_0_9_0_1 - 0.269206349206347*G0_1_0_10_1_0 - 0.269206349206347*G0_1_0_10_1_1 - 0.00507936507936571*G0_1_0_11_1_0 + 0.177777777777774*G0_1_0_12_1_1 - 0.33523809523809*G0_1_0_13_1_0 - 0.106666666666666*G0_1_0_13_1_1 + 0.0761904761904728*G0_1_0_14_1_0 - 0.335238095238091*G0_1_0_14_1_1 - 0.487619047619046*G0_1_0_15_1_0 + 0.36571428571428*G0_1_0_15_1_1 - 0.076190476190473*G0_1_0_16_1_0 - 0.274285714285708*G0_1_0_16_1_1 - 0.853333333333326*G0_1_0_17_1_1 + 0.274285714285713*G0_1_0_18_1_0 + 0.106666666666666*G0_1_0_18_1_1 + 0.822857142857137*G0_1_0_19_1_0 + 1.18857142857142*G0_1_0_19_1_1 + 1.18349206349206*G0_1_1_0_0_0 + 1.18349206349206*G0_1_1_0_0_1 + 0.172698412698412*G0_1_1_1_0_0 - 0.299682539682539*G0_1_1_2_0_1 - 0.891428571428567*G0_1_1_3_0_0 - 0.106666666666668*G0_1_1_3_0_1 + 0.297142857142855*G0_1_1_4_0_0 - 0.0152380952380933*G0_1_1_4_0_1 - 0.982857142857142*G0_1_1_5_0_0 - 2.86476190476189*G0_1_1_5_0_1 - 0.297142857142856*G0_1_1_6_0_0 + 1.98095238095237*G0_1_1_6_0_1 - 1.04380952380952*G0_1_1_7_0_0 + 0.838095238095233*G0_1_1_7_0_1 - 0.312380952380953*G0_1_1_8_0_0 + 0.106666666666669*G0_1_1_8_0_1 + 1.87428571428571*G0_1_1_9_0_0 - 0.822857142857141*G0_1_1_9_0_1 + 1.18349206349206*G0_1_1_10_1_0 + 1.18349206349206*G0_1_1_10_1_1 + 0.172698412698412*G0_1_1_11_1_0 - 0.299682539682539*G0_1_1_12_1_1 - 0.891428571428567*G0_1_1_13_1_0 - 0.106666666666668*G0_1_1_13_1_1 + 0.297142857142855*G0_1_1_14_1_0 - 0.0152380952380933*G0_1_1_14_1_1 - 0.982857142857142*G0_1_1_15_1_0 - 2.86476190476189*G0_1_1_15_1_1 - 0.297142857142856*G0_1_1_16_1_0 + 1.98095238095237*G0_1_1_16_1_1 - 1.04380952380952*G0_1_1_17_1_0 + 0.838095238095233*G0_1_1_17_1_1 - 0.312380952380953*G0_1_1_18_1_0 + 0.106666666666669*G0_1_1_18_1_1 + 1.87428571428571*G0_1_1_19_1_0 - 0.822857142857141*G0_1_1_19_1_1; + A[310] = A[775]; + A[745] = A[309] - 0.863492063492056*G0_0_1_0_0_0 - 0.863492063492056*G0_0_1_0_0_1 - 0.467301587301586*G0_0_1_1_0_0 + 0.548571428571424*G0_0_1_2_0_1 + 0.248888888888888*G0_0_1_3_0_0 - 0.0609523809523806*G0_0_1_3_0_1 - 0.238730158730159*G0_0_1_4_0_0 - 0.944761904761899*G0_0_1_4_0_1 - 0.888888888888884*G0_0_1_5_0_0 + 2.03174603174602*G0_0_1_5_0_1 + 0.238730158730159*G0_0_1_6_0_0 - 1.71682539682538*G0_0_1_6_0_1 - 1.19365079365079*G0_0_1_7_0_0 - 4.11428571428569*G0_0_1_7_0_1 + 2.52444444444443*G0_0_1_8_0_0 + 0.0609523809523815*G0_0_1_8_0_1 + 0.639999999999996*G0_0_1_9_0_0 + 5.05904761904759*G0_0_1_9_0_1 - 0.863492063492056*G0_0_1_10_1_0 - 0.863492063492056*G0_0_1_10_1_1 - 0.467301587301586*G0_0_1_11_1_0 + 0.548571428571424*G0_0_1_12_1_1 + 0.248888888888888*G0_0_1_13_1_0 - 0.0609523809523806*G0_0_1_13_1_1 - 0.238730158730159*G0_0_1_14_1_0 - 0.944761904761899*G0_0_1_14_1_1 - 0.888888888888884*G0_0_1_15_1_0 + 2.03174603174602*G0_0_1_15_1_1 + 0.238730158730159*G0_0_1_16_1_0 - 1.71682539682538*G0_0_1_16_1_1 - 1.19365079365079*G0_0_1_17_1_0 - 4.11428571428569*G0_0_1_17_1_1 + 2.52444444444443*G0_0_1_18_1_0 + 0.0609523809523815*G0_0_1_18_1_1 + 0.639999999999996*G0_0_1_19_1_0 + 5.05904761904759*G0_0_1_19_1_1 + 0.863492063492056*G0_1_0_0_0_0 + 0.863492063492056*G0_1_0_0_0_1 + 0.467301587301586*G0_1_0_1_0_0 - 0.548571428571424*G0_1_0_2_0_1 - 0.248888888888888*G0_1_0_3_0_0 + 0.0609523809523806*G0_1_0_3_0_1 + 0.238730158730159*G0_1_0_4_0_0 + 0.944761904761899*G0_1_0_4_0_1 + 0.888888888888884*G0_1_0_5_0_0 - 2.03174603174602*G0_1_0_5_0_1 - 0.238730158730159*G0_1_0_6_0_0 + 1.71682539682538*G0_1_0_6_0_1 + 1.19365079365079*G0_1_0_7_0_0 + 4.11428571428569*G0_1_0_7_0_1 - 2.52444444444443*G0_1_0_8_0_0 - 0.0609523809523815*G0_1_0_8_0_1 - 0.639999999999996*G0_1_0_9_0_0 - 5.05904761904759*G0_1_0_9_0_1 + 0.863492063492056*G0_1_0_10_1_0 + 0.863492063492056*G0_1_0_10_1_1 + 0.467301587301586*G0_1_0_11_1_0 - 0.548571428571424*G0_1_0_12_1_1 - 0.248888888888888*G0_1_0_13_1_0 + 0.0609523809523806*G0_1_0_13_1_1 + 0.238730158730159*G0_1_0_14_1_0 + 0.944761904761899*G0_1_0_14_1_1 + 0.888888888888884*G0_1_0_15_1_0 - 2.03174603174602*G0_1_0_15_1_1 - 0.238730158730159*G0_1_0_16_1_0 + 1.71682539682538*G0_1_0_16_1_1 + 1.19365079365079*G0_1_0_17_1_0 + 4.11428571428569*G0_1_0_17_1_1 - 2.52444444444443*G0_1_0_18_1_0 - 0.0609523809523815*G0_1_0_18_1_1 - 0.639999999999996*G0_1_0_19_1_0 - 5.05904761904759*G0_1_0_19_1_1; + A[364] = A[132] + 0.335238095238092*G0_0_1_1_0_0 - 0.335238095238096*G0_0_1_2_0_1 + 0.380952380952382*G0_0_1_3_0_0 + 0.716190476190472*G0_0_1_3_0_1 - 0.716190476190475*G0_0_1_4_0_0 - 0.380952380952376*G0_0_1_4_0_1 - 0.289523809523802*G0_0_1_5_0_0 - 0.28952380952381*G0_0_1_5_0_1 + 0.716190476190475*G0_0_1_6_0_0 + 0.624761904761903*G0_0_1_6_0_1 + 0.289523809523807*G0_0_1_7_0_0 + 0.289523809523816*G0_0_1_7_0_1 - 0.624761904761901*G0_0_1_8_0_0 - 0.716190476190472*G0_0_1_8_0_1 - 0.0914285714285796*G0_0_1_9_0_0 + 0.091428571428561*G0_0_1_9_0_1 + 0.335238095238092*G0_0_1_11_1_0 - 0.335238095238096*G0_0_1_12_1_1 + 0.380952380952382*G0_0_1_13_1_0 + 0.716190476190472*G0_0_1_13_1_1 - 0.716190476190475*G0_0_1_14_1_0 - 0.380952380952376*G0_0_1_14_1_1 - 0.289523809523802*G0_0_1_15_1_0 - 0.28952380952381*G0_0_1_15_1_1 + 0.716190476190475*G0_0_1_16_1_0 + 0.624761904761903*G0_0_1_16_1_1 + 0.289523809523807*G0_0_1_17_1_0 + 0.289523809523816*G0_0_1_17_1_1 - 0.624761904761901*G0_0_1_18_1_0 - 0.716190476190472*G0_0_1_18_1_1 - 0.0914285714285796*G0_0_1_19_1_0 + 0.091428571428561*G0_0_1_19_1_1 - 0.335238095238092*G0_1_0_1_0_0 + 0.335238095238096*G0_1_0_2_0_1 - 0.380952380952381*G0_1_0_3_0_0 - 0.716190476190471*G0_1_0_3_0_1 + 0.716190476190475*G0_1_0_4_0_0 + 0.380952380952376*G0_1_0_4_0_1 + 0.289523809523802*G0_1_0_5_0_0 + 0.28952380952381*G0_1_0_5_0_1 - 0.716190476190475*G0_1_0_6_0_0 - 0.624761904761903*G0_1_0_6_0_1 - 0.289523809523807*G0_1_0_7_0_0 - 0.289523809523816*G0_1_0_7_0_1 + 0.624761904761901*G0_1_0_8_0_0 + 0.716190476190472*G0_1_0_8_0_1 + 0.0914285714285792*G0_1_0_9_0_0 - 0.0914285714285614*G0_1_0_9_0_1 - 0.335238095238092*G0_1_0_11_1_0 + 0.335238095238096*G0_1_0_12_1_1 - 0.380952380952381*G0_1_0_13_1_0 - 0.716190476190471*G0_1_0_13_1_1 + 0.716190476190475*G0_1_0_14_1_0 + 0.380952380952376*G0_1_0_14_1_1 + 0.289523809523802*G0_1_0_15_1_0 + 0.28952380952381*G0_1_0_15_1_1 - 0.716190476190475*G0_1_0_16_1_0 - 0.624761904761903*G0_1_0_16_1_1 - 0.289523809523807*G0_1_0_17_1_0 - 0.289523809523816*G0_1_0_17_1_1 + 0.624761904761901*G0_1_0_18_1_0 + 0.716190476190472*G0_1_0_18_1_1 + 0.0914285714285792*G0_1_0_19_1_0 - 0.0914285714285614*G0_1_0_19_1_1; + A[687] = A[367] + 0.609523809523809*G0_0_1_0_0_0 + 0.609523809523809*G0_0_1_0_0_1 - 0.579047619047615*G0_0_1_1_0_0 + 0.639999999999998*G0_0_1_2_0_1 + 0.777142857142854*G0_0_1_3_0_0 + 0.0304761904761931*G0_0_1_3_0_1 + 0.868571428571428*G0_0_1_4_0_0 + 0.396190476190475*G0_0_1_4_0_1 + 2.05714285714285*G0_0_1_5_0_0 + 0.609523809523803*G0_0_1_5_0_1 - 0.868571428571428*G0_0_1_6_0_0 - 1.85904761904761*G0_0_1_6_0_1 - 2.2095238095238*G0_0_1_7_0_0 - 0.761904761904755*G0_0_1_7_0_1 + 2.17904761904761*G0_0_1_8_0_0 - 0.0304761904761934*G0_0_1_8_0_1 - 2.8342857142857*G0_0_1_9_0_0 + 0.36571428571428*G0_0_1_9_0_1 + 0.609523809523809*G0_0_1_10_1_0 + 0.609523809523809*G0_0_1_10_1_1 - 0.579047619047615*G0_0_1_11_1_0 + 0.639999999999998*G0_0_1_12_1_1 + 0.777142857142854*G0_0_1_13_1_0 + 0.0304761904761931*G0_0_1_13_1_1 + 0.868571428571428*G0_0_1_14_1_0 + 0.396190476190475*G0_0_1_14_1_1 + 2.05714285714285*G0_0_1_15_1_0 + 0.609523809523803*G0_0_1_15_1_1 - 0.868571428571428*G0_0_1_16_1_0 - 1.85904761904761*G0_0_1_16_1_1 - 2.2095238095238*G0_0_1_17_1_0 - 0.761904761904755*G0_0_1_17_1_1 + 2.17904761904761*G0_0_1_18_1_0 - 0.0304761904761934*G0_0_1_18_1_1 - 2.8342857142857*G0_0_1_19_1_0 + 0.36571428571428*G0_0_1_19_1_1 - 0.609523809523809*G0_1_0_0_0_0 - 0.609523809523809*G0_1_0_0_0_1 + 0.579047619047615*G0_1_0_1_0_0 - 0.639999999999998*G0_1_0_2_0_1 - 0.777142857142853*G0_1_0_3_0_0 - 0.030476190476193*G0_1_0_3_0_1 - 0.868571428571428*G0_1_0_4_0_0 - 0.396190476190476*G0_1_0_4_0_1 - 2.05714285714285*G0_1_0_5_0_0 - 0.609523809523803*G0_1_0_5_0_1 + 0.868571428571428*G0_1_0_6_0_0 + 1.85904761904761*G0_1_0_6_0_1 + 2.2095238095238*G0_1_0_7_0_0 + 0.761904761904755*G0_1_0_7_0_1 - 2.17904761904761*G0_1_0_8_0_0 + 0.0304761904761934*G0_1_0_8_0_1 + 2.8342857142857*G0_1_0_9_0_0 - 0.36571428571428*G0_1_0_9_0_1 - 0.609523809523809*G0_1_0_10_1_0 - 0.609523809523809*G0_1_0_10_1_1 + 0.579047619047615*G0_1_0_11_1_0 - 0.639999999999998*G0_1_0_12_1_1 - 0.777142857142853*G0_1_0_13_1_0 - 0.030476190476193*G0_1_0_13_1_1 - 0.868571428571428*G0_1_0_14_1_0 - 0.396190476190476*G0_1_0_14_1_1 - 2.05714285714285*G0_1_0_15_1_0 - 0.609523809523803*G0_1_0_15_1_1 + 0.868571428571428*G0_1_0_16_1_0 + 1.85904761904761*G0_1_0_16_1_1 + 2.2095238095238*G0_1_0_17_1_0 + 0.761904761904755*G0_1_0_17_1_1 - 2.17904761904761*G0_1_0_18_1_0 + 0.0304761904761934*G0_1_0_18_1_1 + 2.8342857142857*G0_1_0_19_1_0 - 0.36571428571428*G0_1_0_19_1_1; + A[829] = A[364]; + A[124] = A[775] + 2.31746031746031*G0_0_0_0_0_0 + 2.31746031746031*G0_0_0_0_0_1 - 2.92698412698412*G0_0_0_1_0_0 + 2.33777777777776*G0_0_0_2_0_1 - 0.559999999999991*G0_0_0_3_0_0 - 5.5238095238095*G0_0_0_3_0_1 + 8.44571428571424*G0_0_0_4_0_0 + 8.14476190476188*G0_0_0_4_0_1 + 5.13142857142854*G0_0_0_5_0_0 - 1.45904761904762*G0_0_0_5_0_1 - 8.44571428571424*G0_0_0_6_0_0 - 3.19619047619045*G0_0_0_6_0_1 - 3.28380952380951*G0_0_0_7_0_0 + 3.30666666666665*G0_0_0_7_0_1 + 3.89333333333331*G0_0_0_8_0_0 + 5.5238095238095*G0_0_0_8_0_1 - 4.57142857142855*G0_0_0_9_0_0 - 11.4514285714285*G0_0_0_9_0_1 + 2.31746031746031*G0_0_0_10_1_0 + 2.31746031746031*G0_0_0_10_1_1 - 2.92698412698412*G0_0_0_11_1_0 + 2.33777777777776*G0_0_0_12_1_1 - 0.559999999999991*G0_0_0_13_1_0 - 5.5238095238095*G0_0_0_13_1_1 + 8.44571428571424*G0_0_0_14_1_0 + 8.14476190476188*G0_0_0_14_1_1 + 5.13142857142854*G0_0_0_15_1_0 - 1.45904761904762*G0_0_0_15_1_1 - 8.44571428571424*G0_0_0_16_1_0 - 3.19619047619045*G0_0_0_16_1_1 - 3.28380952380951*G0_0_0_17_1_0 + 3.30666666666665*G0_0_0_17_1_1 + 3.89333333333331*G0_0_0_18_1_0 + 5.5238095238095*G0_0_0_18_1_1 - 4.57142857142855*G0_0_0_19_1_0 - 11.4514285714285*G0_0_0_19_1_1 - 0.314920634920632*G0_0_1_0_0_0 - 0.314920634920633*G0_0_1_0_0_1 - 2.92698412698412*G0_0_1_1_0_0 - 0.294603174603176*G0_0_1_2_0_1 + 0.352380952380951*G0_0_1_3_0_0 - 5.52380952380951*G0_0_1_3_0_1 + 1.46095238095237*G0_0_1_4_0_0 + 4.70476190476189*G0_0_1_4_0_1 + 0.779047619047616*G0_0_1_5_0_0 + 1.17333333333333*G0_0_1_5_0_1 - 1.46095238095237*G0_0_1_6_0_0 - 0.563809523809516*G0_0_1_6_0_1 + 0.260952380952382*G0_0_1_7_0_0 - 0.133333333333329*G0_0_1_7_0_1 + 2.98095238095237*G0_0_1_8_0_0 + 5.52380952380951*G0_0_1_8_0_1 - 1.13142857142857*G0_0_1_9_0_0 - 4.57142857142856*G0_0_1_9_0_1 - 0.314920634920632*G0_0_1_10_1_0 - 0.314920634920633*G0_0_1_10_1_1 - 2.92698412698412*G0_0_1_11_1_0 - 0.294603174603176*G0_0_1_12_1_1 + 0.352380952380951*G0_0_1_13_1_0 - 5.52380952380951*G0_0_1_13_1_1 + 1.46095238095237*G0_0_1_14_1_0 + 4.70476190476189*G0_0_1_14_1_1 + 0.779047619047616*G0_0_1_15_1_0 + 1.17333333333333*G0_0_1_15_1_1 - 1.46095238095237*G0_0_1_16_1_0 - 0.563809523809516*G0_0_1_16_1_1 + 0.260952380952382*G0_0_1_17_1_0 - 0.133333333333329*G0_0_1_17_1_1 + 2.98095238095237*G0_0_1_18_1_0 + 5.52380952380951*G0_0_1_18_1_1 - 1.13142857142857*G0_0_1_19_1_0 - 4.57142857142856*G0_0_1_19_1_1 - 0.314920634920632*G0_1_0_0_0_0 - 0.314920634920633*G0_1_0_0_0_1 - 2.92698412698412*G0_1_0_1_0_0 - 0.294603174603176*G0_1_0_2_0_1 + 0.35238095238095*G0_1_0_3_0_0 - 5.52380952380951*G0_1_0_3_0_1 + 1.46095238095237*G0_1_0_4_0_0 + 4.70476190476189*G0_1_0_4_0_1 + 0.779047619047615*G0_1_0_5_0_0 + 1.17333333333333*G0_1_0_5_0_1 - 1.46095238095237*G0_1_0_6_0_0 - 0.563809523809516*G0_1_0_6_0_1 + 0.260952380952382*G0_1_0_7_0_0 - 0.133333333333329*G0_1_0_7_0_1 + 2.98095238095237*G0_1_0_8_0_0 + 5.52380952380951*G0_1_0_8_0_1 - 1.13142857142857*G0_1_0_9_0_0 - 4.57142857142856*G0_1_0_9_0_1 - 0.314920634920632*G0_1_0_10_1_0 - 0.314920634920633*G0_1_0_10_1_1 - 2.92698412698412*G0_1_0_11_1_0 - 0.294603174603176*G0_1_0_12_1_1 + 0.35238095238095*G0_1_0_13_1_0 - 5.52380952380951*G0_1_0_13_1_1 + 1.46095238095237*G0_1_0_14_1_0 + 4.70476190476189*G0_1_0_14_1_1 + 0.779047619047615*G0_1_0_15_1_0 + 1.17333333333333*G0_1_0_15_1_1 - 1.46095238095237*G0_1_0_16_1_0 - 0.563809523809516*G0_1_0_16_1_1 + 0.260952380952382*G0_1_0_17_1_0 - 0.133333333333329*G0_1_0_17_1_1 + 2.98095238095237*G0_1_0_18_1_0 + 5.52380952380951*G0_1_0_18_1_1 - 1.13142857142857*G0_1_0_19_1_0 - 4.57142857142856*G0_1_0_19_1_1 - 0.60952380952381*G0_1_1_0_0_0 - 0.609523809523809*G0_1_1_0_0_1 - 0.609523809523806*G0_1_1_2_0_1 + 2.89523809523809*G0_1_1_3_0_0 + 1.06666666666666*G0_1_1_4_0_0 + 4.57142857142855*G0_1_1_4_0_1 + 1.67619047619047*G0_1_1_5_0_0 + 0.609523809523809*G0_1_1_5_0_1 - 1.06666666666666*G0_1_1_6_0_0 + 0.609523809523808*G0_1_1_6_0_1 + 3.5047619047619*G0_1_1_7_0_0 + 4.57142857142856*G0_1_1_7_0_1 - 2.8952380952381*G0_1_1_8_0_0 - 4.57142857142856*G0_1_1_9_0_0 - 9.14285714285712*G0_1_1_9_0_1 - 0.60952380952381*G0_1_1_10_1_0 - 0.609523809523809*G0_1_1_10_1_1 - 0.609523809523806*G0_1_1_12_1_1 + 2.89523809523809*G0_1_1_13_1_0 + 1.06666666666666*G0_1_1_14_1_0 + 4.57142857142855*G0_1_1_14_1_1 + 1.67619047619047*G0_1_1_15_1_0 + 0.609523809523809*G0_1_1_15_1_1 - 1.06666666666666*G0_1_1_16_1_0 + 0.609523809523808*G0_1_1_16_1_1 + 3.5047619047619*G0_1_1_17_1_0 + 4.57142857142856*G0_1_1_17_1_1 - 2.8952380952381*G0_1_1_18_1_0 - 4.57142857142856*G0_1_1_19_1_0 - 9.14285714285712*G0_1_1_19_1_1; + A[681] = A[216]; + A[280] = A[745]; + A[589] = A[124]; + A[222] = A[687]; + A[594] = A[274] + 0.020317460317466*G0_0_1_0_0_0 + 0.020317460317466*G0_0_1_0_0_1 - 0.0152380952380979*G0_0_1_1_0_0 - 0.132063492063494*G0_0_1_2_0_1 + 0.215873015873014*G0_0_1_3_0_0 + 0.0609523809523771*G0_0_1_3_0_1 - 0.195555555555557*G0_0_1_4_0_0 + 0.0761904761904763*G0_0_1_4_0_1 - 0.0482539682539682*G0_0_1_5_0_0 - 0.0812698412698503*G0_0_1_5_0_1 + 0.195555555555557*G0_0_1_6_0_0 + 0.193015873015878*G0_0_1_6_0_1 + 0.0126984126984038*G0_0_1_7_0_0 + 0.0457142857142863*G0_0_1_7_0_1 - 0.0177777777777723*G0_0_1_8_0_0 - 0.0609523809523775*G0_0_1_8_0_1 - 0.167619047619046*G0_0_1_9_0_0 - 0.121904761904762*G0_0_1_9_0_1 + 0.020317460317466*G0_0_1_10_1_0 + 0.020317460317466*G0_0_1_10_1_1 - 0.0152380952380979*G0_0_1_11_1_0 - 0.132063492063494*G0_0_1_12_1_1 + 0.215873015873014*G0_0_1_13_1_0 + 0.0609523809523771*G0_0_1_13_1_1 - 0.195555555555557*G0_0_1_14_1_0 + 0.0761904761904763*G0_0_1_14_1_1 - 0.0482539682539682*G0_0_1_15_1_0 - 0.0812698412698503*G0_0_1_15_1_1 + 0.195555555555557*G0_0_1_16_1_0 + 0.193015873015878*G0_0_1_16_1_1 + 0.0126984126984038*G0_0_1_17_1_0 + 0.0457142857142863*G0_0_1_17_1_1 - 0.0177777777777723*G0_0_1_18_1_0 - 0.0609523809523775*G0_0_1_18_1_1 - 0.167619047619046*G0_0_1_19_1_0 - 0.121904761904762*G0_0_1_19_1_1 - 0.020317460317466*G0_1_0_0_0_0 - 0.020317460317466*G0_1_0_0_0_1 + 0.0152380952380978*G0_1_0_1_0_0 + 0.132063492063494*G0_1_0_2_0_1 - 0.215873015873014*G0_1_0_3_0_0 - 0.0609523809523772*G0_1_0_3_0_1 + 0.195555555555557*G0_1_0_4_0_0 - 0.076190476190476*G0_1_0_4_0_1 + 0.0482539682539682*G0_1_0_5_0_0 + 0.0812698412698503*G0_1_0_5_0_1 - 0.195555555555557*G0_1_0_6_0_0 - 0.193015873015878*G0_1_0_6_0_1 - 0.0126984126984038*G0_1_0_7_0_0 - 0.0457142857142862*G0_1_0_7_0_1 + 0.0177777777777723*G0_1_0_8_0_0 + 0.0609523809523775*G0_1_0_8_0_1 + 0.167619047619046*G0_1_0_9_0_0 + 0.121904761904762*G0_1_0_9_0_1 - 0.020317460317466*G0_1_0_10_1_0 - 0.020317460317466*G0_1_0_10_1_1 + 0.0152380952380978*G0_1_0_11_1_0 + 0.132063492063494*G0_1_0_12_1_1 - 0.215873015873014*G0_1_0_13_1_0 - 0.0609523809523772*G0_1_0_13_1_1 + 0.195555555555557*G0_1_0_14_1_0 - 0.076190476190476*G0_1_0_14_1_1 + 0.0482539682539682*G0_1_0_15_1_0 + 0.0812698412698503*G0_1_0_15_1_1 - 0.195555555555557*G0_1_0_16_1_0 - 0.193015873015878*G0_1_0_16_1_1 - 0.0126984126984038*G0_1_0_17_1_0 - 0.0457142857142862*G0_1_0_17_1_1 + 0.0177777777777723*G0_1_0_18_1_0 + 0.0609523809523775*G0_1_0_18_1_1 + 0.167619047619046*G0_1_0_19_1_0 + 0.121904761904762*G0_1_0_19_1_1; + A[834] = A[594] - 1.94031746031745*G0_0_0_0_0_0 - 1.94031746031745*G0_0_0_0_0_1 + 0.0507936507936486*G0_0_0_1_0_0 + 0.172698412698413*G0_0_0_2_0_1 - 1.81333333333333*G0_0_0_3_0_0 - 1.4095238095238*G0_0_0_3_0_1 - 0.335238095238094*G0_0_0_4_0_0 - 0.860952380952381*G0_0_0_4_0_1 - 1.8742857142857*G0_0_0_5_0_0 + 2.33904761904761*G0_0_0_5_0_1 + 0.335238095238093*G0_0_0_6_0_0 - 0.571428571428571*G0_0_0_6_0_1 + 3.04761904761902*G0_0_0_7_0_0 - 1.16571428571428*G0_0_0_7_0_1 - 1.15809523809523*G0_0_0_8_0_0 + 1.4095238095238*G0_0_0_8_0_1 + 3.68761904761903*G0_0_0_9_0_0 + 2.02666666666666*G0_0_0_9_0_1 - 1.94031746031745*G0_0_0_10_1_0 - 1.94031746031745*G0_0_0_10_1_1 + 0.0507936507936486*G0_0_0_11_1_0 + 0.172698412698413*G0_0_0_12_1_1 - 1.81333333333333*G0_0_0_13_1_0 - 1.4095238095238*G0_0_0_13_1_1 - 0.335238095238094*G0_0_0_14_1_0 - 0.860952380952381*G0_0_0_14_1_1 - 1.8742857142857*G0_0_0_15_1_0 + 2.33904761904761*G0_0_0_15_1_1 + 0.335238095238093*G0_0_0_16_1_0 - 0.571428571428571*G0_0_0_16_1_1 + 3.04761904761902*G0_0_0_17_1_0 - 1.16571428571428*G0_0_0_17_1_1 - 1.15809523809523*G0_0_0_18_1_0 + 1.4095238095238*G0_0_0_18_1_1 + 3.68761904761903*G0_0_0_19_1_0 + 2.02666666666666*G0_0_0_19_1_1 + 1.01841269841269*G0_0_1_0_0_0 + 1.01841269841269*G0_0_1_0_0_1 - 0.698412698412695*G0_0_1_1_0_0 + 0.124444444444447*G0_0_1_2_0_1 - 1.14285714285714*G0_0_1_3_0_0 - 1.25714285714285*G0_0_1_3_0_1 + 0.0228571428571442*G0_0_1_4_0_0 - 0.685714285714285*G0_0_1_4_0_1 + 1.18857142857143*G0_0_1_5_0_0 - 0.731428571428559*G0_0_1_5_0_1 - 0.0228571428571444*G0_0_1_6_0_0 - 0.411428571428577*G0_0_1_6_0_1 - 1.91999999999999*G0_0_1_7_0_0 + 1.59999999999999*G0_0_1_8_0_0 + 1.25714285714285*G0_0_1_8_0_1 - 0.0457142857142885*G0_0_1_9_0_0 + 0.685714285714284*G0_0_1_9_0_1 + 1.01841269841269*G0_0_1_10_1_0 + 1.01841269841269*G0_0_1_10_1_1 - 0.698412698412695*G0_0_1_11_1_0 + 0.124444444444447*G0_0_1_12_1_1 - 1.14285714285714*G0_0_1_13_1_0 - 1.25714285714285*G0_0_1_13_1_1 + 0.0228571428571442*G0_0_1_14_1_0 - 0.685714285714285*G0_0_1_14_1_1 + 1.18857142857143*G0_0_1_15_1_0 - 0.731428571428559*G0_0_1_15_1_1 - 0.0228571428571444*G0_0_1_16_1_0 - 0.411428571428577*G0_0_1_16_1_1 - 1.91999999999999*G0_0_1_17_1_0 + 1.59999999999999*G0_0_1_18_1_0 + 1.25714285714285*G0_0_1_18_1_1 - 0.0457142857142885*G0_0_1_19_1_0 + 0.685714285714284*G0_0_1_19_1_1 - 0.383492063492061*G0_1_0_0_0_0 - 0.38349206349206*G0_1_0_0_0_1 + 0.0177777777777748*G0_1_0_1_0_0 - 0.39365079365079*G0_1_0_2_0_1 - 1.27238095238095*G0_1_0_3_0_0 - 1.37904761904762*G0_1_0_3_0_1 - 0.152380952380951*G0_1_0_4_0_0 + 0.365714285714283*G0_1_0_4_0_1 + 0.0228571428571444*G0_1_0_5_0_0 + 0.15238095238095*G0_1_0_6_0_0 + 0.777142857142849*G0_1_0_6_0_1 + 2.46095238095236*G0_1_0_7_0_0 + 2.48380952380951*G0_1_0_7_0_1 - 2.09523809523808*G0_1_0_8_0_0 + 1.37904761904762*G0_1_0_8_0_1 + 1.2495238095238*G0_1_0_9_0_0 - 2.84952380952379*G0_1_0_9_0_1 - 0.383492063492061*G0_1_0_10_1_0 - 0.38349206349206*G0_1_0_10_1_1 + 0.0177777777777748*G0_1_0_11_1_0 - 0.39365079365079*G0_1_0_12_1_1 - 1.27238095238095*G0_1_0_13_1_0 - 1.37904761904762*G0_1_0_13_1_1 - 0.152380952380951*G0_1_0_14_1_0 + 0.365714285714283*G0_1_0_14_1_1 + 0.0228571428571444*G0_1_0_15_1_0 + 0.15238095238095*G0_1_0_16_1_0 + 0.777142857142849*G0_1_0_16_1_1 + 2.46095238095236*G0_1_0_17_1_0 + 2.48380952380951*G0_1_0_17_1_1 - 2.09523809523808*G0_1_0_18_1_0 + 1.37904761904762*G0_1_0_18_1_1 + 1.2495238095238*G0_1_0_19_1_0 - 2.84952380952379*G0_1_0_19_1_1 + 2.57523809523808*G0_1_1_0_0_0 + 2.57523809523808*G0_1_1_0_0_1 - 0.0304761904761901*G0_1_1_1_0_0 - 1.14285714285713*G0_1_1_2_0_1 - 1.09714285714285*G0_1_1_3_0_0 - 1.02095238095238*G0_1_1_3_0_1 + 1.03619047619047*G0_1_1_4_0_1 + 1.18857142857143*G0_1_1_5_0_0 - 4.96761904761901*G0_1_1_5_0_1 + 3.53523809523807*G0_1_1_6_0_1 - 0.609523809523802*G0_1_1_7_0_0 + 5.54666666666664*G0_1_1_7_0_1 - 1.93523809523809*G0_1_1_8_0_0 + 1.02095238095238*G0_1_1_8_0_1 - 0.0914285714285725*G0_1_1_9_0_0 - 6.58285714285711*G0_1_1_9_0_1 + 2.57523809523808*G0_1_1_10_1_0 + 2.57523809523808*G0_1_1_10_1_1 - 0.0304761904761901*G0_1_1_11_1_0 - 1.14285714285713*G0_1_1_12_1_1 - 1.09714285714285*G0_1_1_13_1_0 - 1.02095238095238*G0_1_1_13_1_1 + 1.03619047619047*G0_1_1_14_1_1 + 1.18857142857143*G0_1_1_15_1_0 - 4.96761904761901*G0_1_1_15_1_1 + 3.53523809523807*G0_1_1_16_1_1 - 0.609523809523802*G0_1_1_17_1_0 + 5.54666666666664*G0_1_1_17_1_1 - 1.93523809523809*G0_1_1_18_1_0 + 1.02095238095238*G0_1_1_18_1_1 - 0.0914285714285725*G0_1_1_19_1_0 - 6.58285714285711*G0_1_1_19_1_1; + A[747] = A[834] - 1.42222222222222*G0_0_1_0_0_0 - 1.42222222222222*G0_0_1_0_0_1 + 0.731428571428568*G0_0_1_1_0_0 - 0.386031746031743*G0_0_1_2_0_1 - 0.345396825396824*G0_0_1_3_0_0 - 0.182857142857141*G0_0_1_3_0_1 + 0.020317460317462*G0_0_1_4_0_0 + 0.975238095238091*G0_0_1_4_0_1 - 1.11746031746031*G0_0_1_5_0_0 + 0.812698412698411*G0_0_1_5_0_1 - 0.0203174603174624*G0_0_1_6_0_0 + 0.995555555555549*G0_0_1_6_0_1 + 4.36825396825395*G0_0_1_7_0_0 + 2.43809523809522*G0_0_1_7_0_1 - 3.6774603174603*G0_0_1_8_0_0 + 0.182857142857141*G0_0_1_8_0_1 + 1.46285714285714*G0_0_1_9_0_0 - 3.41333333333331*G0_0_1_9_0_1 - 1.42222222222222*G0_0_1_10_1_0 - 1.42222222222222*G0_0_1_10_1_1 + 0.731428571428568*G0_0_1_11_1_0 - 0.386031746031743*G0_0_1_12_1_1 - 0.345396825396824*G0_0_1_13_1_0 - 0.182857142857141*G0_0_1_13_1_1 + 0.020317460317462*G0_0_1_14_1_0 + 0.975238095238091*G0_0_1_14_1_1 - 1.11746031746031*G0_0_1_15_1_0 + 0.812698412698411*G0_0_1_15_1_1 - 0.0203174603174624*G0_0_1_16_1_0 + 0.995555555555549*G0_0_1_16_1_1 + 4.36825396825395*G0_0_1_17_1_0 + 2.43809523809522*G0_0_1_17_1_1 - 3.6774603174603*G0_0_1_18_1_0 + 0.182857142857141*G0_0_1_18_1_1 + 1.46285714285714*G0_0_1_19_1_0 - 3.41333333333331*G0_0_1_19_1_1 + 1.42222222222222*G0_1_0_0_0_0 + 1.42222222222222*G0_1_0_0_0_1 - 0.731428571428568*G0_1_0_1_0_0 + 0.386031746031743*G0_1_0_2_0_1 + 0.345396825396824*G0_1_0_3_0_0 + 0.182857142857141*G0_1_0_3_0_1 - 0.020317460317462*G0_1_0_4_0_0 - 0.975238095238091*G0_1_0_4_0_1 + 1.11746031746031*G0_1_0_5_0_0 - 0.812698412698411*G0_1_0_5_0_1 + 0.0203174603174625*G0_1_0_6_0_0 - 0.995555555555549*G0_1_0_6_0_1 - 4.36825396825395*G0_1_0_7_0_0 - 2.43809523809522*G0_1_0_7_0_1 + 3.6774603174603*G0_1_0_8_0_0 - 0.182857142857141*G0_1_0_8_0_1 - 1.46285714285714*G0_1_0_9_0_0 + 3.41333333333331*G0_1_0_9_0_1 + 1.42222222222222*G0_1_0_10_1_0 + 1.42222222222222*G0_1_0_10_1_1 - 0.731428571428568*G0_1_0_11_1_0 + 0.386031746031743*G0_1_0_12_1_1 + 0.345396825396824*G0_1_0_13_1_0 + 0.182857142857141*G0_1_0_13_1_1 - 0.020317460317462*G0_1_0_14_1_0 - 0.975238095238091*G0_1_0_14_1_1 + 1.11746031746031*G0_1_0_15_1_0 - 0.812698412698411*G0_1_0_15_1_1 + 0.0203174603174625*G0_1_0_16_1_0 - 0.995555555555549*G0_1_0_16_1_1 - 4.36825396825395*G0_1_0_17_1_0 - 2.43809523809522*G0_1_0_17_1_1 + 3.6774603174603*G0_1_0_18_1_0 - 0.182857142857141*G0_1_0_18_1_1 - 1.46285714285714*G0_1_0_19_1_0 + 3.41333333333331*G0_1_0_19_1_1; + A[448] = 0.0; + A[304] = A[769]; + A[475] = A[765] + 1.47777777777777*G0_0_1_0_0_0 + 1.47777777777777*G0_0_1_0_0_1 - 0.276190476190474*G0_0_1_1_0_0 - 0.174603174603174*G0_0_1_2_0_1 + 0.0849206349206355*G0_0_1_3_0_0 + 0.034126984126984*G0_0_1_3_0_1 + 0.103968253968254*G0_0_1_4_0_0 + 0.0531746031746039*G0_0_1_4_0_1 + 0.586507936507934*G0_0_1_5_0_0 - 2.11825396825396*G0_0_1_5_0_1 - 0.103968253968254*G0_0_1_6_0_0 + 0.815079365079362*G0_0_1_6_0_1 - 2.35317460317459*G0_0_1_7_0_0 + 0.351587301587301*G0_0_1_7_0_1 + 1.1515873015873*G0_0_1_8_0_0 - 0.0341269841269842*G0_0_1_8_0_1 - 0.671428571428569*G0_0_1_9_0_0 - 0.404761904761905*G0_0_1_9_0_1 + 1.47777777777777*G0_0_1_10_1_0 + 1.47777777777777*G0_0_1_10_1_1 - 0.276190476190474*G0_0_1_11_1_0 - 0.174603174603174*G0_0_1_12_1_1 + 0.0849206349206355*G0_0_1_13_1_0 + 0.034126984126984*G0_0_1_13_1_1 + 0.103968253968254*G0_0_1_14_1_0 + 0.0531746031746039*G0_0_1_14_1_1 + 0.586507936507934*G0_0_1_15_1_0 - 2.11825396825396*G0_0_1_15_1_1 - 0.103968253968254*G0_0_1_16_1_0 + 0.815079365079362*G0_0_1_16_1_1 - 2.35317460317459*G0_0_1_17_1_0 + 0.351587301587301*G0_0_1_17_1_1 + 1.1515873015873*G0_0_1_18_1_0 - 0.0341269841269842*G0_0_1_18_1_1 - 0.671428571428569*G0_0_1_19_1_0 - 0.404761904761905*G0_0_1_19_1_1 - 1.47777777777777*G0_1_0_0_0_0 - 1.47777777777777*G0_1_0_0_0_1 + 0.276190476190474*G0_1_0_1_0_0 + 0.174603174603174*G0_1_0_2_0_1 - 0.0849206349206355*G0_1_0_3_0_0 - 0.034126984126984*G0_1_0_3_0_1 - 0.103968253968254*G0_1_0_4_0_0 - 0.0531746031746038*G0_1_0_4_0_1 - 0.586507936507934*G0_1_0_5_0_0 + 2.11825396825396*G0_1_0_5_0_1 + 0.103968253968254*G0_1_0_6_0_0 - 0.815079365079362*G0_1_0_6_0_1 + 2.35317460317459*G0_1_0_7_0_0 - 0.351587301587301*G0_1_0_7_0_1 - 1.1515873015873*G0_1_0_8_0_0 + 0.0341269841269842*G0_1_0_8_0_1 + 0.671428571428569*G0_1_0_9_0_0 + 0.404761904761905*G0_1_0_9_0_1 - 1.47777777777777*G0_1_0_10_1_0 - 1.47777777777777*G0_1_0_10_1_1 + 0.276190476190474*G0_1_0_11_1_0 + 0.174603174603174*G0_1_0_12_1_1 - 0.0849206349206355*G0_1_0_13_1_0 - 0.034126984126984*G0_1_0_13_1_1 - 0.103968253968254*G0_1_0_14_1_0 - 0.0531746031746038*G0_1_0_14_1_1 - 0.586507936507934*G0_1_0_15_1_0 + 2.11825396825396*G0_1_0_15_1_1 + 0.103968253968254*G0_1_0_16_1_0 - 0.815079365079362*G0_1_0_16_1_1 + 2.35317460317459*G0_1_0_17_1_0 - 0.351587301587301*G0_1_0_17_1_1 - 1.1515873015873*G0_1_0_18_1_0 + 0.0341269841269842*G0_1_0_18_1_1 + 0.671428571428569*G0_1_0_19_1_0 + 0.404761904761905*G0_1_0_19_1_1; + A[339] = A[804]; + A[18] = 0.0; + A[735] = A[270]; + A[426] = A[194] + 0.406349206349208*G0_0_1_0_0_0 + 0.406349206349209*G0_0_1_0_0_1 + 0.101587301587302*G0_0_1_1_0_0 + 0.121904761904764*G0_0_1_2_0_1 - 0.731428571428572*G0_0_1_3_0_0 - 0.101587301587299*G0_0_1_3_0_1 + 0.42666666666667*G0_0_1_4_0_0 - 0.223492063492065*G0_0_1_4_0_1 - 0.487619047619043*G0_0_1_5_0_0 - 0.995555555555556*G0_0_1_5_0_1 - 0.426666666666671*G0_0_1_6_0_0 + 0.467301587301583*G0_0_1_6_0_1 - 0.528253968253973*G0_0_1_7_0_0 - 0.0203174603174608*G0_0_1_7_0_1 + 0.0203174603174624*G0_0_1_8_0_0 + 0.101587301587299*G0_0_1_8_0_1 + 1.21904761904762*G0_0_1_9_0_0 + 0.243809523809526*G0_0_1_9_0_1 + 0.406349206349208*G0_0_1_10_1_0 + 0.406349206349209*G0_0_1_10_1_1 + 0.101587301587302*G0_0_1_11_1_0 + 0.121904761904764*G0_0_1_12_1_1 - 0.731428571428572*G0_0_1_13_1_0 - 0.101587301587299*G0_0_1_13_1_1 + 0.42666666666667*G0_0_1_14_1_0 - 0.223492063492065*G0_0_1_14_1_1 - 0.487619047619043*G0_0_1_15_1_0 - 0.995555555555556*G0_0_1_15_1_1 - 0.426666666666671*G0_0_1_16_1_0 + 0.467301587301583*G0_0_1_16_1_1 - 0.528253968253973*G0_0_1_17_1_0 - 0.0203174603174608*G0_0_1_17_1_1 + 0.0203174603174624*G0_0_1_18_1_0 + 0.101587301587299*G0_0_1_18_1_1 + 1.21904761904762*G0_0_1_19_1_0 + 0.243809523809526*G0_0_1_19_1_1 - 0.406349206349208*G0_1_0_0_0_0 - 0.406349206349209*G0_1_0_0_0_1 - 0.101587301587302*G0_1_0_1_0_0 - 0.121904761904764*G0_1_0_2_0_1 + 0.731428571428572*G0_1_0_3_0_0 + 0.101587301587299*G0_1_0_3_0_1 - 0.42666666666667*G0_1_0_4_0_0 + 0.223492063492065*G0_1_0_4_0_1 + 0.487619047619043*G0_1_0_5_0_0 + 0.995555555555556*G0_1_0_5_0_1 + 0.42666666666667*G0_1_0_6_0_0 - 0.467301587301583*G0_1_0_6_0_1 + 0.528253968253973*G0_1_0_7_0_0 + 0.0203174603174608*G0_1_0_7_0_1 - 0.0203174603174625*G0_1_0_8_0_0 - 0.101587301587299*G0_1_0_8_0_1 - 1.21904761904762*G0_1_0_9_0_0 - 0.243809523809526*G0_1_0_9_0_1 - 0.406349206349208*G0_1_0_10_1_0 - 0.406349206349209*G0_1_0_10_1_1 - 0.101587301587302*G0_1_0_11_1_0 - 0.121904761904764*G0_1_0_12_1_1 + 0.731428571428572*G0_1_0_13_1_0 + 0.101587301587299*G0_1_0_13_1_1 - 0.42666666666667*G0_1_0_14_1_0 + 0.223492063492065*G0_1_0_14_1_1 + 0.487619047619043*G0_1_0_15_1_0 + 0.995555555555556*G0_1_0_15_1_1 + 0.42666666666667*G0_1_0_16_1_0 - 0.467301587301583*G0_1_0_16_1_1 + 0.528253968253973*G0_1_0_17_1_0 + 0.0203174603174608*G0_1_0_17_1_1 - 0.0203174603174625*G0_1_0_18_1_0 - 0.101587301587299*G0_1_0_18_1_1 - 1.21904761904762*G0_1_0_19_1_0 - 0.243809523809526*G0_1_0_19_1_1; + A[748] = A[426] + 1.08359788359788*G0_0_0_0_0_0 + 1.08359788359788*G0_0_0_0_0_1 + 0.948148148148142*G0_0_0_1_0_0 - 1.59153439153439*G0_0_0_2_0_1 + 1.52380952380952*G0_0_0_3_0_0 + 2.33650793650792*G0_0_0_3_0_1 - 2.74285714285714*G0_0_0_4_0_0 - 1.01587301587301*G0_0_0_4_0_1 - 0.304761904761909*G0_0_0_5_0_0 - 2.64126984126983*G0_0_0_5_0_1 + 2.74285714285714*G0_0_0_6_0_0 + 3.14920634920634*G0_0_0_6_0_1 - 0.101587301587303*G0_0_0_7_0_0 + 2.23492063492062*G0_0_0_7_0_1 - 1.93015873015872*G0_0_0_8_0_0 - 2.33650793650792*G0_0_0_8_0_1 - 1.21904761904761*G0_0_0_9_0_0 - 1.21904761904761*G0_0_0_9_0_1 + 1.08359788359788*G0_0_0_10_1_0 + 1.08359788359788*G0_0_0_10_1_1 + 0.948148148148142*G0_0_0_11_1_0 - 1.59153439153439*G0_0_0_12_1_1 + 1.52380952380952*G0_0_0_13_1_0 + 2.33650793650792*G0_0_0_13_1_1 - 2.74285714285714*G0_0_0_14_1_0 - 1.01587301587301*G0_0_0_14_1_1 - 0.304761904761909*G0_0_0_15_1_0 - 2.64126984126983*G0_0_0_15_1_1 + 2.74285714285714*G0_0_0_16_1_0 + 3.14920634920634*G0_0_0_16_1_1 - 0.101587301587303*G0_0_0_17_1_0 + 2.23492063492062*G0_0_0_17_1_1 - 1.93015873015872*G0_0_0_18_1_0 - 2.33650793650792*G0_0_0_18_1_1 - 1.21904761904761*G0_0_0_19_1_0 - 1.21904761904761*G0_0_0_19_1_1 + 1.4831746031746*G0_0_1_1_0_0 - 1.4831746031746*G0_0_1_2_0_1 + 1.42222222222222*G0_0_1_3_0_0 + 2.90539682539681*G0_0_1_3_0_1 - 2.90539682539682*G0_0_1_4_0_0 - 1.42222222222222*G0_0_1_4_0_1 - 1.54412698412698*G0_0_1_5_0_0 - 1.54412698412696*G0_0_1_5_0_1 + 2.90539682539682*G0_0_1_6_0_0 + 3.02730158730157*G0_0_1_6_0_1 + 1.54412698412699*G0_0_1_7_0_0 + 1.54412698412697*G0_0_1_7_0_1 - 3.02730158730157*G0_0_1_8_0_0 - 2.90539682539681*G0_0_1_8_0_1 + 0.121904761904764*G0_0_1_9_0_0 - 0.121904761904754*G0_0_1_9_0_1 + 1.4831746031746*G0_0_1_11_1_0 - 1.4831746031746*G0_0_1_12_1_1 + 1.42222222222222*G0_0_1_13_1_0 + 2.90539682539681*G0_0_1_13_1_1 - 2.90539682539682*G0_0_1_14_1_0 - 1.42222222222222*G0_0_1_14_1_1 - 1.54412698412698*G0_0_1_15_1_0 - 1.54412698412696*G0_0_1_15_1_1 + 2.90539682539682*G0_0_1_16_1_0 + 3.02730158730157*G0_0_1_16_1_1 + 1.54412698412699*G0_0_1_17_1_0 + 1.54412698412697*G0_0_1_17_1_1 - 3.02730158730157*G0_0_1_18_1_0 - 2.90539682539681*G0_0_1_18_1_1 + 0.121904761904764*G0_0_1_19_1_0 - 0.121904761904754*G0_0_1_19_1_1 + 1.46285714285713*G0_1_0_1_0_0 - 1.46285714285713*G0_1_0_2_0_1 + 0.91428571428571*G0_1_0_3_0_0 + 2.37714285714284*G0_1_0_3_0_1 - 2.37714285714284*G0_1_0_4_0_0 - 0.914285714285709*G0_1_0_4_0_1 - 2.01142857142856*G0_1_0_5_0_0 - 2.01142857142856*G0_1_0_5_0_1 + 2.37714285714285*G0_1_0_6_0_0 + 3.47428571428569*G0_1_0_6_0_1 + 2.01142857142856*G0_1_0_7_0_0 + 2.01142857142856*G0_1_0_7_0_1 - 3.47428571428569*G0_1_0_8_0_0 - 2.37714285714284*G0_1_0_8_0_1 + 1.09714285714285*G0_1_0_9_0_0 - 1.09714285714284*G0_1_0_9_0_1 + 1.46285714285713*G0_1_0_11_1_0 - 1.46285714285713*G0_1_0_12_1_1 + 0.91428571428571*G0_1_0_13_1_0 + 2.37714285714284*G0_1_0_13_1_1 - 2.37714285714284*G0_1_0_14_1_0 - 0.914285714285709*G0_1_0_14_1_1 - 2.01142857142856*G0_1_0_15_1_0 - 2.01142857142856*G0_1_0_15_1_1 + 2.37714285714285*G0_1_0_16_1_0 + 3.47428571428569*G0_1_0_16_1_1 + 2.01142857142856*G0_1_0_17_1_0 + 2.01142857142856*G0_1_0_17_1_1 - 3.47428571428569*G0_1_0_18_1_0 - 2.37714285714284*G0_1_0_18_1_1 + 1.09714285714285*G0_1_0_19_1_0 - 1.09714285714284*G0_1_0_19_1_1 - 1.08359788359788*G0_1_1_0_0_0 - 1.08359788359788*G0_1_1_0_0_1 + 1.59153439153438*G0_1_1_1_0_0 - 0.948148148148143*G0_1_1_2_0_1 + 1.01587301587301*G0_1_1_3_0_0 + 2.74285714285713*G0_1_1_3_0_1 - 2.33650793650792*G0_1_1_4_0_0 - 1.52380952380951*G0_1_1_4_0_1 - 2.23492063492062*G0_1_1_5_0_0 + 0.10158730158731*G0_1_1_5_0_1 + 2.33650793650793*G0_1_1_6_0_0 + 1.93015873015872*G0_1_1_6_0_1 + 2.64126984126983*G0_1_1_7_0_0 + 0.304761904761901*G0_1_1_7_0_1 - 3.14920634920633*G0_1_1_8_0_0 - 2.74285714285713*G0_1_1_8_0_1 + 1.21904761904761*G0_1_1_9_0_0 + 1.21904761904762*G0_1_1_9_0_1 - 1.08359788359788*G0_1_1_10_1_0 - 1.08359788359788*G0_1_1_10_1_1 + 1.59153439153438*G0_1_1_11_1_0 - 0.948148148148143*G0_1_1_12_1_1 + 1.01587301587301*G0_1_1_13_1_0 + 2.74285714285713*G0_1_1_13_1_1 - 2.33650793650792*G0_1_1_14_1_0 - 1.52380952380951*G0_1_1_14_1_1 - 2.23492063492062*G0_1_1_15_1_0 + 0.10158730158731*G0_1_1_15_1_1 + 2.33650793650793*G0_1_1_16_1_0 + 1.93015873015872*G0_1_1_16_1_1 + 2.64126984126983*G0_1_1_17_1_0 + 0.304761904761901*G0_1_1_17_1_1 - 3.14920634920633*G0_1_1_18_1_0 - 2.74285714285713*G0_1_1_18_1_1 + 1.21904761904761*G0_1_1_19_1_0 + 1.21904761904762*G0_1_1_19_1_1; + A[864] = A[748] - 0.406349206349201*G0_0_1_0_0_0 - 0.406349206349201*G0_0_1_0_0_1 - 0.121904761904764*G0_0_1_1_0_0 - 0.101587301587302*G0_0_1_2_0_1 + 0.223492063492066*G0_0_1_3_0_0 - 0.426666666666666*G0_0_1_3_0_1 + 0.101587301587302*G0_0_1_4_0_0 + 0.731428571428572*G0_0_1_4_0_1 + 0.0203174603174606*G0_0_1_5_0_0 + 0.528253968253962*G0_0_1_5_0_1 - 0.101587301587301*G0_0_1_6_0_0 - 0.0203174603174574*G0_0_1_6_0_1 + 0.995555555555545*G0_0_1_7_0_0 + 0.487619047619044*G0_0_1_7_0_1 - 0.46730158730158*G0_0_1_8_0_0 + 0.426666666666665*G0_0_1_8_0_1 - 0.243809523809527*G0_0_1_9_0_0 - 1.21904761904762*G0_0_1_9_0_1 - 0.406349206349201*G0_0_1_10_1_0 - 0.406349206349201*G0_0_1_10_1_1 - 0.121904761904764*G0_0_1_11_1_0 - 0.101587301587302*G0_0_1_12_1_1 + 0.223492063492066*G0_0_1_13_1_0 - 0.426666666666666*G0_0_1_13_1_1 + 0.101587301587302*G0_0_1_14_1_0 + 0.731428571428572*G0_0_1_14_1_1 + 0.0203174603174606*G0_0_1_15_1_0 + 0.528253968253962*G0_0_1_15_1_1 - 0.101587301587301*G0_0_1_16_1_0 - 0.0203174603174574*G0_0_1_16_1_1 + 0.995555555555545*G0_0_1_17_1_0 + 0.487619047619044*G0_0_1_17_1_1 - 0.46730158730158*G0_0_1_18_1_0 + 0.426666666666665*G0_0_1_18_1_1 - 0.243809523809527*G0_0_1_19_1_0 - 1.21904761904762*G0_0_1_19_1_1 + 0.406349206349202*G0_1_0_0_0_0 + 0.406349206349202*G0_1_0_0_0_1 + 0.121904761904764*G0_1_0_1_0_0 + 0.101587301587302*G0_1_0_2_0_1 - 0.223492063492066*G0_1_0_3_0_0 + 0.426666666666667*G0_1_0_3_0_1 - 0.101587301587302*G0_1_0_4_0_0 - 0.731428571428573*G0_1_0_4_0_1 - 0.0203174603174605*G0_1_0_5_0_0 - 0.528253968253962*G0_1_0_5_0_1 + 0.101587301587302*G0_1_0_6_0_0 + 0.0203174603174575*G0_1_0_6_0_1 - 0.995555555555545*G0_1_0_7_0_0 - 0.487619047619044*G0_1_0_7_0_1 + 0.467301587301579*G0_1_0_8_0_0 - 0.426666666666666*G0_1_0_8_0_1 + 0.243809523809527*G0_1_0_9_0_0 + 1.21904761904762*G0_1_0_9_0_1 + 0.406349206349202*G0_1_0_10_1_0 + 0.406349206349202*G0_1_0_10_1_1 + 0.121904761904764*G0_1_0_11_1_0 + 0.101587301587302*G0_1_0_12_1_1 - 0.223492063492066*G0_1_0_13_1_0 + 0.426666666666667*G0_1_0_13_1_1 - 0.101587301587302*G0_1_0_14_1_0 - 0.731428571428573*G0_1_0_14_1_1 - 0.0203174603174605*G0_1_0_15_1_0 - 0.528253968253962*G0_1_0_15_1_1 + 0.101587301587302*G0_1_0_16_1_0 + 0.0203174603174575*G0_1_0_16_1_1 - 0.995555555555545*G0_1_0_17_1_0 - 0.487619047619044*G0_1_0_17_1_1 + 0.467301587301579*G0_1_0_18_1_0 - 0.426666666666666*G0_1_0_18_1_1 + 0.243809523809527*G0_1_0_19_1_0 + 1.21904761904762*G0_1_0_19_1_1; + A[283] = A[748]; + A[399] = A[864]; + A[378] = 0.0; + A[49] = 0.0; + A[764] = 0.0; + A[457] = 0.0; + A[409] = 0.0; + A[84] = 0.0; + A[793] = 0.0; + A[8] = A[240] + 0.590476190476188*G0_0_1_0_0_0 + 0.590476190476188*G0_0_1_0_0_1 - 0.0711111111111104*G0_0_1_1_0_0 - 0.17269841269841*G0_0_1_2_0_1 + 0.0628571428571416*G0_0_1_3_0_0 + 0.052698412698412*G0_0_1_3_0_1 - 0.112380952380949*G0_0_1_4_0_0 - 0.000634920634920072*G0_0_1_4_0_1 + 0.123809523809524*G0_0_1_5_0_0 - 0.955555555555551*G0_0_1_5_0_1 + 0.112380952380949*G0_0_1_6_0_0 + 0.537777777777774*G0_0_1_6_0_1 - 0.815873015873012*G0_0_1_7_0_0 + 0.263492063492063*G0_0_1_7_0_1 + 0.296507936507935*G0_0_1_8_0_0 - 0.052698412698412*G0_0_1_8_0_1 - 0.186666666666666*G0_0_1_9_0_0 - 0.262857142857143*G0_0_1_9_0_1 + 0.590476190476188*G0_0_1_10_1_0 + 0.590476190476188*G0_0_1_10_1_1 - 0.0711111111111104*G0_0_1_11_1_0 - 0.17269841269841*G0_0_1_12_1_1 + 0.0628571428571416*G0_0_1_13_1_0 + 0.052698412698412*G0_0_1_13_1_1 - 0.112380952380949*G0_0_1_14_1_0 - 0.000634920634920072*G0_0_1_14_1_1 + 0.123809523809524*G0_0_1_15_1_0 - 0.955555555555551*G0_0_1_15_1_1 + 0.112380952380949*G0_0_1_16_1_0 + 0.537777777777774*G0_0_1_16_1_1 - 0.815873015873012*G0_0_1_17_1_0 + 0.263492063492063*G0_0_1_17_1_1 + 0.296507936507935*G0_0_1_18_1_0 - 0.052698412698412*G0_0_1_18_1_1 - 0.186666666666666*G0_0_1_19_1_0 - 0.262857142857143*G0_0_1_19_1_1 - 0.590476190476188*G0_1_0_0_0_0 - 0.590476190476188*G0_1_0_0_0_1 + 0.0711111111111104*G0_1_0_1_0_0 + 0.17269841269841*G0_1_0_2_0_1 - 0.0628571428571416*G0_1_0_3_0_0 - 0.052698412698412*G0_1_0_3_0_1 + 0.112380952380949*G0_1_0_4_0_0 + 0.000634920634920072*G0_1_0_4_0_1 - 0.123809523809524*G0_1_0_5_0_0 + 0.955555555555551*G0_1_0_5_0_1 - 0.112380952380949*G0_1_0_6_0_0 - 0.537777777777774*G0_1_0_6_0_1 + 0.815873015873012*G0_1_0_7_0_0 - 0.263492063492063*G0_1_0_7_0_1 - 0.296507936507935*G0_1_0_8_0_0 + 0.052698412698412*G0_1_0_8_0_1 + 0.186666666666666*G0_1_0_9_0_0 + 0.262857142857143*G0_1_0_9_0_1 - 0.590476190476188*G0_1_0_10_1_0 - 0.590476190476188*G0_1_0_10_1_1 + 0.0711111111111104*G0_1_0_11_1_0 + 0.17269841269841*G0_1_0_12_1_1 - 0.0628571428571416*G0_1_0_13_1_0 - 0.052698412698412*G0_1_0_13_1_1 + 0.112380952380949*G0_1_0_14_1_0 + 0.000634920634920072*G0_1_0_14_1_1 - 0.123809523809524*G0_1_0_15_1_0 + 0.955555555555551*G0_1_0_15_1_1 - 0.112380952380949*G0_1_0_16_1_0 - 0.537777777777774*G0_1_0_16_1_1 + 0.815873015873012*G0_1_0_17_1_0 - 0.263492063492063*G0_1_0_17_1_1 - 0.296507936507935*G0_1_0_18_1_0 + 0.052698412698412*G0_1_0_18_1_1 + 0.186666666666666*G0_1_0_19_1_0 + 0.262857142857143*G0_1_0_19_1_1; + A[5] = -A[8] + 0.590476190476187*G0_0_1_0_0_0 + 0.590476190476188*G0_0_1_0_0_1 - 0.0876190476190465*G0_0_1_1_0_0 - 0.285714285714285*G0_0_1_2_0_1 + 0.227301587301586*G0_0_1_3_0_0 + 0.0711111111111108*G0_0_1_3_0_1 - 0.26031746031746*G0_0_1_4_0_0 + 0.0939682539682524*G0_0_1_4_0_1 + 0.0622222222222212*G0_0_1_5_0_0 - 1.01714285714285*G0_0_1_5_0_1 + 0.26031746031746*G0_0_1_6_0_0 + 0.71238095238095*G0_0_1_6_0_1 - 0.75428571428571*G0_0_1_7_0_0 + 0.325079365079364*G0_0_1_7_0_1 + 0.251428571428569*G0_0_1_8_0_0 - 0.0711111111111109*G0_0_1_8_0_1 - 0.289523809523807*G0_0_1_9_0_0 - 0.419047619047617*G0_0_1_9_0_1 + 0.590476190476187*G0_0_1_10_1_0 + 0.590476190476188*G0_0_1_10_1_1 - 0.0876190476190465*G0_0_1_11_1_0 - 0.285714285714285*G0_0_1_12_1_1 + 0.227301587301586*G0_0_1_13_1_0 + 0.0711111111111108*G0_0_1_13_1_1 - 0.26031746031746*G0_0_1_14_1_0 + 0.0939682539682524*G0_0_1_14_1_1 + 0.0622222222222212*G0_0_1_15_1_0 - 1.01714285714285*G0_0_1_15_1_1 + 0.26031746031746*G0_0_1_16_1_0 + 0.71238095238095*G0_0_1_16_1_1 - 0.75428571428571*G0_0_1_17_1_0 + 0.325079365079364*G0_0_1_17_1_1 + 0.251428571428569*G0_0_1_18_1_0 - 0.0711111111111109*G0_0_1_18_1_1 - 0.289523809523807*G0_0_1_19_1_0 - 0.419047619047617*G0_0_1_19_1_1 + 0.590476190476187*G0_1_1_0_0_0 + 0.590476190476188*G0_1_1_0_0_1 - 0.0876190476190467*G0_1_1_1_0_0 - 0.285714285714285*G0_1_1_2_0_1 + 0.227301587301586*G0_1_1_3_0_0 + 0.0711111111111111*G0_1_1_3_0_1 - 0.260317460317462*G0_1_1_4_0_0 + 0.0939682539682519*G0_1_1_4_0_1 + 0.0622222222222208*G0_1_1_5_0_0 - 1.01714285714285*G0_1_1_5_0_1 + 0.260317460317462*G0_1_1_6_0_0 + 0.712380952380951*G0_1_1_6_0_1 - 0.75428571428571*G0_1_1_7_0_0 + 0.325079365079363*G0_1_1_7_0_1 + 0.251428571428569*G0_1_1_8_0_0 - 0.0711111111111111*G0_1_1_8_0_1 - 0.289523809523807*G0_1_1_9_0_0 - 0.419047619047616*G0_1_1_9_0_1 + 0.590476190476187*G0_1_1_10_1_0 + 0.590476190476188*G0_1_1_10_1_1 - 0.0876190476190467*G0_1_1_11_1_0 - 0.285714285714285*G0_1_1_12_1_1 + 0.227301587301586*G0_1_1_13_1_0 + 0.0711111111111111*G0_1_1_13_1_1 - 0.260317460317462*G0_1_1_14_1_0 + 0.0939682539682519*G0_1_1_14_1_1 + 0.0622222222222208*G0_1_1_15_1_0 - 1.01714285714285*G0_1_1_15_1_1 + 0.260317460317462*G0_1_1_16_1_0 + 0.712380952380951*G0_1_1_16_1_1 - 0.75428571428571*G0_1_1_17_1_0 + 0.325079365079363*G0_1_1_17_1_1 + 0.251428571428569*G0_1_1_18_1_0 - 0.0711111111111111*G0_1_1_18_1_1 - 0.289523809523807*G0_1_1_19_1_0 - 0.419047619047616*G0_1_1_19_1_1; + A[469] = A[5] - 0.0355555555555557*G0_0_0_1_0_0 - 0.25111111111111*G0_0_0_2_0_1 + 0.321587301587299*G0_0_0_3_0_0 + 0.0350793650793644*G0_0_0_3_0_1 - 0.357460317460316*G0_0_0_4_0_0 + 0.144603174603173*G0_0_0_4_0_1 - 0.18063492063492*G0_0_0_5_0_0 - 0.144920634920637*G0_0_0_5_0_1 + 0.357460317460316*G0_0_0_6_0_0 + 0.396031746031746*G0_0_0_6_0_1 + 0.109206349206346*G0_0_0_7_0_0 + 0.0734920634920631*G0_0_0_7_0_1 - 0.073650793650792*G0_0_0_8_0_0 - 0.0350793650793644*G0_0_0_8_0_1 - 0.140952380952379*G0_0_0_9_0_0 - 0.218095238095236*G0_0_0_9_0_1 - 0.0355555555555557*G0_0_0_11_1_0 - 0.25111111111111*G0_0_0_12_1_1 + 0.321587301587299*G0_0_0_13_1_0 + 0.0350793650793644*G0_0_0_13_1_1 - 0.357460317460316*G0_0_0_14_1_0 + 0.144603174603173*G0_0_0_14_1_1 - 0.18063492063492*G0_0_0_15_1_0 - 0.144920634920637*G0_0_0_15_1_1 + 0.357460317460316*G0_0_0_16_1_0 + 0.396031746031746*G0_0_0_16_1_1 + 0.109206349206346*G0_0_0_17_1_0 + 0.0734920634920631*G0_0_0_17_1_1 - 0.073650793650792*G0_0_0_18_1_0 - 0.0350793650793644*G0_0_0_18_1_1 - 0.140952380952379*G0_0_0_19_1_0 - 0.218095238095236*G0_0_0_19_1_1 + 0.0053968253968236*G0_0_1_1_0_0 - 0.162539682539682*G0_0_1_2_0_1 + 0.180158730158729*G0_0_1_3_0_0 + 0.0641269841269815*G0_0_1_3_0_1 - 0.256984126984124*G0_0_1_4_0_0 + 0.0269841269841285*G0_0_1_4_0_1 - 0.144920634920633*G0_0_1_5_0_0 - 0.109206349206353*G0_0_1_5_0_1 + 0.256984126984124*G0_0_1_6_0_0 + 0.271746031746031*G0_0_1_6_0_1 + 0.0734920634920577*G0_0_1_7_0_0 + 0.0377777777777777*G0_0_1_7_0_1 - 0.0788888888888844*G0_0_1_8_0_0 - 0.0641269841269815*G0_0_1_8_0_1 - 0.035238095238096*G0_0_1_9_0_0 - 0.0647619047619059*G0_0_1_9_0_1 + 0.0053968253968236*G0_0_1_11_1_0 - 0.162539682539682*G0_0_1_12_1_1 + 0.180158730158729*G0_0_1_13_1_0 + 0.0641269841269815*G0_0_1_13_1_1 - 0.256984126984124*G0_0_1_14_1_0 + 0.0269841269841285*G0_0_1_14_1_1 - 0.144920634920633*G0_0_1_15_1_0 - 0.109206349206353*G0_0_1_15_1_1 + 0.256984126984124*G0_0_1_16_1_0 + 0.271746031746031*G0_0_1_16_1_1 + 0.0734920634920577*G0_0_1_17_1_0 + 0.0377777777777777*G0_0_1_17_1_1 - 0.0788888888888844*G0_0_1_18_1_0 - 0.0641269841269815*G0_0_1_18_1_1 - 0.035238095238096*G0_0_1_19_1_0 - 0.0647619047619059*G0_0_1_19_1_1 - 0.035555555555556*G0_1_0_1_0_0 - 0.251111111111112*G0_1_0_2_0_1 + 0.3215873015873*G0_1_0_3_0_0 + 0.0350793650793644*G0_1_0_3_0_1 - 0.35746031746032*G0_1_0_4_0_0 + 0.144603174603172*G0_1_0_4_0_1 - 0.180634920634922*G0_1_0_5_0_0 - 0.144920634920639*G0_1_0_5_0_1 + 0.35746031746032*G0_1_0_6_0_0 + 0.396031746031749*G0_1_0_6_0_1 + 0.109206349206346*G0_1_0_7_0_0 + 0.0734920634920629*G0_1_0_7_0_1 - 0.0736507936507922*G0_1_0_8_0_0 - 0.0350793650793644*G0_1_0_8_0_1 - 0.140952380952378*G0_1_0_9_0_0 - 0.218095238095235*G0_1_0_9_0_1 - 0.035555555555556*G0_1_0_11_1_0 - 0.251111111111112*G0_1_0_12_1_1 + 0.3215873015873*G0_1_0_13_1_0 + 0.0350793650793644*G0_1_0_13_1_1 - 0.35746031746032*G0_1_0_14_1_0 + 0.144603174603172*G0_1_0_14_1_1 - 0.180634920634922*G0_1_0_15_1_0 - 0.144920634920639*G0_1_0_15_1_1 + 0.35746031746032*G0_1_0_16_1_0 + 0.396031746031749*G0_1_0_16_1_1 + 0.109206349206346*G0_1_0_17_1_0 + 0.0734920634920629*G0_1_0_17_1_1 - 0.0736507936507922*G0_1_0_18_1_0 - 0.0350793650793644*G0_1_0_18_1_1 - 0.140952380952378*G0_1_0_19_1_0 - 0.218095238095235*G0_1_0_19_1_1 + 0.00539682539682346*G0_1_1_1_0_0 - 0.162539682539682*G0_1_1_2_0_1 + 0.180158730158728*G0_1_1_3_0_0 + 0.064126984126981*G0_1_1_3_0_1 - 0.256984126984125*G0_1_1_4_0_0 + 0.026984126984128*G0_1_1_4_0_1 - 0.144920634920633*G0_1_1_5_0_0 - 0.109206349206353*G0_1_1_5_0_1 + 0.256984126984125*G0_1_1_6_0_0 + 0.271746031746032*G0_1_1_6_0_1 + 0.0734920634920577*G0_1_1_7_0_0 + 0.0377777777777777*G0_1_1_7_0_1 - 0.0788888888888844*G0_1_1_8_0_0 - 0.064126984126981*G0_1_1_8_0_1 - 0.0352380952380947*G0_1_1_9_0_0 - 0.0647619047619054*G0_1_1_9_0_1 + 0.00539682539682346*G0_1_1_11_1_0 - 0.162539682539682*G0_1_1_12_1_1 + 0.180158730158728*G0_1_1_13_1_0 + 0.064126984126981*G0_1_1_13_1_1 - 0.256984126984125*G0_1_1_14_1_0 + 0.026984126984128*G0_1_1_14_1_1 - 0.144920634920633*G0_1_1_15_1_0 - 0.109206349206353*G0_1_1_15_1_1 + 0.256984126984125*G0_1_1_16_1_0 + 0.271746031746032*G0_1_1_16_1_1 + 0.0734920634920577*G0_1_1_17_1_0 + 0.0377777777777777*G0_1_1_17_1_1 - 0.0788888888888844*G0_1_1_18_1_0 - 0.064126984126981*G0_1_1_18_1_1 - 0.0352380952380947*G0_1_1_19_1_0 - 0.0647619047619054*G0_1_1_19_1_1; + A[585] = A[469] - 0.0244444444444434*G0_0_1_1_0_0 + 0.0244444444444434*G0_0_1_2_0_1 - 0.0230158730158728*G0_0_1_3_0_0 - 0.0474603174603159*G0_0_1_3_0_1 + 0.0474603174603147*G0_0_1_4_0_0 + 0.0230158730158708*G0_0_1_4_0_1 + 0.0258730158730142*G0_0_1_5_0_0 + 0.025873015873016*G0_0_1_5_0_1 - 0.0474603174603146*G0_0_1_6_0_0 - 0.0503174603174586*G0_0_1_6_0_1 - 0.0258730158730138*G0_0_1_7_0_0 - 0.0258730158730158*G0_0_1_7_0_1 + 0.050317460317458*G0_0_1_8_0_0 + 0.0474603174603159*G0_0_1_8_0_1 - 0.00285714285714134*G0_0_1_9_0_0 + 0.00285714285714472*G0_0_1_9_0_1 - 0.0244444444444434*G0_0_1_11_1_0 + 0.0244444444444434*G0_0_1_12_1_1 - 0.0230158730158728*G0_0_1_13_1_0 - 0.0474603174603159*G0_0_1_13_1_1 + 0.0474603174603147*G0_0_1_14_1_0 + 0.0230158730158708*G0_0_1_14_1_1 + 0.0258730158730142*G0_0_1_15_1_0 + 0.025873015873016*G0_0_1_15_1_1 - 0.0474603174603146*G0_0_1_16_1_0 - 0.0503174603174586*G0_0_1_16_1_1 - 0.0258730158730138*G0_0_1_17_1_0 - 0.0258730158730158*G0_0_1_17_1_1 + 0.050317460317458*G0_0_1_18_1_0 + 0.0474603174603159*G0_0_1_18_1_1 - 0.00285714285714134*G0_0_1_19_1_0 + 0.00285714285714472*G0_0_1_19_1_1 + 0.0244444444444434*G0_1_0_1_0_0 - 0.0244444444444434*G0_1_0_2_0_1 + 0.0230158730158728*G0_1_0_3_0_0 + 0.047460317460316*G0_1_0_3_0_1 - 0.0474603174603147*G0_1_0_4_0_0 - 0.0230158730158709*G0_1_0_4_0_1 - 0.0258730158730142*G0_1_0_5_0_0 - 0.025873015873016*G0_1_0_5_0_1 + 0.0474603174603146*G0_1_0_6_0_0 + 0.0503174603174586*G0_1_0_6_0_1 + 0.0258730158730138*G0_1_0_7_0_0 + 0.0258730158730158*G0_1_0_7_0_1 - 0.0503174603174581*G0_1_0_8_0_0 - 0.047460317460316*G0_1_0_8_0_1 + 0.00285714285714134*G0_1_0_9_0_0 - 0.00285714285714472*G0_1_0_9_0_1 + 0.0244444444444434*G0_1_0_11_1_0 - 0.0244444444444434*G0_1_0_12_1_1 + 0.0230158730158728*G0_1_0_13_1_0 + 0.047460317460316*G0_1_0_13_1_1 - 0.0474603174603147*G0_1_0_14_1_0 - 0.0230158730158709*G0_1_0_14_1_1 - 0.0258730158730142*G0_1_0_15_1_0 - 0.025873015873016*G0_1_0_15_1_1 + 0.0474603174603146*G0_1_0_16_1_0 + 0.0503174603174586*G0_1_0_16_1_1 + 0.0258730158730138*G0_1_0_17_1_0 + 0.0258730158730158*G0_1_0_17_1_1 - 0.0503174603174581*G0_1_0_18_1_0 - 0.047460317460316*G0_1_0_18_1_1 + 0.00285714285714134*G0_1_0_19_1_0 - 0.00285714285714472*G0_1_0_19_1_1; + A[470] = A[5]; + A[555] = A[5] + 0.126984126984126*G0_0_0_1_0_0 - 0.256507936507935*G0_0_0_2_0_1 + 0.294603174603173*G0_0_0_3_0_0 + 0.29206349206349*G0_0_0_3_0_1 - 0.421587301587299*G0_0_0_4_0_0 - 0.0355555555555551*G0_0_0_4_0_1 - 0.218412698412697*G0_0_0_5_0_0 - 0.218412698412699*G0_0_0_5_0_1 + 0.421587301587299*G0_0_0_6_0_0 + 0.474920634920633*G0_0_0_6_0_1 + 0.218412698412696*G0_0_0_7_0_0 + 0.218412698412697*G0_0_0_7_0_1 - 0.345396825396822*G0_0_0_8_0_0 - 0.29206349206349*G0_0_0_8_0_1 - 0.0761904761904753*G0_0_0_9_0_0 - 0.182857142857142*G0_0_0_9_0_1 + 0.126984126984126*G0_0_0_11_1_0 - 0.256507936507935*G0_0_0_12_1_1 + 0.294603174603173*G0_0_0_13_1_0 + 0.29206349206349*G0_0_0_13_1_1 - 0.421587301587299*G0_0_0_14_1_0 - 0.0355555555555551*G0_0_0_14_1_1 - 0.218412698412697*G0_0_0_15_1_0 - 0.218412698412699*G0_0_0_15_1_1 + 0.421587301587299*G0_0_0_16_1_0 + 0.474920634920633*G0_0_0_16_1_1 + 0.218412698412696*G0_0_0_17_1_0 + 0.218412698412697*G0_0_0_17_1_1 - 0.345396825396822*G0_0_0_18_1_0 - 0.29206349206349*G0_0_0_18_1_1 - 0.0761904761904753*G0_0_0_19_1_0 - 0.182857142857142*G0_0_0_19_1_1 + 0.143492063492062*G0_0_1_1_0_0 - 0.143492063492062*G0_0_1_2_0_1 + 0.130158730158728*G0_0_1_3_0_0 + 0.27365079365079*G0_0_1_3_0_1 - 0.27365079365079*G0_0_1_4_0_0 - 0.130158730158728*G0_0_1_4_0_1 - 0.156825396825395*G0_0_1_5_0_0 - 0.156825396825398*G0_0_1_5_0_1 + 0.27365079365079*G0_0_1_6_0_0 + 0.300317460317458*G0_0_1_6_0_1 + 0.156825396825393*G0_0_1_7_0_0 + 0.156825396825396*G0_0_1_7_0_1 - 0.300317460317456*G0_0_1_8_0_0 - 0.27365079365079*G0_0_1_8_0_1 + 0.0266666666666667*G0_0_1_9_0_0 - 0.0266666666666669*G0_0_1_9_0_1 + 0.143492063492062*G0_0_1_11_1_0 - 0.143492063492062*G0_0_1_12_1_1 + 0.130158730158728*G0_0_1_13_1_0 + 0.27365079365079*G0_0_1_13_1_1 - 0.27365079365079*G0_0_1_14_1_0 - 0.130158730158728*G0_0_1_14_1_1 - 0.156825396825395*G0_0_1_15_1_0 - 0.156825396825398*G0_0_1_15_1_1 + 0.27365079365079*G0_0_1_16_1_0 + 0.300317460317458*G0_0_1_16_1_1 + 0.156825396825393*G0_0_1_17_1_0 + 0.156825396825396*G0_0_1_17_1_1 - 0.300317460317456*G0_0_1_18_1_0 - 0.27365079365079*G0_0_1_18_1_1 + 0.0266666666666667*G0_0_1_19_1_0 - 0.0266666666666669*G0_0_1_19_1_1 + 0.239999999999999*G0_1_0_1_0_0 - 0.24*G0_1_0_2_0_1 + 0.2*G0_1_0_3_0_0 + 0.439999999999998*G0_1_0_3_0_1 - 0.440000000000001*G0_1_0_4_0_0 - 0.2*G0_1_0_4_0_1 - 0.28*G0_1_0_5_0_0 - 0.280000000000001*G0_1_0_5_0_1 + 0.440000000000001*G0_1_0_6_0_0 + 0.520000000000001*G0_1_0_6_0_1 + 0.279999999999997*G0_1_0_7_0_0 + 0.279999999999999*G0_1_0_7_0_1 - 0.519999999999997*G0_1_0_8_0_0 - 0.439999999999999*G0_1_0_8_0_1 + 0.0799999999999997*G0_1_0_9_0_0 - 0.0799999999999988*G0_1_0_9_0_1 + 0.239999999999999*G0_1_0_11_1_0 - 0.24*G0_1_0_12_1_1 + 0.2*G0_1_0_13_1_0 + 0.439999999999998*G0_1_0_13_1_1 - 0.440000000000001*G0_1_0_14_1_0 - 0.2*G0_1_0_14_1_1 - 0.28*G0_1_0_15_1_0 - 0.280000000000001*G0_1_0_15_1_1 + 0.440000000000001*G0_1_0_16_1_0 + 0.520000000000001*G0_1_0_16_1_1 + 0.279999999999997*G0_1_0_17_1_0 + 0.279999999999999*G0_1_0_17_1_1 - 0.519999999999997*G0_1_0_18_1_0 - 0.439999999999999*G0_1_0_18_1_1 + 0.0799999999999997*G0_1_0_19_1_0 - 0.0799999999999988*G0_1_0_19_1_1 + 0.256507936507935*G0_1_1_1_0_0 - 0.126984126984127*G0_1_1_2_0_1 + 0.0355555555555556*G0_1_1_3_0_0 + 0.421587301587299*G0_1_1_3_0_1 - 0.29206349206349*G0_1_1_4_0_0 - 0.294603174603172*G0_1_1_4_0_1 - 0.218412698412697*G0_1_1_5_0_0 - 0.218412698412699*G0_1_1_5_0_1 + 0.29206349206349*G0_1_1_6_0_0 + 0.345396825396825*G0_1_1_6_0_1 + 0.218412698412695*G0_1_1_7_0_0 + 0.218412698412697*G0_1_1_7_0_1 - 0.474920634920631*G0_1_1_8_0_0 - 0.421587301587299*G0_1_1_8_0_1 + 0.182857142857141*G0_1_1_9_0_0 + 0.0761904761904753*G0_1_1_9_0_1 + 0.256507936507935*G0_1_1_11_1_0 - 0.126984126984127*G0_1_1_12_1_1 + 0.0355555555555556*G0_1_1_13_1_0 + 0.421587301587299*G0_1_1_13_1_1 - 0.29206349206349*G0_1_1_14_1_0 - 0.294603174603172*G0_1_1_14_1_1 - 0.218412698412697*G0_1_1_15_1_0 - 0.218412698412699*G0_1_1_15_1_1 + 0.29206349206349*G0_1_1_16_1_0 + 0.345396825396825*G0_1_1_16_1_1 + 0.218412698412695*G0_1_1_17_1_0 + 0.218412698412697*G0_1_1_17_1_1 - 0.474920634920631*G0_1_1_18_1_0 - 0.421587301587299*G0_1_1_18_1_1 + 0.182857142857141*G0_1_1_19_1_0 + 0.0761904761904753*G0_1_1_19_1_1; + A[795] = -A[555] + 0.59047619047619*G0_0_0_0_0_0 + 0.59047619047619*G0_0_0_0_0_1 - 0.285714285714285*G0_0_0_1_0_0 - 0.0876190476190473*G0_0_0_2_0_1 + 0.0939682539682533*G0_0_0_3_0_0 - 0.26031746031746*G0_0_0_3_0_1 + 0.071111111111112*G0_0_0_4_0_0 + 0.227301587301587*G0_0_0_4_0_1 + 0.325079365079364*G0_0_0_5_0_0 - 0.754285714285715*G0_0_0_5_0_1 - 0.0711111111111119*G0_0_0_6_0_0 + 0.251428571428572*G0_0_0_6_0_1 - 1.01714285714286*G0_0_0_7_0_0 + 0.0622222222222223*G0_0_0_7_0_1 + 0.712380952380951*G0_0_0_8_0_0 + 0.26031746031746*G0_0_0_8_0_1 - 0.419047619047617*G0_0_0_9_0_0 - 0.28952380952381*G0_0_0_9_0_1 + 0.59047619047619*G0_0_0_10_1_0 + 0.59047619047619*G0_0_0_10_1_1 - 0.285714285714285*G0_0_0_11_1_0 - 0.0876190476190473*G0_0_0_12_1_1 + 0.0939682539682533*G0_0_0_13_1_0 - 0.26031746031746*G0_0_0_13_1_1 + 0.071111111111112*G0_0_0_14_1_0 + 0.227301587301587*G0_0_0_14_1_1 + 0.325079365079364*G0_0_0_15_1_0 - 0.754285714285715*G0_0_0_15_1_1 - 0.0711111111111119*G0_0_0_16_1_0 + 0.251428571428572*G0_0_0_16_1_1 - 1.01714285714286*G0_0_0_17_1_0 + 0.0622222222222223*G0_0_0_17_1_1 + 0.712380952380951*G0_0_0_18_1_0 + 0.26031746031746*G0_0_0_18_1_1 - 0.419047619047617*G0_0_0_19_1_0 - 0.28952380952381*G0_0_0_19_1_1 + 0.59047619047619*G0_0_1_0_0_0 + 0.59047619047619*G0_0_1_0_0_1 - 0.285714285714285*G0_0_1_1_0_0 - 0.0876190476190469*G0_0_1_2_0_1 + 0.0939682539682528*G0_0_1_3_0_0 - 0.26031746031746*G0_0_1_3_0_1 + 0.0711111111111124*G0_0_1_4_0_0 + 0.227301587301587*G0_0_1_4_0_1 + 0.325079365079364*G0_0_1_5_0_0 - 0.754285714285715*G0_0_1_5_0_1 - 0.0711111111111123*G0_0_1_6_0_0 + 0.251428571428572*G0_0_1_6_0_1 - 1.01714285714286*G0_0_1_7_0_0 + 0.062222222222222*G0_0_1_7_0_1 + 0.712380952380951*G0_0_1_8_0_0 + 0.26031746031746*G0_0_1_8_0_1 - 0.419047619047617*G0_0_1_9_0_0 - 0.289523809523809*G0_0_1_9_0_1 + 0.59047619047619*G0_0_1_10_1_0 + 0.59047619047619*G0_0_1_10_1_1 - 0.285714285714285*G0_0_1_11_1_0 - 0.0876190476190469*G0_0_1_12_1_1 + 0.0939682539682528*G0_0_1_13_1_0 - 0.26031746031746*G0_0_1_13_1_1 + 0.0711111111111124*G0_0_1_14_1_0 + 0.227301587301587*G0_0_1_14_1_1 + 0.325079365079364*G0_0_1_15_1_0 - 0.754285714285715*G0_0_1_15_1_1 - 0.0711111111111123*G0_0_1_16_1_0 + 0.251428571428572*G0_0_1_16_1_1 - 1.01714285714286*G0_0_1_17_1_0 + 0.062222222222222*G0_0_1_17_1_1 + 0.712380952380951*G0_0_1_18_1_0 + 0.26031746031746*G0_0_1_18_1_1 - 0.419047619047617*G0_0_1_19_1_0 - 0.289523809523809*G0_0_1_19_1_1; + A[4] = A[469]; + A[886] = A[421]; + A[95] = A[560]; + A[810] = 0.0; + A[126] = A[274] + 0.0897354497354514*G0_0_0_0_0_0 + 0.0897354497354515*G0_0_0_0_0_1 + 0.0423280423280416*G0_0_0_1_0_0 + 0.250582010582005*G0_0_0_2_0_1 - 0.594285714285711*G0_0_0_3_0_0 - 0.0888888888888882*G0_0_0_3_0_1 + 0.259047619047609*G0_0_0_4_0_0 - 0.454603174603177*G0_0_0_4_0_1 + 0.0761904761904725*G0_0_0_5_0_0 - 0.0177777777777827*G0_0_0_5_0_1 - 0.259047619047609*G0_0_0_6_0_0 - 0.322539682539674*G0_0_0_6_0_1 - 0.294603174603176*G0_0_0_7_0_0 - 0.200634920634921*G0_0_0_7_0_1 + 0.162539682539683*G0_0_0_8_0_0 + 0.0888888888888883*G0_0_0_8_0_1 + 0.518095238095238*G0_0_0_9_0_0 + 0.655238095238098*G0_0_0_9_0_1 + 0.0897354497354514*G0_0_0_10_1_0 + 0.0897354497354515*G0_0_0_10_1_1 + 0.0423280423280416*G0_0_0_11_1_0 + 0.250582010582005*G0_0_0_12_1_1 - 0.594285714285711*G0_0_0_13_1_0 - 0.0888888888888882*G0_0_0_13_1_1 + 0.259047619047609*G0_0_0_14_1_0 - 0.454603174603177*G0_0_0_14_1_1 + 0.0761904761904725*G0_0_0_15_1_0 - 0.0177777777777827*G0_0_0_15_1_1 - 0.259047619047609*G0_0_0_16_1_0 - 0.322539682539674*G0_0_0_16_1_1 - 0.294603174603176*G0_0_0_17_1_0 - 0.200634920634921*G0_0_0_17_1_1 + 0.162539682539683*G0_0_0_18_1_0 + 0.0888888888888883*G0_0_0_18_1_1 + 0.518095238095238*G0_0_0_19_1_0 + 0.655238095238098*G0_0_0_19_1_1 - 0.0355555555555579*G0_0_1_1_0_0 + 0.0355555555555547*G0_0_1_2_0_1 - 0.0126984126984111*G0_0_1_3_0_0 - 0.0482539682539707*G0_0_1_3_0_1 + 0.0482539682539675*G0_0_1_4_0_0 + 0.0126984126984145*G0_0_1_4_0_1 + 0.0584126984126986*G0_0_1_5_0_0 + 0.0584126984126984*G0_0_1_5_0_1 - 0.0482539682539675*G0_0_1_6_0_0 - 0.0939682539682538*G0_0_1_6_0_1 - 0.0584126984127015*G0_0_1_7_0_0 - 0.0584126984127007*G0_0_1_7_0_1 + 0.0939682539682583*G0_0_1_8_0_0 + 0.0482539682539706*G0_0_1_8_0_1 - 0.0457142857142876*G0_0_1_9_0_0 + 0.0457142857142865*G0_0_1_9_0_1 - 0.0355555555555579*G0_0_1_11_1_0 + 0.0355555555555547*G0_0_1_12_1_1 - 0.0126984126984111*G0_0_1_13_1_0 - 0.0482539682539707*G0_0_1_13_1_1 + 0.0482539682539675*G0_0_1_14_1_0 + 0.0126984126984145*G0_0_1_14_1_1 + 0.0584126984126986*G0_0_1_15_1_0 + 0.0584126984126984*G0_0_1_15_1_1 - 0.0482539682539675*G0_0_1_16_1_0 - 0.0939682539682538*G0_0_1_16_1_1 - 0.0584126984127015*G0_0_1_17_1_0 - 0.0584126984127007*G0_0_1_17_1_1 + 0.0939682539682583*G0_0_1_18_1_0 + 0.0482539682539706*G0_0_1_18_1_1 - 0.0457142857142876*G0_0_1_19_1_0 + 0.0457142857142865*G0_0_1_19_1_1 - 0.152380952380953*G0_1_0_1_0_0 + 0.152380952380951*G0_1_0_2_0_1 - 0.152380952380955*G0_1_0_3_0_0 - 0.304761904761908*G0_1_0_3_0_1 + 0.304761904761902*G0_1_0_4_0_0 + 0.152380952380951*G0_1_0_4_0_1 + 0.152380952380947*G0_1_0_5_0_0 + 0.152380952380952*G0_1_0_5_0_1 - 0.304761904761902*G0_1_0_6_0_0 - 0.304761904761902*G0_1_0_6_0_1 - 0.152380952380951*G0_1_0_7_0_0 - 0.152380952380956*G0_1_0_7_0_1 + 0.304761904761905*G0_1_0_8_0_0 + 0.304761904761908*G0_1_0_8_0_1 - 0.152380952380953*G0_1_0_11_1_0 + 0.152380952380951*G0_1_0_12_1_1 - 0.152380952380955*G0_1_0_13_1_0 - 0.304761904761908*G0_1_0_13_1_1 + 0.304761904761902*G0_1_0_14_1_0 + 0.152380952380951*G0_1_0_14_1_1 + 0.152380952380947*G0_1_0_15_1_0 + 0.152380952380952*G0_1_0_15_1_1 - 0.304761904761902*G0_1_0_16_1_0 - 0.304761904761902*G0_1_0_16_1_1 - 0.152380952380951*G0_1_0_17_1_0 - 0.152380952380956*G0_1_0_17_1_1 + 0.304761904761905*G0_1_0_18_1_0 + 0.304761904761908*G0_1_0_18_1_1 - 0.0897354497354552*G0_1_1_0_0_0 - 0.0897354497354554*G0_1_1_0_0_1 - 0.25058201058201*G0_1_1_1_0_0 - 0.0423280423280422*G0_1_1_2_0_1 + 0.454603174603174*G0_1_1_3_0_0 - 0.259047619047619*G0_1_1_3_0_1 + 0.088888888888887*G0_1_1_4_0_0 + 0.594285714285713*G0_1_1_4_0_1 + 0.200634920634917*G0_1_1_5_0_0 + 0.294603174603183*G0_1_1_5_0_1 - 0.0888888888888868*G0_1_1_6_0_0 - 0.162539682539685*G0_1_1_6_0_1 + 0.0177777777777857*G0_1_1_7_0_0 - 0.0761904761904796*G0_1_1_7_0_1 + 0.322539682539679*G0_1_1_8_0_0 + 0.259047619047619*G0_1_1_8_0_1 - 0.655238095238092*G0_1_1_9_0_0 - 0.518095238095233*G0_1_1_9_0_1 - 0.0897354497354552*G0_1_1_10_1_0 - 0.0897354497354554*G0_1_1_10_1_1 - 0.25058201058201*G0_1_1_11_1_0 - 0.0423280423280422*G0_1_1_12_1_1 + 0.454603174603174*G0_1_1_13_1_0 - 0.259047619047619*G0_1_1_13_1_1 + 0.088888888888887*G0_1_1_14_1_0 + 0.594285714285713*G0_1_1_14_1_1 + 0.200634920634917*G0_1_1_15_1_0 + 0.294603174603183*G0_1_1_15_1_1 - 0.0888888888888868*G0_1_1_16_1_0 - 0.162539682539685*G0_1_1_16_1_1 + 0.0177777777777857*G0_1_1_17_1_0 - 0.0761904761904796*G0_1_1_17_1_1 + 0.322539682539679*G0_1_1_18_1_0 + 0.259047619047619*G0_1_1_18_1_1 - 0.655238095238092*G0_1_1_19_1_0 - 0.518095238095233*G0_1_1_19_1_1; + A[851] = 0.0; + A[880] = 0.0; + A[481] = 0.0; + A[200] = 0.0; + A[582] = 0.0; + A[522] = 0.0; + A[227] = 0.0; + A[615] = A[5] + 0.0165079365079362*G0_0_1_1_0_0 + 0.113015873015874*G0_0_1_2_0_1 - 0.164444444444444*G0_0_1_3_0_0 - 0.0184126984126989*G0_0_1_3_0_1 + 0.147936507936511*G0_0_1_4_0_0 - 0.0946031746031725*G0_0_1_4_0_1 + 0.0615873015873032*G0_0_1_5_0_0 + 0.0615873015873022*G0_0_1_5_0_1 - 0.147936507936511*G0_0_1_6_0_0 - 0.174603174603177*G0_0_1_6_0_1 - 0.0615873015873022*G0_0_1_7_0_0 - 0.0615873015873011*G0_0_1_7_0_1 + 0.0450793650793658*G0_0_1_8_0_0 + 0.0184126984126989*G0_0_1_8_0_1 + 0.102857142857141*G0_0_1_9_0_0 + 0.156190476190474*G0_0_1_9_0_1 + 0.0165079365079362*G0_0_1_11_1_0 + 0.113015873015874*G0_0_1_12_1_1 - 0.164444444444444*G0_0_1_13_1_0 - 0.0184126984126989*G0_0_1_13_1_1 + 0.147936507936511*G0_0_1_14_1_0 - 0.0946031746031725*G0_0_1_14_1_1 + 0.0615873015873032*G0_0_1_15_1_0 + 0.0615873015873022*G0_0_1_15_1_1 - 0.147936507936511*G0_0_1_16_1_0 - 0.174603174603177*G0_0_1_16_1_1 - 0.0615873015873022*G0_0_1_17_1_0 - 0.0615873015873011*G0_0_1_17_1_1 + 0.0450793650793658*G0_0_1_18_1_0 + 0.0184126984126989*G0_0_1_18_1_1 + 0.102857142857141*G0_0_1_19_1_0 + 0.156190476190474*G0_0_1_19_1_1 - 0.0165079365079362*G0_1_0_1_0_0 - 0.113015873015874*G0_1_0_2_0_1 + 0.164444444444444*G0_1_0_3_0_0 + 0.0184126984126989*G0_1_0_3_0_1 - 0.147936507936511*G0_1_0_4_0_0 + 0.0946031746031725*G0_1_0_4_0_1 - 0.0615873015873033*G0_1_0_5_0_0 - 0.0615873015873022*G0_1_0_5_0_1 + 0.147936507936511*G0_1_0_6_0_0 + 0.174603174603177*G0_1_0_6_0_1 + 0.0615873015873022*G0_1_0_7_0_0 + 0.0615873015873011*G0_1_0_7_0_1 - 0.0450793650793658*G0_1_0_8_0_0 - 0.0184126984126989*G0_1_0_8_0_1 - 0.102857142857141*G0_1_0_9_0_0 - 0.156190476190474*G0_1_0_9_0_1 - 0.0165079365079362*G0_1_0_11_1_0 - 0.113015873015874*G0_1_0_12_1_1 + 0.164444444444444*G0_1_0_13_1_0 + 0.0184126984126989*G0_1_0_13_1_1 - 0.147936507936511*G0_1_0_14_1_0 + 0.0946031746031725*G0_1_0_14_1_1 - 0.0615873015873033*G0_1_0_15_1_0 - 0.0615873015873022*G0_1_0_15_1_1 + 0.147936507936511*G0_1_0_16_1_0 + 0.174603174603177*G0_1_0_16_1_1 + 0.0615873015873022*G0_1_0_17_1_0 + 0.0615873015873011*G0_1_0_17_1_1 - 0.0450793650793658*G0_1_0_18_1_0 - 0.0184126984126989*G0_1_0_18_1_1 - 0.102857142857141*G0_1_0_19_1_0 - 0.156190476190474*G0_1_0_19_1_1; + A[551] = 0.0; + A[708] = -A[716] + 0.0135449735449745*G0_0_0_0_0_0 + 0.0135449735449744*G0_0_0_0_0_1 - 0.440211640211639*G0_0_0_1_0_0 - 1.35449735449735*G0_0_0_2_0_1 + 1.74730158730157*G0_0_0_3_0_0 - 0.0507936507936532*G0_0_0_3_0_1 - 2.33650793650792*G0_0_0_4_0_0 + 0.375873015873014*G0_0_0_4_0_1 - 0.284444444444444*G0_0_0_5_0_0 - 0.213333333333334*G0_0_0_5_0_1 + 2.33650793650792*G0_0_0_6_0_0 + 1.55428571428571*G0_0_0_6_0_1 + 0.24380952380952*G0_0_0_7_0_0 + 0.172698412698409*G0_0_0_7_0_1 + 0.182857142857145*G0_0_0_8_0_0 + 0.0507936507936529*G0_0_0_8_0_1 - 1.46285714285713*G0_0_0_9_0_0 - 0.548571428571423*G0_0_0_9_0_1 + 0.0135449735449745*G0_0_0_10_1_0 + 0.0135449735449744*G0_0_0_10_1_1 - 0.440211640211639*G0_0_0_11_1_0 - 1.35449735449735*G0_0_0_12_1_1 + 1.74730158730157*G0_0_0_13_1_0 - 0.0507936507936532*G0_0_0_13_1_1 - 2.33650793650792*G0_0_0_14_1_0 + 0.375873015873014*G0_0_0_14_1_1 - 0.284444444444444*G0_0_0_15_1_0 - 0.213333333333334*G0_0_0_15_1_1 + 2.33650793650792*G0_0_0_16_1_0 + 1.55428571428571*G0_0_0_16_1_1 + 0.24380952380952*G0_0_0_17_1_0 + 0.172698412698409*G0_0_0_17_1_1 + 0.182857142857145*G0_0_0_18_1_0 + 0.0507936507936529*G0_0_0_18_1_1 - 1.46285714285713*G0_0_0_19_1_0 - 0.548571428571423*G0_0_0_19_1_1 + 0.142222222222221*G0_1_0_0_0_0 + 0.14222222222222*G0_1_0_0_0_1 - 0.528253968253965*G0_1_0_2_0_1 + 0.132063492063487*G0_1_0_3_0_0 - 0.782222222222217*G0_1_0_4_0_0 - 0.121904761904762*G0_1_0_4_0_1 - 0.924444444444442*G0_1_0_5_0_0 - 0.812698412698407*G0_1_0_5_0_1 + 0.782222222222217*G0_1_0_6_0_0 + 1.19873015873015*G0_1_0_6_0_1 - 0.0101587301587298*G0_1_0_7_0_0 - 0.121904761904765*G0_1_0_7_0_1 - 0.132063492063488*G0_1_0_8_0_0 + 0.792380952380955*G0_1_0_9_0_0 + 0.243809523809527*G0_1_0_9_0_1 + 0.142222222222221*G0_1_0_10_1_0 + 0.14222222222222*G0_1_0_10_1_1 - 0.528253968253965*G0_1_0_12_1_1 + 0.132063492063487*G0_1_0_13_1_0 - 0.782222222222217*G0_1_0_14_1_0 - 0.121904761904762*G0_1_0_14_1_1 - 0.924444444444442*G0_1_0_15_1_0 - 0.812698412698407*G0_1_0_15_1_1 + 0.782222222222217*G0_1_0_16_1_0 + 1.19873015873015*G0_1_0_16_1_1 - 0.0101587301587298*G0_1_0_17_1_0 - 0.121904761904765*G0_1_0_17_1_1 - 0.132063492063488*G0_1_0_18_1_0 + 0.792380952380955*G0_1_0_19_1_0 + 0.243809523809527*G0_1_0_19_1_1; + A[644] = 0.0; + A[253] = A[718]; + A[673] = 0.0; + A[278] = A[743]; + A[698] = 0.0; + A[315] = 0.0; + A[259] = 0.0; + A[344] = -A[569] + 0.352169312169311*G0_0_0_0_0_0 + 0.352169312169311*G0_0_0_0_0_1 + 0.541798941798936*G0_0_0_1_0_0 + 1.61862433862433*G0_0_0_2_0_1 - 2.98666666666665*G0_0_0_3_0_0 - 0.507936507936508*G0_0_0_3_0_1 + 3.71809523809521*G0_0_0_4_0_0 + 0.162539682539682*G0_0_0_4_0_1 - 1.64571428571428*G0_0_0_5_0_0 - 1.62539682539682*G0_0_0_5_0_1 - 3.71809523809522*G0_0_0_6_0_0 - 0.345396825396824*G0_0_0_6_0_1 - 0.629841269841268*G0_0_0_7_0_0 - 0.650158730158726*G0_0_0_7_0_1 - 0.26412698412698*G0_0_0_8_0_0 + 0.507936507936508*G0_0_0_8_0_1 + 4.63238095238092*G0_0_0_9_0_0 + 0.487619047619044*G0_0_0_9_0_1 + 0.352169312169311*G0_0_0_10_1_0 + 0.352169312169311*G0_0_0_10_1_1 + 0.541798941798936*G0_0_0_11_1_0 + 1.61862433862433*G0_0_0_12_1_1 - 2.98666666666665*G0_0_0_13_1_0 - 0.507936507936508*G0_0_0_13_1_1 + 3.71809523809521*G0_0_0_14_1_0 + 0.162539682539682*G0_0_0_14_1_1 - 1.64571428571428*G0_0_0_15_1_0 - 1.62539682539682*G0_0_0_15_1_1 - 3.71809523809522*G0_0_0_16_1_0 - 0.345396825396824*G0_0_0_16_1_1 - 0.629841269841268*G0_0_0_17_1_0 - 0.650158730158726*G0_0_0_17_1_1 - 0.26412698412698*G0_0_0_18_1_0 + 0.507936507936508*G0_0_0_18_1_1 + 4.63238095238092*G0_0_0_19_1_0 + 0.487619047619044*G0_0_0_19_1_1 - 0.345396825396823*G0_0_1_0_0_0 - 0.345396825396823*G0_0_1_0_0_1 + 0.142222222222223*G0_0_1_2_0_1 + 0.711111111111111*G0_0_1_3_0_0 + 0.65015873015873*G0_0_1_4_0_0 + 1.21904761904762*G0_0_1_4_0_1 + 0.995555555555555*G0_0_1_5_0_0 + 0.833015873015868*G0_0_1_5_0_1 - 0.65015873015873*G0_0_1_6_0_0 - 0.629841269841269*G0_0_1_6_0_1 + 1.05650793650793*G0_0_1_7_0_0 + 1.21904761904762*G0_0_1_7_0_1 - 0.711111111111111*G0_0_1_8_0_0 - 1.70666666666667*G0_0_1_9_0_0 - 2.43809523809523*G0_0_1_9_0_1 - 0.345396825396823*G0_0_1_10_1_0 - 0.345396825396823*G0_0_1_10_1_1 + 0.142222222222223*G0_0_1_12_1_1 + 0.711111111111111*G0_0_1_13_1_0 + 0.65015873015873*G0_0_1_14_1_0 + 1.21904761904762*G0_0_1_14_1_1 + 0.995555555555555*G0_0_1_15_1_0 + 0.833015873015868*G0_0_1_15_1_1 - 0.65015873015873*G0_0_1_16_1_0 - 0.629841269841269*G0_0_1_16_1_1 + 1.05650793650793*G0_0_1_17_1_0 + 1.21904761904762*G0_0_1_17_1_1 - 0.711111111111111*G0_0_1_18_1_0 - 1.70666666666667*G0_0_1_19_1_0 - 2.43809523809523*G0_0_1_19_1_1; + A[288] = 0.0; + A[742] = A[277]; + A[429] = A[830] + 0.474074074074075*G0_0_0_0_0_0 + 0.474074074074075*G0_0_0_0_0_1 - 0.108359788359789*G0_0_0_1_0_0 + 0.19640211640211*G0_0_0_2_0_1 + 0.18285714285714*G0_0_0_3_0_0 + 0.0609523809523798*G0_0_0_3_0_1 + 0.670476190476177*G0_0_0_4_0_0 + 0.487619047619039*G0_0_0_4_0_1 + 0.304761904761897*G0_0_0_5_0_0 - 0.609523809523815*G0_0_0_5_0_1 - 0.670476190476177*G0_0_0_6_0_0 - 0.0609523809523707*G0_0_0_6_0_1 - 0.914285714285715*G0_0_0_7_0_0 + 0.548571428571428*G0_0_0_8_0_0 - 0.0609523809523797*G0_0_0_8_0_1 - 0.487619047619038*G0_0_0_9_0_0 - 0.487619047619036*G0_0_0_9_0_1 + 0.474074074074075*G0_0_0_10_1_0 + 0.474074074074075*G0_0_0_10_1_1 - 0.108359788359789*G0_0_0_11_1_0 + 0.19640211640211*G0_0_0_12_1_1 + 0.18285714285714*G0_0_0_13_1_0 + 0.0609523809523798*G0_0_0_13_1_1 + 0.670476190476177*G0_0_0_14_1_0 + 0.487619047619039*G0_0_0_14_1_1 + 0.304761904761897*G0_0_0_15_1_0 - 0.609523809523815*G0_0_0_15_1_1 - 0.670476190476177*G0_0_0_16_1_0 - 0.0609523809523707*G0_0_0_16_1_1 - 0.914285714285715*G0_0_0_17_1_0 + 0.548571428571428*G0_0_0_18_1_0 - 0.0609523809523797*G0_0_0_18_1_1 - 0.487619047619038*G0_0_0_19_1_0 - 0.487619047619036*G0_0_0_19_1_1 - 0.196402116402118*G0_0_1_0_0_0 - 0.196402116402118*G0_0_1_0_0_1 + 0.135449735449733*G0_0_1_1_0_0 - 0.0474074074074067*G0_0_1_2_0_1 - 0.365714285714281*G0_0_1_3_0_0 - 0.182857142857143*G0_0_1_4_0_0 - 0.365714285714283*G0_0_1_4_0_1 - 0.731428571428566*G0_0_1_5_0_0 - 0.0609523809523738*G0_0_1_5_0_1 + 0.182857142857142*G0_0_1_6_0_0 + 0.304761904761898*G0_0_1_6_0_1 + 0.304761904761905*G0_0_1_7_0_0 - 0.365714285714287*G0_0_1_7_0_1 - 0.24380952380952*G0_0_1_8_0_0 + 1.09714285714285*G0_0_1_9_0_0 + 0.73142857142857*G0_0_1_9_0_1 - 0.196402116402118*G0_0_1_10_1_0 - 0.196402116402118*G0_0_1_10_1_1 + 0.135449735449733*G0_0_1_11_1_0 - 0.0474074074074067*G0_0_1_12_1_1 - 0.365714285714281*G0_0_1_13_1_0 - 0.182857142857143*G0_0_1_14_1_0 - 0.365714285714283*G0_0_1_14_1_1 - 0.731428571428566*G0_0_1_15_1_0 - 0.0609523809523738*G0_0_1_15_1_1 + 0.182857142857142*G0_0_1_16_1_0 + 0.304761904761898*G0_0_1_16_1_1 + 0.304761904761905*G0_0_1_17_1_0 - 0.365714285714287*G0_0_1_17_1_1 - 0.24380952380952*G0_0_1_18_1_0 + 1.09714285714285*G0_0_1_19_1_0 + 0.73142857142857*G0_0_1_19_1_1 + 0.230264550264555*G0_1_0_0_0_0 + 0.230264550264555*G0_1_0_0_0_1 - 0.352169312169311*G0_1_0_1_0_0 - 0.474074074074076*G0_1_0_2_0_1 + 1.03619047619047*G0_1_0_3_0_0 + 0.121904761904761*G0_1_0_3_0_1 - 0.914285714285718*G0_1_0_4_0_0 + 0.121904761904755*G0_1_0_4_0_1 - 0.182857142857147*G0_1_0_5_0_0 - 0.243809523809535*G0_1_0_5_0_1 + 0.914285714285718*G0_1_0_6_0_0 + 0.487619047619056*G0_1_0_6_0_1 - 0.914285714285719*G0_1_0_7_0_0 - 0.853333333333332*G0_1_0_7_0_1 + 1.03619047619047*G0_1_0_8_0_0 - 0.121904761904761*G0_1_0_8_0_1 - 0.853333333333322*G0_1_0_9_0_0 + 0.731428571428576*G0_1_0_9_0_1 + 0.230264550264555*G0_1_0_10_1_0 + 0.230264550264555*G0_1_0_10_1_1 - 0.352169312169311*G0_1_0_11_1_0 - 0.474074074074076*G0_1_0_12_1_1 + 1.03619047619047*G0_1_0_13_1_0 + 0.121904761904761*G0_1_0_13_1_1 - 0.914285714285718*G0_1_0_14_1_0 + 0.121904761904755*G0_1_0_14_1_1 - 0.182857142857147*G0_1_0_15_1_0 - 0.243809523809535*G0_1_0_15_1_1 + 0.914285714285718*G0_1_0_16_1_0 + 0.487619047619056*G0_1_0_16_1_1 - 0.914285714285719*G0_1_0_17_1_0 - 0.853333333333332*G0_1_0_17_1_1 + 1.03619047619047*G0_1_0_18_1_0 - 0.121904761904761*G0_1_0_18_1_1 - 0.853333333333322*G0_1_0_19_1_0 + 0.731428571428576*G0_1_0_19_1_1 - 0.243809523809524*G0_1_1_0_0_0 - 0.243809523809524*G0_1_1_0_0_1 - 0.243809523809523*G0_1_1_2_0_1 - 0.121904761904759*G0_1_1_3_0_0 - 0.853333333333332*G0_1_1_4_0_0 - 0.731428571428569*G0_1_1_4_0_1 - 0.609523809523807*G0_1_1_5_0_0 + 0.243809523809527*G0_1_1_5_0_1 + 0.853333333333332*G0_1_1_6_0_0 + 0.243809523809521*G0_1_1_6_0_1 + 0.121904761904764*G0_1_1_7_0_0 - 0.731428571428569*G0_1_1_7_0_1 + 0.121904761904761*G0_1_1_8_0_0 + 0.731428571428566*G0_1_1_9_0_0 + 1.46285714285714*G0_1_1_9_0_1 - 0.243809523809524*G0_1_1_10_1_0 - 0.243809523809524*G0_1_1_10_1_1 - 0.243809523809523*G0_1_1_12_1_1 - 0.121904761904759*G0_1_1_13_1_0 - 0.853333333333332*G0_1_1_14_1_0 - 0.731428571428569*G0_1_1_14_1_1 - 0.609523809523807*G0_1_1_15_1_0 + 0.243809523809527*G0_1_1_15_1_1 + 0.853333333333332*G0_1_1_16_1_0 + 0.243809523809521*G0_1_1_16_1_1 + 0.121904761904764*G0_1_1_17_1_0 - 0.731428571428569*G0_1_1_17_1_1 + 0.121904761904761*G0_1_1_18_1_0 + 0.731428571428566*G0_1_1_19_1_0 + 1.46285714285714*G0_1_1_19_1_1; + A[369] = A[834]; + A[50] = 0.0; + A[773] = A[308]; + A[462] = 0.0; + A[79] = 0.0; + A[800] = A[335]; + A[15] = 0.0; + A[835] = A[370]; + A[44] = A[509]; + A[842] = 0.0; + A[73] = A[538]; + A[150] = A[615]; + A[873] = 0.0; + A[106] = 0.0; + A[195] = 0.0; + A[591] = A[126]; + A[515] = 0.0; + A[224] = A[892] + 0.640000000000002*G0_0_1_0_0_0 + 0.640000000000002*G0_0_1_0_0_1 + 0.57904761904762*G0_0_1_1_0_0 + 0.609523809523814*G0_0_1_2_0_1 - 2.20952380952381*G0_0_1_3_0_0 - 0.0304761904761874*G0_0_1_3_0_1 + 1.44761904761906*G0_0_1_4_0_0 - 0.761904761904758*G0_0_1_4_0_1 - 0.990476190476185*G0_0_1_5_0_0 - 1.85904761904762*G0_0_1_5_0_1 - 1.44761904761906*G0_0_1_6_0_0 + 0.609523809523802*G0_0_1_6_0_1 - 0.472380952380957*G0_0_1_7_0_0 + 0.396190476190479*G0_0_1_7_0_1 - 0.746666666666665*G0_0_1_8_0_0 + 0.0304761904761872*G0_0_1_8_0_1 + 3.2*G0_0_1_9_0_0 + 0.36571428571428*G0_0_1_9_0_1 + 0.640000000000002*G0_0_1_10_1_0 + 0.640000000000002*G0_0_1_10_1_1 + 0.57904761904762*G0_0_1_11_1_0 + 0.609523809523814*G0_0_1_12_1_1 - 2.20952380952381*G0_0_1_13_1_0 - 0.0304761904761874*G0_0_1_13_1_1 + 1.44761904761906*G0_0_1_14_1_0 - 0.761904761904758*G0_0_1_14_1_1 - 0.990476190476185*G0_0_1_15_1_0 - 1.85904761904762*G0_0_1_15_1_1 - 1.44761904761906*G0_0_1_16_1_0 + 0.609523809523802*G0_0_1_16_1_1 - 0.472380952380957*G0_0_1_17_1_0 + 0.396190476190479*G0_0_1_17_1_1 - 0.746666666666665*G0_0_1_18_1_0 + 0.0304761904761872*G0_0_1_18_1_1 + 3.2*G0_0_1_19_1_0 + 0.36571428571428*G0_0_1_19_1_1 - 0.640000000000002*G0_1_0_0_0_0 - 0.640000000000002*G0_1_0_0_0_1 - 0.57904761904762*G0_1_0_1_0_0 - 0.609523809523814*G0_1_0_2_0_1 + 2.20952380952381*G0_1_0_3_0_0 + 0.0304761904761873*G0_1_0_3_0_1 - 1.44761904761906*G0_1_0_4_0_0 + 0.761904761904758*G0_1_0_4_0_1 + 0.990476190476185*G0_1_0_5_0_0 + 1.85904761904762*G0_1_0_5_0_1 + 1.44761904761906*G0_1_0_6_0_0 - 0.609523809523803*G0_1_0_6_0_1 + 0.472380952380957*G0_1_0_7_0_0 - 0.396190476190479*G0_1_0_7_0_1 + 0.746666666666666*G0_1_0_8_0_0 - 0.0304761904761872*G0_1_0_8_0_1 - 3.19999999999999*G0_1_0_9_0_0 - 0.36571428571428*G0_1_0_9_0_1 - 0.640000000000002*G0_1_0_10_1_0 - 0.640000000000002*G0_1_0_10_1_1 - 0.57904761904762*G0_1_0_11_1_0 - 0.609523809523814*G0_1_0_12_1_1 + 2.20952380952381*G0_1_0_13_1_0 + 0.0304761904761873*G0_1_0_13_1_1 - 1.44761904761906*G0_1_0_14_1_0 + 0.761904761904758*G0_1_0_14_1_1 + 0.990476190476185*G0_1_0_15_1_0 + 1.85904761904762*G0_1_0_15_1_1 + 1.44761904761906*G0_1_0_16_1_0 - 0.609523809523803*G0_1_0_16_1_1 + 0.472380952380957*G0_1_0_17_1_0 - 0.396190476190479*G0_1_0_17_1_1 + 0.746666666666666*G0_1_0_18_1_0 - 0.0304761904761872*G0_1_0_18_1_1 - 3.19999999999999*G0_1_0_19_1_0 - 0.36571428571428*G0_1_0_19_1_1; + A[134] = A[224] + 0.609523809523805*G0_0_0_0_0_0 + 0.609523809523806*G0_0_0_0_0_1 + 0.609523809523812*G0_0_0_1_0_0 - 4.57142857142857*G0_0_0_3_0_0 - 1.06666666666666*G0_0_0_3_0_1 - 2.89523809523808*G0_0_0_4_0_1 - 4.57142857142855*G0_0_0_5_0_0 - 3.50476190476189*G0_0_0_5_0_1 + 2.89523809523807*G0_0_0_6_0_1 - 0.609523809523807*G0_0_0_7_0_0 - 1.67619047619047*G0_0_0_7_0_1 - 0.609523809523811*G0_0_0_8_0_0 + 1.06666666666666*G0_0_0_8_0_1 + 9.14285714285711*G0_0_0_9_0_0 + 4.57142857142855*G0_0_0_9_0_1 + 0.609523809523805*G0_0_0_10_1_0 + 0.609523809523806*G0_0_0_10_1_1 + 0.609523809523812*G0_0_0_11_1_0 - 4.57142857142857*G0_0_0_13_1_0 - 1.06666666666666*G0_0_0_13_1_1 - 2.89523809523808*G0_0_0_14_1_1 - 4.57142857142855*G0_0_0_15_1_0 - 3.50476190476189*G0_0_0_15_1_1 + 2.89523809523807*G0_0_0_16_1_1 - 0.609523809523807*G0_0_0_17_1_0 - 1.67619047619047*G0_0_0_17_1_1 - 0.609523809523811*G0_0_0_18_1_0 + 1.06666666666666*G0_0_0_18_1_1 + 9.14285714285711*G0_0_0_19_1_0 + 4.57142857142855*G0_0_0_19_1_1 + 0.284444444444442*G0_0_1_0_0_0 + 0.284444444444442*G0_0_1_0_0_1 + 0.325079365079363*G0_0_1_1_0_0 + 1.57460317460316*G0_0_1_2_0_1 - 3.35238095238093*G0_0_1_3_0_0 - 0.639999999999997*G0_0_1_3_0_1 + 2.59047619047617*G0_0_1_4_0_0 - 1.37142857142857*G0_0_1_4_0_1 - 1.21904761904761*G0_0_1_5_0_0 - 0.792380952380949*G0_0_1_5_0_1 - 2.59047619047617*G0_0_1_6_0_0 - 1.06666666666666*G0_0_1_6_0_1 - 1.31047619047618*G0_0_1_7_0_0 - 1.73714285714284*G0_0_1_7_0_1 + 0.700952380952373*G0_0_1_8_0_0 + 0.639999999999998*G0_0_1_8_0_1 + 4.57142857142855*G0_0_1_9_0_0 + 3.10857142857141*G0_0_1_9_0_1 + 0.284444444444442*G0_0_1_10_1_0 + 0.284444444444442*G0_0_1_10_1_1 + 0.325079365079363*G0_0_1_11_1_0 + 1.57460317460316*G0_0_1_12_1_1 - 3.35238095238093*G0_0_1_13_1_0 - 0.639999999999997*G0_0_1_13_1_1 + 2.59047619047617*G0_0_1_14_1_0 - 1.37142857142857*G0_0_1_14_1_1 - 1.21904761904761*G0_0_1_15_1_0 - 0.792380952380949*G0_0_1_15_1_1 - 2.59047619047617*G0_0_1_16_1_0 - 1.06666666666666*G0_0_1_16_1_1 - 1.31047619047618*G0_0_1_17_1_0 - 1.73714285714284*G0_0_1_17_1_1 + 0.700952380952373*G0_0_1_18_1_0 + 0.639999999999998*G0_0_1_18_1_1 + 4.57142857142855*G0_0_1_19_1_0 + 3.10857142857141*G0_0_1_19_1_1 + 0.345396825396828*G0_1_0_0_0_0 + 0.345396825396828*G0_1_0_0_0_1 + 0.264126984126985*G0_1_0_1_0_0 + 2.79365079365079*G0_1_0_2_0_1 - 4.57142857142856*G0_1_0_3_0_0 - 1.53904761904761*G0_1_0_3_0_1 + 5.48571428571427*G0_1_0_4_0_0 - 0.0761904761904812*G0_1_0_4_0_1 - 0.472380952380957*G0_1_0_5_0_1 - 5.48571428571427*G0_1_0_6_0_0 - 2.66666666666666*G0_1_0_6_0_1 - 1.03619047619048*G0_1_0_7_0_0 - 0.56380952380952*G0_1_0_7_0_1 + 0.426666666666665*G0_1_0_8_0_0 + 1.53904761904761*G0_1_0_8_0_1 + 4.57142857142856*G0_1_0_9_0_0 + 0.640000000000001*G0_1_0_9_0_1 + 0.345396825396828*G0_1_0_10_1_0 + 0.345396825396828*G0_1_0_10_1_1 + 0.264126984126985*G0_1_0_11_1_0 + 2.79365079365079*G0_1_0_12_1_1 - 4.57142857142856*G0_1_0_13_1_0 - 1.53904761904761*G0_1_0_13_1_1 + 5.48571428571427*G0_1_0_14_1_0 - 0.0761904761904812*G0_1_0_14_1_1 - 0.472380952380957*G0_1_0_15_1_1 - 5.48571428571427*G0_1_0_16_1_0 - 2.66666666666666*G0_1_0_16_1_1 - 1.03619047619048*G0_1_0_17_1_0 - 0.56380952380952*G0_1_0_17_1_1 + 0.426666666666665*G0_1_0_18_1_0 + 1.53904761904761*G0_1_0_18_1_1 + 4.57142857142856*G0_1_0_19_1_0 + 0.640000000000001*G0_1_0_19_1_1 + 0.711111111111113*G0_1_1_0_0_0 + 0.711111111111113*G0_1_1_0_0_1 + 0.69079365079365*G0_1_1_1_0_0 + 2.18412698412697*G0_1_1_2_0_1 - 0.259047619047617*G0_1_1_3_0_0 + 1.55428571428571*G0_1_1_3_0_1 + 4.03809523809521*G0_1_1_4_0_0 + 0.731428571428565*G0_1_1_4_0_1 + 3.09333333333332*G0_1_1_5_0_0 + 0.426666666666653*G0_1_1_5_0_1 - 4.03809523809521*G0_1_1_6_0_0 - 3.32190476190474*G0_1_1_6_0_1 - 1.56952380952381*G0_1_1_7_0_0 + 1.09714285714286*G0_1_1_7_0_1 + 0.167619047619043*G0_1_1_8_0_0 - 1.55428571428571*G0_1_1_8_0_1 - 2.8342857142857*G0_1_1_9_0_0 - 1.82857142857142*G0_1_1_9_0_1 + 0.711111111111113*G0_1_1_10_1_0 + 0.711111111111113*G0_1_1_10_1_1 + 0.69079365079365*G0_1_1_11_1_0 + 2.18412698412697*G0_1_1_12_1_1 - 0.259047619047617*G0_1_1_13_1_0 + 1.55428571428571*G0_1_1_13_1_1 + 4.03809523809521*G0_1_1_14_1_0 + 0.731428571428565*G0_1_1_14_1_1 + 3.09333333333332*G0_1_1_15_1_0 + 0.426666666666653*G0_1_1_15_1_1 - 4.03809523809521*G0_1_1_16_1_0 - 3.32190476190474*G0_1_1_16_1_1 - 1.56952380952381*G0_1_1_17_1_0 + 1.09714285714286*G0_1_1_17_1_1 + 0.167619047619043*G0_1_1_18_1_0 - 1.55428571428571*G0_1_1_18_1_1 - 2.8342857142857*G0_1_1_19_1_0 - 1.82857142857142*G0_1_1_19_1_1; + A[314] = A[134] - 1.03619047619047*G0_0_0_0_0_0 - 1.03619047619047*G0_0_0_0_0_1 + 0.426666666666664*G0_0_0_1_0_0 + 2.65142857142856*G0_0_0_2_0_1 + 2.37714285714285*G0_0_0_3_0_0 + 0.807619047619044*G0_0_0_3_0_1 + 7.67999999999997*G0_0_0_4_0_0 + 7.02476190476188*G0_0_0_4_0_1 + 2.1942857142857*G0_0_0_5_0_0 + 1.93523809523809*G0_0_0_5_0_1 - 7.67999999999997*G0_0_0_6_0_0 - 3.55047619047617*G0_0_0_6_0_1 + 2.13333333333333*G0_0_0_7_0_0 + 2.39238095238094*G0_0_0_7_0_1 - 1.52380952380952*G0_0_0_8_0_0 - 0.807619047619044*G0_0_0_8_0_1 - 4.57142857142855*G0_0_0_9_0_0 - 9.41714285714282*G0_0_0_9_0_1 - 1.03619047619047*G0_0_0_10_1_0 - 1.03619047619047*G0_0_0_10_1_1 + 0.426666666666664*G0_0_0_11_1_0 + 2.65142857142856*G0_0_0_12_1_1 + 2.37714285714285*G0_0_0_13_1_0 + 0.807619047619044*G0_0_0_13_1_1 + 7.67999999999997*G0_0_0_14_1_0 + 7.02476190476188*G0_0_0_14_1_1 + 2.1942857142857*G0_0_0_15_1_0 + 1.93523809523809*G0_0_0_15_1_1 - 7.67999999999997*G0_0_0_16_1_0 - 3.55047619047617*G0_0_0_16_1_1 + 2.13333333333333*G0_0_0_17_1_0 + 2.39238095238094*G0_0_0_17_1_1 - 1.52380952380952*G0_0_0_18_1_0 - 0.807619047619044*G0_0_0_18_1_1 - 4.57142857142855*G0_0_0_19_1_0 - 9.41714285714282*G0_0_0_19_1_1 - 0.507936507936509*G0_0_1_0_0_0 - 0.507936507936509*G0_0_1_0_0_1 + 0.203174603174602*G0_0_1_1_0_0 + 0.538412698412704*G0_0_1_2_0_1 + 3.55047619047617*G0_0_1_3_0_0 + 1.37142857142856*G0_0_1_3_0_1 + 2.54476190476191*G0_0_1_4_0_0 + 4.38857142857141*G0_0_1_4_0_1 + 2.39238095238094*G0_0_1_5_0_0 + 1.40190476190476*G0_0_1_5_0_1 - 2.54476190476191*G0_0_1_6_0_0 - 1.43238095238096*G0_0_1_6_0_1 + 1.5695238095238*G0_0_1_7_0_0 + 2.55999999999998*G0_0_1_7_0_1 - 1.26476190476189*G0_0_1_8_0_0 - 1.37142857142856*G0_0_1_8_0_1 - 5.94285714285711*G0_0_1_9_0_0 - 6.94857142857139*G0_0_1_9_0_1 - 0.507936507936509*G0_0_1_10_1_0 - 0.507936507936509*G0_0_1_10_1_1 + 0.203174603174602*G0_0_1_11_1_0 + 0.538412698412704*G0_0_1_12_1_1 + 3.55047619047617*G0_0_1_13_1_0 + 1.37142857142856*G0_0_1_13_1_1 + 2.54476190476191*G0_0_1_14_1_0 + 4.38857142857141*G0_0_1_14_1_1 + 2.39238095238094*G0_0_1_15_1_0 + 1.40190476190476*G0_0_1_15_1_1 - 2.54476190476191*G0_0_1_16_1_0 - 1.43238095238096*G0_0_1_16_1_1 + 1.5695238095238*G0_0_1_17_1_0 + 2.55999999999998*G0_0_1_17_1_1 - 1.26476190476189*G0_0_1_18_1_0 - 1.37142857142856*G0_0_1_18_1_1 - 5.94285714285711*G0_0_1_19_1_0 - 6.94857142857139*G0_0_1_19_1_1 - 0.264126984126983*G0_1_0_0_0_0 - 0.264126984126983*G0_1_0_0_0_1 + 0.507936507936508*G0_1_0_1_0_0 - 0.0711111111111083*G0_1_0_2_0_1 + 2.46857142857142*G0_1_0_3_0_0 + 1.52380952380952*G0_1_0_3_0_1 + 1.09714285714286*G0_1_0_4_0_0 + 2.62095238095238*G0_1_0_4_0_1 + 0.0914285714285648*G0_1_0_5_0_0 - 0.152380952380956*G0_1_0_5_0_1 - 1.09714285714286*G0_1_0_6_0_0 + 0.487619047619048*G0_1_0_6_0_1 + 1.15809523809523*G0_1_0_7_0_0 + 1.40190476190475*G0_1_0_7_0_1 - 1.40190476190476*G0_1_0_8_0_0 - 1.52380952380952*G0_1_0_8_0_1 - 2.55999999999998*G0_1_0_9_0_0 - 4.02285714285713*G0_1_0_9_0_1 - 0.264126984126983*G0_1_0_10_1_0 - 0.264126984126983*G0_1_0_10_1_1 + 0.507936507936508*G0_1_0_11_1_0 - 0.0711111111111083*G0_1_0_12_1_1 + 2.46857142857142*G0_1_0_13_1_0 + 1.52380952380952*G0_1_0_13_1_1 + 1.09714285714286*G0_1_0_14_1_0 + 2.62095238095238*G0_1_0_14_1_1 + 0.0914285714285648*G0_1_0_15_1_0 - 0.152380952380956*G0_1_0_15_1_1 - 1.09714285714286*G0_1_0_16_1_0 + 0.487619047619048*G0_1_0_16_1_1 + 1.15809523809523*G0_1_0_17_1_0 + 1.40190476190475*G0_1_0_17_1_1 - 1.40190476190476*G0_1_0_18_1_0 - 1.52380952380952*G0_1_0_18_1_1 - 2.55999999999998*G0_1_0_19_1_0 - 4.02285714285713*G0_1_0_19_1_1 - 0.426666666666666*G0_1_1_0_0_0 - 0.426666666666666*G0_1_1_0_0_1 + 0.121904761904764*G0_1_1_2_0_1 + 0.15238095238095*G0_1_1_3_0_0 - 0.0304761904761845*G0_1_1_4_0_0 + 0.396190476190474*G0_1_1_5_0_0 + 0.975238095238094*G0_1_1_5_0_1 + 0.0304761904761845*G0_1_1_6_0_0 - 0.670476190476192*G0_1_1_6_0_1 + 0.579047619047615*G0_1_1_7_0_0 - 0.152380952380944*G0_1_1_8_0_0 - 0.548571428571424*G0_1_1_9_0_0 - 0.426666666666666*G0_1_1_10_1_0 - 0.426666666666666*G0_1_1_10_1_1 + 0.121904761904764*G0_1_1_12_1_1 + 0.15238095238095*G0_1_1_13_1_0 - 0.0304761904761845*G0_1_1_14_1_0 + 0.396190476190474*G0_1_1_15_1_0 + 0.975238095238094*G0_1_1_15_1_1 + 0.0304761904761845*G0_1_1_16_1_0 - 0.670476190476192*G0_1_1_16_1_1 + 0.579047619047615*G0_1_1_17_1_0 - 0.152380952380944*G0_1_1_18_1_0 - 0.548571428571424*G0_1_1_19_1_0; + A[394] = A[134] - 0.294603174603175*G0_0_0_0_0_0 - 0.294603174603175*G0_0_0_0_0_1 + 0.812698412698408*G0_0_0_1_0_0 + 3.25079365079363*G0_0_0_2_0_1 + 0.0914285714285796*G0_0_0_3_0_0 + 0.60952380952381*G0_0_0_3_0_1 + 9.1428571428571*G0_0_0_4_0_0 + 6.18666666666665*G0_0_0_4_0_1 + 0.091428571428571*G0_0_0_5_0_0 - 0.426666666666662*G0_0_0_5_0_1 - 9.14285714285711*G0_0_0_6_0_0 - 2.5295238095238*G0_0_0_6_0_1 + 0.792380952380952*G0_0_0_7_0_0 + 1.31047619047619*G0_0_0_7_0_1 - 1.31047619047619*G0_0_0_8_0_0 - 0.609523809523809*G0_0_0_8_0_1 - 0.182857142857151*G0_0_0_9_0_0 - 7.49714285714284*G0_0_0_9_0_1 - 0.294603174603175*G0_0_0_10_1_0 - 0.294603174603175*G0_0_0_10_1_1 + 0.812698412698408*G0_0_0_11_1_0 + 3.25079365079363*G0_0_0_12_1_1 + 0.0914285714285796*G0_0_0_13_1_0 + 0.60952380952381*G0_0_0_13_1_1 + 9.1428571428571*G0_0_0_14_1_0 + 6.18666666666665*G0_0_0_14_1_1 + 0.091428571428571*G0_0_0_15_1_0 - 0.426666666666662*G0_0_0_15_1_1 - 9.14285714285711*G0_0_0_16_1_0 - 2.5295238095238*G0_0_0_16_1_1 + 0.792380952380952*G0_0_0_17_1_0 + 1.31047619047619*G0_0_0_17_1_1 - 1.31047619047619*G0_0_0_18_1_0 - 0.609523809523809*G0_0_0_18_1_1 - 0.182857142857151*G0_0_0_19_1_0 - 7.49714285714284*G0_0_0_19_1_1 - 0.959999999999994*G0_0_1_1_0_0 + 0.960000000000002*G0_0_1_2_0_1 - 1.14285714285714*G0_0_1_3_0_0 - 2.10285714285713*G0_0_1_3_0_1 + 2.10285714285714*G0_0_1_4_0_0 + 1.14285714285714*G0_0_1_4_0_1 + 0.777142857142851*G0_0_1_5_0_0 + 0.777142857142856*G0_0_1_5_0_1 - 2.10285714285714*G0_0_1_6_0_0 - 1.73714285714286*G0_0_1_6_0_1 - 0.777142857142855*G0_0_1_7_0_0 - 0.777142857142862*G0_0_1_7_0_1 + 1.73714285714285*G0_0_1_8_0_0 + 2.10285714285713*G0_0_1_8_0_1 + 0.365714285714289*G0_0_1_9_0_0 - 0.365714285714278*G0_0_1_9_0_1 - 0.959999999999994*G0_0_1_11_1_0 + 0.960000000000002*G0_0_1_12_1_1 - 1.14285714285714*G0_0_1_13_1_0 - 2.10285714285713*G0_0_1_13_1_1 + 2.10285714285714*G0_0_1_14_1_0 + 1.14285714285714*G0_0_1_14_1_1 + 0.777142857142851*G0_0_1_15_1_0 + 0.777142857142856*G0_0_1_15_1_1 - 2.10285714285714*G0_0_1_16_1_0 - 1.73714285714286*G0_0_1_16_1_1 - 0.777142857142855*G0_0_1_17_1_0 - 0.777142857142862*G0_0_1_17_1_1 + 1.73714285714285*G0_0_1_18_1_0 + 2.10285714285713*G0_0_1_18_1_1 + 0.365714285714289*G0_0_1_19_1_0 - 0.365714285714278*G0_0_1_19_1_1 + 0.289523809523814*G0_1_0_1_0_0 - 0.289523809523802*G0_1_0_2_0_1 - 0.0761904761904741*G0_1_0_3_0_0 + 0.213333333333343*G0_1_0_3_0_1 - 0.21333333333332*G0_1_0_4_0_0 + 0.0761904761904795*G0_1_0_4_0_1 - 0.655238095238091*G0_1_0_5_0_0 - 0.655238095238091*G0_1_0_5_0_1 + 0.21333333333332*G0_1_0_6_0_0 + 0.944761904761894*G0_1_0_6_0_1 + 0.655238095238095*G0_1_0_7_0_0 + 0.655238095238095*G0_1_0_7_0_1 - 0.944761904761907*G0_1_0_8_0_0 - 0.213333333333344*G0_1_0_8_0_1 + 0.731428571428565*G0_1_0_9_0_0 - 0.731428571428574*G0_1_0_9_0_1 + 0.289523809523814*G0_1_0_11_1_0 - 0.289523809523802*G0_1_0_12_1_1 - 0.0761904761904741*G0_1_0_13_1_0 + 0.213333333333343*G0_1_0_13_1_1 - 0.21333333333332*G0_1_0_14_1_0 + 0.0761904761904795*G0_1_0_14_1_1 - 0.655238095238091*G0_1_0_15_1_0 - 0.655238095238091*G0_1_0_15_1_1 + 0.21333333333332*G0_1_0_16_1_0 + 0.944761904761894*G0_1_0_16_1_1 + 0.655238095238095*G0_1_0_17_1_0 + 0.655238095238095*G0_1_0_17_1_1 - 0.944761904761907*G0_1_0_18_1_0 - 0.213333333333344*G0_1_0_18_1_1 + 0.731428571428565*G0_1_0_19_1_0 - 0.731428571428574*G0_1_0_19_1_1 + 0.294603174603172*G0_1_1_0_0_0 + 0.294603174603171*G0_1_1_0_0_1 - 3.25079365079364*G0_1_1_1_0_0 - 0.812698412698402*G0_1_1_2_0_1 - 6.18666666666664*G0_1_1_3_0_0 - 9.1428571428571*G0_1_1_3_0_1 - 0.6095238095238*G0_1_1_4_0_0 - 0.0914285714285747*G0_1_1_4_0_1 - 1.31047619047618*G0_1_1_5_0_0 - 0.792380952380943*G0_1_1_5_0_1 + 0.609523809523798*G0_1_1_6_0_0 + 1.31047619047617*G0_1_1_6_0_1 + 0.426666666666664*G0_1_1_7_0_0 - 0.0914285714285761*G0_1_1_7_0_1 + 2.5295238095238*G0_1_1_8_0_0 + 9.1428571428571*G0_1_1_8_0_1 + 7.49714285714282*G0_1_1_9_0_0 + 0.182857142857146*G0_1_1_9_0_1 + 0.294603174603172*G0_1_1_10_1_0 + 0.294603174603171*G0_1_1_10_1_1 - 3.25079365079364*G0_1_1_11_1_0 - 0.812698412698402*G0_1_1_12_1_1 - 6.18666666666664*G0_1_1_13_1_0 - 9.1428571428571*G0_1_1_13_1_1 - 0.6095238095238*G0_1_1_14_1_0 - 0.0914285714285747*G0_1_1_14_1_1 - 1.31047619047618*G0_1_1_15_1_0 - 0.792380952380943*G0_1_1_15_1_1 + 0.609523809523798*G0_1_1_16_1_0 + 1.31047619047617*G0_1_1_16_1_1 + 0.426666666666664*G0_1_1_17_1_0 - 0.0914285714285761*G0_1_1_17_1_1 + 2.5295238095238*G0_1_1_18_1_0 + 9.1428571428571*G0_1_1_18_1_1 + 7.49714285714282*G0_1_1_19_1_0 + 0.182857142857146*G0_1_1_19_1_1; + A[599] = A[134]; + A[688] = A[394] - 0.426666666666661*G0_0_0_0_0_0 - 0.426666666666661*G0_0_0_0_0_1 + 0.121904761904761*G0_0_0_1_0_0 - 0.0304761904761955*G0_0_0_3_0_1 + 0.15238095238094*G0_0_0_4_0_1 + 0.579047619047605*G0_0_0_5_0_1 - 0.152380952380939*G0_0_0_6_0_1 + 0.975238095238086*G0_0_0_7_0_0 + 0.396190476190469*G0_0_0_7_0_1 - 0.670476190476186*G0_0_0_8_0_0 + 0.0304761904761958*G0_0_0_8_0_1 - 0.548571428571409*G0_0_0_9_0_1 - 0.426666666666661*G0_0_0_10_1_0 - 0.426666666666661*G0_0_0_10_1_1 + 0.121904761904761*G0_0_0_11_1_0 - 0.0304761904761955*G0_0_0_13_1_1 + 0.15238095238094*G0_0_0_14_1_1 + 0.579047619047605*G0_0_0_15_1_1 - 0.152380952380939*G0_0_0_16_1_1 + 0.975238095238086*G0_0_0_17_1_0 + 0.396190476190469*G0_0_0_17_1_1 - 0.670476190476186*G0_0_0_18_1_0 + 0.0304761904761958*G0_0_0_18_1_1 - 0.548571428571409*G0_0_0_19_1_1 - 0.843174603174596*G0_0_1_0_0_0 - 0.843174603174596*G0_0_1_0_0_1 + 0.538412698412692*G0_0_1_1_0_0 - 0.132063492063496*G0_0_1_2_0_1 + 4.67809523809521*G0_0_1_3_0_0 + 2.54476190476188*G0_0_1_3_0_1 + 0.655238095238088*G0_0_1_4_0_0 + 3.4590476190476*G0_0_1_4_0_1 + 2.1790476190476*G0_0_1_5_0_0 + 1.90476190476189*G0_0_1_5_0_1 - 0.655238095238086*G0_0_1_6_0_0 - 0.929523809523796*G0_0_1_6_0_1 + 2.02666666666665*G0_0_1_7_0_0 + 2.30095238095237*G0_0_1_7_0_1 - 1.72190476190475*G0_0_1_8_0_0 - 2.54476190476188*G0_0_1_8_0_1 - 6.85714285714282*G0_0_1_9_0_0 - 5.75999999999997*G0_0_1_9_0_1 - 0.843174603174596*G0_0_1_10_1_0 - 0.843174603174596*G0_0_1_10_1_1 + 0.538412698412692*G0_0_1_11_1_0 - 0.132063492063496*G0_0_1_12_1_1 + 4.67809523809521*G0_0_1_13_1_0 + 2.54476190476188*G0_0_1_13_1_1 + 0.655238095238088*G0_0_1_14_1_0 + 3.4590476190476*G0_0_1_14_1_1 + 2.1790476190476*G0_0_1_15_1_0 + 1.90476190476189*G0_0_1_15_1_1 - 0.655238095238086*G0_0_1_16_1_0 - 0.929523809523796*G0_0_1_16_1_1 + 2.02666666666665*G0_0_1_17_1_0 + 2.30095238095237*G0_0_1_17_1_1 - 1.72190476190475*G0_0_1_18_1_0 - 2.54476190476188*G0_0_1_18_1_1 - 6.85714285714282*G0_0_1_19_1_0 - 5.75999999999997*G0_0_1_19_1_1 + 0.0711111111111112*G0_1_0_0_0_0 + 0.0711111111111112*G0_1_0_0_0_1 - 0.0711111111111147*G0_1_0_1_0_0 + 0.843174603174593*G0_1_0_2_0_1 + 2.33142857142856*G0_1_0_3_0_0 + 1.09714285714284*G0_1_0_3_0_1 + 2.23999999999998*G0_1_0_4_0_0 + 2.55999999999999*G0_1_0_4_0_1 + 1.78285714285713*G0_1_0_5_0_0 + 0.822857142857134*G0_1_0_5_0_1 - 2.23999999999998*G0_1_0_6_0_0 - 1.73714285714284*G0_1_0_6_0_1 - 0.777142857142852*G0_1_0_7_0_0 + 0.182857142857139*G0_1_0_7_0_1 + 0.777142857142855*G0_1_0_8_0_0 - 1.09714285714284*G0_1_0_8_0_1 - 4.11428571428568*G0_1_0_9_0_0 - 2.74285714285713*G0_1_0_9_0_1 + 0.0711111111111112*G0_1_0_10_1_0 + 0.0711111111111112*G0_1_0_10_1_1 - 0.0711111111111147*G0_1_0_11_1_0 + 0.843174603174593*G0_1_0_12_1_1 + 2.33142857142856*G0_1_0_13_1_0 + 1.09714285714284*G0_1_0_13_1_1 + 2.23999999999998*G0_1_0_14_1_0 + 2.55999999999999*G0_1_0_14_1_1 + 1.78285714285713*G0_1_0_15_1_0 + 0.822857142857134*G0_1_0_15_1_1 - 2.23999999999998*G0_1_0_16_1_0 - 1.73714285714284*G0_1_0_16_1_1 - 0.777142857142852*G0_1_0_17_1_0 + 0.182857142857139*G0_1_0_17_1_1 + 0.777142857142855*G0_1_0_18_1_0 - 1.09714285714284*G0_1_0_18_1_1 - 4.11428571428568*G0_1_0_19_1_0 - 2.74285714285713*G0_1_0_19_1_1 - 1.03619047619047*G0_1_1_0_0_0 - 1.03619047619047*G0_1_1_0_0_1 + 2.65142857142855*G0_1_1_1_0_0 + 0.426666666666659*G0_1_1_2_0_1 + 7.02476190476187*G0_1_1_3_0_0 + 7.67999999999995*G0_1_1_3_0_1 + 0.807619047619042*G0_1_1_4_0_0 + 2.37714285714285*G0_1_1_4_0_1 + 2.39238095238094*G0_1_1_5_0_0 + 2.13333333333331*G0_1_1_5_0_1 - 0.807619047619039*G0_1_1_6_0_0 - 1.52380952380951*G0_1_1_6_0_1 + 1.93523809523808*G0_1_1_7_0_0 + 2.1942857142857*G0_1_1_7_0_1 - 3.55047619047617*G0_1_1_8_0_0 - 7.67999999999996*G0_1_1_8_0_1 - 9.41714285714281*G0_1_1_9_0_0 - 4.57142857142855*G0_1_1_9_0_1 - 1.03619047619047*G0_1_1_10_1_0 - 1.03619047619047*G0_1_1_10_1_1 + 2.65142857142855*G0_1_1_11_1_0 + 0.426666666666659*G0_1_1_12_1_1 + 7.02476190476187*G0_1_1_13_1_0 + 7.67999999999995*G0_1_1_13_1_1 + 0.807619047619042*G0_1_1_14_1_0 + 2.37714285714285*G0_1_1_14_1_1 + 2.39238095238094*G0_1_1_15_1_0 + 2.13333333333331*G0_1_1_15_1_1 - 0.807619047619039*G0_1_1_16_1_0 - 1.52380952380951*G0_1_1_16_1_1 + 1.93523809523808*G0_1_1_17_1_0 + 2.1942857142857*G0_1_1_17_1_1 - 3.55047619047617*G0_1_1_18_1_0 - 7.67999999999996*G0_1_1_18_1_1 - 9.41714285714281*G0_1_1_19_1_0 - 4.57142857142855*G0_1_1_19_1_1; + A[779] = A[314]; + A[895] = A[314] - 0.335238095238089*G0_0_1_0_0_0 - 0.33523809523809*G0_0_1_0_0_1 - 0.335238095238092*G0_0_1_1_0_0 - 0.0914285714285735*G0_0_1_3_0_0 - 0.716190476190471*G0_0_1_3_0_1 + 0.289523809523806*G0_0_1_4_0_1 - 0.0914285714285757*G0_0_1_5_0_0 + 0.624761904761892*G0_0_1_5_0_1 - 0.289523809523802*G0_0_1_6_0_1 + 0.335238095238088*G0_0_1_7_0_0 - 0.380952380952379*G0_0_1_7_0_1 + 0.335238095238093*G0_0_1_8_0_0 + 0.71619047619047*G0_0_1_8_0_1 + 0.182857142857149*G0_0_1_9_0_0 + 0.091428571428573*G0_0_1_9_0_1 - 0.335238095238089*G0_0_1_10_1_0 - 0.33523809523809*G0_0_1_10_1_1 - 0.335238095238092*G0_0_1_11_1_0 - 0.0914285714285735*G0_0_1_13_1_0 - 0.716190476190471*G0_0_1_13_1_1 + 0.289523809523806*G0_0_1_14_1_1 - 0.0914285714285757*G0_0_1_15_1_0 + 0.624761904761892*G0_0_1_15_1_1 - 0.289523809523802*G0_0_1_16_1_1 + 0.335238095238088*G0_0_1_17_1_0 - 0.380952380952379*G0_0_1_17_1_1 + 0.335238095238093*G0_0_1_18_1_0 + 0.71619047619047*G0_0_1_18_1_1 + 0.182857142857149*G0_0_1_19_1_0 + 0.091428571428573*G0_0_1_19_1_1 + 0.335238095238089*G0_1_0_0_0_0 + 0.335238095238089*G0_1_0_0_0_1 + 0.335238095238092*G0_1_0_1_0_0 + 0.0914285714285736*G0_1_0_3_0_0 + 0.716190476190471*G0_1_0_3_0_1 - 0.289523809523806*G0_1_0_4_0_1 + 0.0914285714285756*G0_1_0_5_0_0 - 0.624761904761891*G0_1_0_5_0_1 + 0.289523809523801*G0_1_0_6_0_1 - 0.335238095238088*G0_1_0_7_0_0 + 0.380952380952379*G0_1_0_7_0_1 - 0.335238095238093*G0_1_0_8_0_0 - 0.71619047619047*G0_1_0_8_0_1 - 0.182857142857149*G0_1_0_9_0_0 - 0.0914285714285729*G0_1_0_9_0_1 + 0.335238095238089*G0_1_0_10_1_0 + 0.335238095238089*G0_1_0_10_1_1 + 0.335238095238092*G0_1_0_11_1_0 + 0.0914285714285736*G0_1_0_13_1_0 + 0.716190476190471*G0_1_0_13_1_1 - 0.289523809523806*G0_1_0_14_1_1 + 0.0914285714285756*G0_1_0_15_1_0 - 0.624761904761891*G0_1_0_15_1_1 + 0.289523809523801*G0_1_0_16_1_1 - 0.335238095238088*G0_1_0_17_1_0 + 0.380952380952379*G0_1_0_17_1_1 - 0.335238095238093*G0_1_0_18_1_0 - 0.71619047619047*G0_1_0_18_1_1 - 0.182857142857149*G0_1_0_19_1_0 - 0.0914285714285729*G0_1_0_19_1_1; + A[859] = A[394]; + A[397] = A[688] + 0.335238095238092*G0_0_1_0_0_0 + 0.335238095238092*G0_0_1_0_0_1 + 0.335238095238096*G0_0_1_2_0_1 - 0.289523809523808*G0_0_1_3_0_0 + 0.716190476190475*G0_0_1_4_0_0 + 0.0914285714285678*G0_0_1_4_0_1 + 0.380952380952381*G0_0_1_5_0_0 - 0.33523809523809*G0_0_1_5_0_1 - 0.716190476190476*G0_0_1_6_0_0 - 0.335238095238099*G0_0_1_6_0_1 - 0.624761904761899*G0_0_1_7_0_0 + 0.0914285714285714*G0_0_1_7_0_1 + 0.289523809523803*G0_0_1_8_0_0 - 0.0914285714285729*G0_0_1_9_0_0 - 0.182857142857139*G0_0_1_9_0_1 + 0.335238095238092*G0_0_1_10_1_0 + 0.335238095238092*G0_0_1_10_1_1 + 0.335238095238096*G0_0_1_12_1_1 - 0.289523809523808*G0_0_1_13_1_0 + 0.716190476190475*G0_0_1_14_1_0 + 0.0914285714285678*G0_0_1_14_1_1 + 0.380952380952381*G0_0_1_15_1_0 - 0.33523809523809*G0_0_1_15_1_1 - 0.716190476190476*G0_0_1_16_1_0 - 0.335238095238099*G0_0_1_16_1_1 - 0.624761904761899*G0_0_1_17_1_0 + 0.0914285714285714*G0_0_1_17_1_1 + 0.289523809523803*G0_0_1_18_1_0 - 0.0914285714285729*G0_0_1_19_1_0 - 0.182857142857139*G0_0_1_19_1_1 - 0.335238095238092*G0_1_0_0_0_0 - 0.335238095238092*G0_1_0_0_0_1 - 0.335238095238097*G0_1_0_2_0_1 + 0.289523809523808*G0_1_0_3_0_0 - 0.716190476190475*G0_1_0_4_0_0 - 0.0914285714285676*G0_1_0_4_0_1 - 0.380952380952381*G0_1_0_5_0_0 + 0.33523809523809*G0_1_0_5_0_1 + 0.716190476190475*G0_1_0_6_0_0 + 0.335238095238099*G0_1_0_6_0_1 + 0.624761904761899*G0_1_0_7_0_0 - 0.0914285714285714*G0_1_0_7_0_1 - 0.289523809523804*G0_1_0_8_0_0 + 0.091428571428573*G0_1_0_9_0_0 + 0.182857142857139*G0_1_0_9_0_1 - 0.335238095238092*G0_1_0_10_1_0 - 0.335238095238092*G0_1_0_10_1_1 - 0.335238095238097*G0_1_0_12_1_1 + 0.289523809523808*G0_1_0_13_1_0 - 0.716190476190475*G0_1_0_14_1_0 - 0.0914285714285676*G0_1_0_14_1_1 - 0.380952380952381*G0_1_0_15_1_0 + 0.33523809523809*G0_1_0_15_1_1 + 0.716190476190475*G0_1_0_16_1_0 + 0.335238095238099*G0_1_0_16_1_1 + 0.624761904761899*G0_1_0_17_1_0 - 0.0914285714285714*G0_1_0_17_1_1 - 0.289523809523804*G0_1_0_18_1_0 + 0.091428571428573*G0_1_0_19_1_0 + 0.182857142857139*G0_1_0_19_1_1; + A[215] = -A[224] - 0.665396825396822*G0_0_0_0_0_0 - 0.665396825396823*G0_0_0_0_0_1 - 0.655238095238096*G0_0_0_1_0_0 + 0.66031746031744*G0_0_0_2_0_1 + 0.761904761904777*G0_0_0_3_0_0 + 0.233650793650793*G0_0_0_3_0_1 - 2.05714285714289*G0_0_0_4_0_0 - 2.84444444444444*G0_0_0_4_0_1 + 6.24761904761902*G0_0_0_5_0_0 + 5.61777777777775*G0_0_0_5_0_1 + 2.05714285714289*G0_0_0_6_0_0 - 5.61269841269837*G0_0_0_6_0_1 - 0.619682539682535*G0_0_0_7_0_0 + 0.0101587301587298*G0_0_0_7_0_1 + 1.94031746031745*G0_0_0_8_0_0 - 0.233650793650794*G0_0_0_8_0_1 - 7.00952380952379*G0_0_0_9_0_0 + 2.83428571428571*G0_0_0_9_0_1 - 0.665396825396822*G0_0_0_10_1_0 - 0.665396825396823*G0_0_0_10_1_1 - 0.655238095238096*G0_0_0_11_1_0 + 0.66031746031744*G0_0_0_12_1_1 + 0.761904761904777*G0_0_0_13_1_0 + 0.233650793650793*G0_0_0_13_1_1 - 2.05714285714289*G0_0_0_14_1_0 - 2.84444444444444*G0_0_0_14_1_1 + 6.24761904761902*G0_0_0_15_1_0 + 5.61777777777775*G0_0_0_15_1_1 + 2.05714285714289*G0_0_0_16_1_0 - 5.61269841269837*G0_0_0_16_1_1 - 0.619682539682535*G0_0_0_17_1_0 + 0.0101587301587298*G0_0_0_17_1_1 + 1.94031746031745*G0_0_0_18_1_0 - 0.233650793650794*G0_0_0_18_1_1 - 7.00952380952379*G0_0_0_19_1_0 + 2.83428571428571*G0_0_0_19_1_1 + 0.0601058201058209*G0_0_1_0_0_0 + 0.0601058201058211*G0_0_1_0_0_1 + 0.0313227513227492*G0_0_1_1_0_0 - 0.639153439153439*G0_0_1_2_0_1 - 0.319999999999996*G0_0_1_3_0_0 + 0.175238095238092*G0_0_1_3_0_1 - 2.4*G0_0_1_4_0_0 - 2.2247619047619*G0_0_1_4_0_1 + 0.82285714285714*G0_0_1_5_0_0 + 0.56380952380952*G0_0_1_5_0_1 + 2.4*G0_0_1_6_0_0 + 0.0152380952380984*G0_0_1_6_0_1 + 0.259047619047617*G0_0_1_7_0_1 - 0.0914285714285676*G0_0_1_8_0_0 - 0.175238095238093*G0_0_1_8_0_1 - 0.502857142857143*G0_0_1_9_0_0 + 1.96571428571428*G0_0_1_9_0_1 + 0.0601058201058209*G0_0_1_10_1_0 + 0.0601058201058211*G0_0_1_10_1_1 + 0.0313227513227492*G0_0_1_11_1_0 - 0.639153439153439*G0_0_1_12_1_1 - 0.319999999999996*G0_0_1_13_1_0 + 0.175238095238092*G0_0_1_13_1_1 - 2.4*G0_0_1_14_1_0 - 2.2247619047619*G0_0_1_14_1_1 + 0.82285714285714*G0_0_1_15_1_0 + 0.56380952380952*G0_0_1_15_1_1 + 2.4*G0_0_1_16_1_0 + 0.0152380952380984*G0_0_1_16_1_1 + 0.259047619047617*G0_0_1_17_1_1 - 0.0914285714285676*G0_0_1_18_1_0 - 0.175238095238093*G0_0_1_18_1_1 - 0.502857142857143*G0_0_1_19_1_0 + 1.96571428571428*G0_0_1_19_1_1 - 0.691640211640213*G0_1_0_0_0_0 - 0.691640211640213*G0_1_0_0_0_1 - 0.334391534391536*G0_1_0_1_0_0 - 0.156613756613767*G0_1_0_2_0_1 + 0.568888888888901*G0_1_0_3_0_0 + 0.152380952380951*G0_1_0_3_0_1 - 2.34920634920636*G0_1_0_4_0_0 - 2.11047619047618*G0_1_0_4_0_1 + 2.67682539682538*G0_1_0_5_0_0 + 3.25841269841269*G0_1_0_5_0_1 + 2.34920634920636*G0_1_0_6_0_0 - 2.41015873015871*G0_1_0_6_0_1 + 0.223492063492069*G0_1_0_7_0_0 - 0.35809523809524*G0_1_0_7_0_1 + 0.802539682539681*G0_1_0_8_0_0 - 0.152380952380952*G0_1_0_8_0_1 - 3.24571428571428*G0_1_0_9_0_0 + 2.46857142857142*G0_1_0_9_0_1 - 0.691640211640213*G0_1_0_10_1_0 - 0.691640211640213*G0_1_0_10_1_1 - 0.334391534391536*G0_1_0_11_1_0 - 0.156613756613767*G0_1_0_12_1_1 + 0.568888888888901*G0_1_0_13_1_0 + 0.152380952380951*G0_1_0_13_1_1 - 2.34920634920636*G0_1_0_14_1_0 - 2.11047619047618*G0_1_0_14_1_1 + 2.67682539682538*G0_1_0_15_1_0 + 3.25841269841269*G0_1_0_15_1_1 + 2.34920634920636*G0_1_0_16_1_0 - 2.41015873015871*G0_1_0_16_1_1 + 0.223492063492069*G0_1_0_17_1_0 - 0.35809523809524*G0_1_0_17_1_1 + 0.802539682539681*G0_1_0_18_1_0 - 0.152380952380952*G0_1_0_18_1_1 - 3.24571428571428*G0_1_0_19_1_0 + 2.46857142857142*G0_1_0_19_1_1 - 0.579047619047621*G0_1_1_0_0_0 - 0.579047619047622*G0_1_1_0_0_1 - 0.579047619047619*G0_1_1_2_0_1 - 0.40380952380952*G0_1_1_3_0_0 - 2.14095238095238*G0_1_1_4_0_0 - 1.96571428571428*G0_1_1_4_0_1 - 1.56190476190476*G0_1_1_5_0_0 + 0.579047619047625*G0_1_1_5_0_1 + 2.14095238095238*G0_1_1_6_0_0 + 0.579047619047615*G0_1_1_6_0_1 + 0.175238095238102*G0_1_1_7_0_0 - 1.96571428571428*G0_1_1_7_0_1 + 0.403809523809521*G0_1_1_8_0_0 + 1.96571428571427*G0_1_1_9_0_0 + 3.93142857142856*G0_1_1_9_0_1 - 0.579047619047621*G0_1_1_10_1_0 - 0.579047619047622*G0_1_1_10_1_1 - 0.579047619047619*G0_1_1_12_1_1 - 0.40380952380952*G0_1_1_13_1_0 - 2.14095238095238*G0_1_1_14_1_0 - 1.96571428571428*G0_1_1_14_1_1 - 1.56190476190476*G0_1_1_15_1_0 + 0.579047619047625*G0_1_1_15_1_1 + 2.14095238095238*G0_1_1_16_1_0 + 0.579047619047615*G0_1_1_16_1_1 + 0.175238095238102*G0_1_1_17_1_0 - 1.96571428571428*G0_1_1_17_1_1 + 0.403809523809521*G0_1_1_18_1_0 + 1.96571428571427*G0_1_1_19_1_0 + 3.93142857142856*G0_1_1_19_1_1; + A[683] = -A[215] - 0.355555555555555*G0_0_1_0_0_0 - 0.355555555555555*G0_0_1_0_0_1 - 0.761904761904763*G0_0_1_1_0_0 - 1.95555555555555*G0_0_1_2_0_1 + 3.27619047619046*G0_0_1_3_0_0 + 0.292063492063484*G0_0_1_3_0_1 - 4.41904761904761*G0_0_1_4_0_0 - 0.241269841269844*G0_0_1_4_0_1 + 1.6*G0_0_1_5_0_0 + 1.68888888888889*G0_0_1_5_0_1 + 4.41904761904761*G0_0_1_6_0_0 + 0.622222222222216*G0_0_1_6_0_1 + 0.558730158730156*G0_0_1_7_0_0 + 0.469841269841264*G0_0_1_7_0_1 + 0.558730158730163*G0_0_1_8_0_0 - 0.292063492063485*G0_0_1_8_0_1 - 4.87619047619046*G0_0_1_9_0_0 - 0.228571428571422*G0_0_1_9_0_1 - 0.355555555555555*G0_0_1_10_1_0 - 0.355555555555555*G0_0_1_10_1_1 - 0.761904761904763*G0_0_1_11_1_0 - 1.95555555555555*G0_0_1_12_1_1 + 3.27619047619046*G0_0_1_13_1_0 + 0.292063492063484*G0_0_1_13_1_1 - 4.41904761904761*G0_0_1_14_1_0 - 0.241269841269844*G0_0_1_14_1_1 + 1.6*G0_0_1_15_1_0 + 1.68888888888889*G0_0_1_15_1_1 + 4.41904761904761*G0_0_1_16_1_0 + 0.622222222222216*G0_0_1_16_1_1 + 0.558730158730156*G0_0_1_17_1_0 + 0.469841269841264*G0_0_1_17_1_1 + 0.558730158730163*G0_0_1_18_1_0 - 0.292063492063485*G0_0_1_18_1_1 - 4.87619047619046*G0_0_1_19_1_0 - 0.228571428571422*G0_0_1_19_1_1 + 1.31724867724867*G0_1_1_0_0_0 + 1.31724867724867*G0_1_1_0_0_1 - 0.580740740740741*G0_1_1_1_0_0 - 2.25185185185184*G0_1_1_2_0_1 + 2.57777777777777*G0_1_1_3_0_0 + 0.426666666666658*G0_1_1_3_0_1 - 4.12698412698411*G0_1_1_4_0_0 - 0.304761904761907*G0_1_1_4_0_1 + 1.76507936507936*G0_1_1_5_0_0 - 1.4526984126984*G0_1_1_5_0_1 + 4.12698412698411*G0_1_1_6_0_0 + 2.38730158730157*G0_1_1_6_0_1 - 0.993015873015866*G0_1_1_7_0_0 + 2.22476190476189*G0_1_1_7_0_1 + 0.256507936507939*G0_1_1_8_0_0 - 0.42666666666666*G0_1_1_8_0_1 - 4.34285714285713*G0_1_1_9_0_0 - 1.91999999999998*G0_1_1_9_0_1 + 1.31724867724867*G0_1_1_10_1_0 + 1.31724867724867*G0_1_1_10_1_1 - 0.580740740740741*G0_1_1_11_1_0 - 2.25185185185184*G0_1_1_12_1_1 + 2.57777777777777*G0_1_1_13_1_0 + 0.426666666666658*G0_1_1_13_1_1 - 4.12698412698411*G0_1_1_14_1_0 - 0.304761904761907*G0_1_1_14_1_1 + 1.76507936507936*G0_1_1_15_1_0 - 1.4526984126984*G0_1_1_15_1_1 + 4.12698412698411*G0_1_1_16_1_0 + 2.38730158730157*G0_1_1_16_1_1 - 0.993015873015866*G0_1_1_17_1_0 + 2.22476190476189*G0_1_1_17_1_1 + 0.256507936507939*G0_1_1_18_1_0 - 0.42666666666666*G0_1_1_18_1_1 - 4.34285714285713*G0_1_1_19_1_0 - 1.91999999999998*G0_1_1_19_1_1; + A[805] = A[683] + 0.834708994708992*G0_0_0_0_0_0 + 0.834708994708991*G0_0_0_0_0_1 - 3.08994708994708*G0_0_0_1_0_0 + 2.6395767195767*G0_0_0_2_0_1 - 2.78857142857141*G0_0_0_3_0_0 - 6.24761904761902*G0_0_0_3_0_1 + 5.9580952380952*G0_0_0_4_0_0 + 3.68761904761903*G0_0_0_4_0_1 + 4.86095238095235*G0_0_0_5_0_0 + 2.08761904761903*G0_0_0_5_0_1 - 5.9580952380952*G0_0_0_6_0_0 - 5.56190476190473*G0_0_0_6_0_1 - 2.89523809523808*G0_0_0_7_0_0 - 0.121904761904759*G0_0_0_7_0_1 + 5.15047619047616*G0_0_0_8_0_0 + 6.24761904761902*G0_0_0_8_0_1 - 2.07238095238095*G0_0_0_9_0_0 - 3.56571428571428*G0_0_0_9_0_1 + 0.834708994708992*G0_0_0_10_1_0 + 0.834708994708991*G0_0_0_10_1_1 - 3.08994708994708*G0_0_0_11_1_0 + 2.6395767195767*G0_0_0_12_1_1 - 2.78857142857141*G0_0_0_13_1_0 - 6.24761904761902*G0_0_0_13_1_1 + 5.9580952380952*G0_0_0_14_1_0 + 3.68761904761903*G0_0_0_14_1_1 + 4.86095238095235*G0_0_0_15_1_0 + 2.08761904761903*G0_0_0_15_1_1 - 5.9580952380952*G0_0_0_16_1_0 - 5.56190476190473*G0_0_0_16_1_1 - 2.89523809523808*G0_0_0_17_1_0 - 0.121904761904759*G0_0_0_17_1_1 + 5.15047619047616*G0_0_0_18_1_0 + 6.24761904761902*G0_0_0_18_1_1 - 2.07238095238095*G0_0_0_19_1_0 - 3.56571428571428*G0_0_0_19_1_1 - 2.7326984126984*G0_0_1_1_0_0 + 2.7326984126984*G0_0_1_2_0_1 - 4.73650793650791*G0_0_1_3_0_0 - 7.46920634920631*G0_0_1_3_0_1 + 7.46920634920632*G0_0_1_4_0_0 + 4.73650793650792*G0_0_1_4_0_1 + 0.72888888888888*G0_0_1_5_0_0 + 0.728888888888878*G0_0_1_5_0_1 - 7.46920634920632*G0_0_1_6_0_0 - 3.46158730158728*G0_0_1_6_0_1 - 0.728888888888881*G0_0_1_7_0_0 - 0.728888888888877*G0_0_1_7_0_1 + 3.46158730158727*G0_0_1_8_0_0 + 7.46920634920631*G0_0_1_8_0_1 + 4.00761904761903*G0_0_1_9_0_0 - 4.00761904761904*G0_0_1_9_0_1 - 2.7326984126984*G0_0_1_11_1_0 + 2.7326984126984*G0_0_1_12_1_1 - 4.73650793650791*G0_0_1_13_1_0 - 7.46920634920631*G0_0_1_13_1_1 + 7.46920634920632*G0_0_1_14_1_0 + 4.73650793650792*G0_0_1_14_1_1 + 0.72888888888888*G0_0_1_15_1_0 + 0.728888888888878*G0_0_1_15_1_1 - 7.46920634920632*G0_0_1_16_1_0 - 3.46158730158728*G0_0_1_16_1_1 - 0.728888888888881*G0_0_1_17_1_0 - 0.728888888888877*G0_0_1_17_1_1 + 3.46158730158727*G0_0_1_18_1_0 + 7.46920634920631*G0_0_1_18_1_1 + 4.00761904761903*G0_0_1_19_1_0 - 4.00761904761904*G0_0_1_19_1_1 - 2.41777777777777*G0_1_0_1_0_0 + 2.41777777777776*G0_1_0_2_0_1 - 1.89206349206348*G0_1_0_3_0_0 - 4.30984126984125*G0_1_0_3_0_1 + 4.30984126984124*G0_1_0_4_0_0 + 1.89206349206348*G0_1_0_4_0_1 + 2.94349206349205*G0_1_0_5_0_0 + 2.94349206349205*G0_1_0_5_0_1 - 4.30984126984124*G0_1_0_6_0_0 - 5.36126984126981*G0_1_0_6_0_1 - 2.94349206349205*G0_1_0_7_0_0 - 2.94349206349205*G0_1_0_7_0_1 + 5.36126984126981*G0_1_0_8_0_0 + 4.30984126984125*G0_1_0_8_0_1 - 1.05142857142857*G0_1_0_9_0_0 + 1.05142857142856*G0_1_0_9_0_1 - 2.41777777777777*G0_1_0_11_1_0 + 2.41777777777776*G0_1_0_12_1_1 - 1.89206349206348*G0_1_0_13_1_0 - 4.30984126984125*G0_1_0_13_1_1 + 4.30984126984124*G0_1_0_14_1_0 + 1.89206349206348*G0_1_0_14_1_1 + 2.94349206349205*G0_1_0_15_1_0 + 2.94349206349205*G0_1_0_15_1_1 - 4.30984126984124*G0_1_0_16_1_0 - 5.36126984126981*G0_1_0_16_1_1 - 2.94349206349205*G0_1_0_17_1_0 - 2.94349206349205*G0_1_0_17_1_1 + 5.36126984126981*G0_1_0_18_1_0 + 4.30984126984125*G0_1_0_18_1_1 - 1.05142857142857*G0_1_0_19_1_0 + 1.05142857142856*G0_1_0_19_1_1 - 0.83470899470899*G0_1_1_0_0_0 - 0.834708994708992*G0_1_1_0_0_1 - 2.6395767195767*G0_1_1_1_0_0 + 3.08994708994708*G0_1_1_2_0_1 - 3.68761904761903*G0_1_1_3_0_0 - 5.9580952380952*G0_1_1_3_0_1 + 6.24761904761902*G0_1_1_4_0_0 + 2.78857142857141*G0_1_1_4_0_1 + 0.121904761904757*G0_1_1_5_0_0 + 2.89523809523808*G0_1_1_5_0_1 - 6.24761904761902*G0_1_1_6_0_0 - 5.15047619047616*G0_1_1_6_0_1 - 2.08761904761904*G0_1_1_7_0_0 - 4.86095238095235*G0_1_1_7_0_1 + 5.56190476190473*G0_1_1_8_0_0 + 5.9580952380952*G0_1_1_8_0_1 + 3.56571428571427*G0_1_1_9_0_0 + 2.07238095238094*G0_1_1_9_0_1 - 0.83470899470899*G0_1_1_10_1_0 - 0.834708994708992*G0_1_1_10_1_1 - 2.6395767195767*G0_1_1_11_1_0 + 3.08994708994708*G0_1_1_12_1_1 - 3.68761904761903*G0_1_1_13_1_0 - 5.9580952380952*G0_1_1_13_1_1 + 6.24761904761902*G0_1_1_14_1_0 + 2.78857142857141*G0_1_1_14_1_1 + 0.121904761904757*G0_1_1_15_1_0 + 2.89523809523808*G0_1_1_15_1_1 - 6.24761904761902*G0_1_1_16_1_0 - 5.15047619047616*G0_1_1_16_1_1 - 2.08761904761904*G0_1_1_17_1_0 - 4.86095238095235*G0_1_1_17_1_1 + 5.56190476190473*G0_1_1_18_1_0 + 5.9580952380952*G0_1_1_18_1_1 + 3.56571428571427*G0_1_1_19_1_0 + 2.07238095238094*G0_1_1_19_1_1; + A[559] = A[805] - 1.71851851851851*G0_0_0_0_0_0 - 1.71851851851851*G0_0_0_0_0_1 + 2.68359788359787*G0_0_0_1_0_0 - 1.01417989417989*G0_0_0_2_0_1 + 3.21523809523807*G0_0_0_3_0_0 + 5.76507936507934*G0_0_0_3_0_1 - 3.36761904761903*G0_0_0_4_0_0 - 2.21968253968254*G0_0_0_4_0_1 - 1.38666666666666*G0_0_0_5_0_0 + 1.53396825396825*G0_0_0_5_0_1 + 3.36761904761903*G0_0_0_6_0_0 + 1.19873015873015*G0_0_0_6_0_1 + 3.49460317460316*G0_0_0_7_0_0 + 0.573968253968247*G0_0_0_7_0_1 - 4.45968253968252*G0_0_0_8_0_0 - 5.76507936507934*G0_0_0_8_0_1 - 1.82857142857141*G0_0_0_9_0_0 + 1.64571428571429*G0_0_0_9_0_1 - 1.71851851851851*G0_0_0_10_1_0 - 1.71851851851851*G0_0_0_10_1_1 + 2.68359788359787*G0_0_0_11_1_0 - 1.01417989417989*G0_0_0_12_1_1 + 3.21523809523807*G0_0_0_13_1_0 + 5.76507936507934*G0_0_0_13_1_1 - 3.36761904761903*G0_0_0_14_1_0 - 2.21968253968254*G0_0_0_14_1_1 - 1.38666666666666*G0_0_0_15_1_0 + 1.53396825396825*G0_0_0_15_1_1 + 3.36761904761903*G0_0_0_16_1_0 + 1.19873015873015*G0_0_0_16_1_1 + 3.49460317460316*G0_0_0_17_1_0 + 0.573968253968247*G0_0_0_17_1_1 - 4.45968253968252*G0_0_0_18_1_0 - 5.76507936507934*G0_0_0_18_1_1 - 1.82857142857141*G0_0_0_19_1_0 + 1.64571428571429*G0_0_0_19_1_1 - 0.748359788359785*G0_0_1_0_0_0 - 0.748359788359784*G0_0_1_0_0_1 + 3.54708994708993*G0_0_1_1_0_0 + 0.0372486772486776*G0_0_1_2_0_1 + 5.7269841269841*G0_0_1_3_0_0 + 8.68571428571425*G0_0_1_3_0_1 - 0.47492063492063*G0_0_1_4_0_0 + 0.0761904761904759*G0_0_1_4_0_1 + 0.993015873015867*G0_0_1_5_0_0 + 0.721269841269837*G0_0_1_5_0_1 + 0.474920634920632*G0_0_1_6_0_0 - 0.0101587301587314*G0_0_1_6_0_1 + 2.09015873015872*G0_0_1_7_0_0 + 2.36190476190475*G0_0_1_7_0_1 - 4.88888888888886*G0_0_1_8_0_0 - 8.68571428571425*G0_0_1_8_0_1 - 6.71999999999997*G0_0_1_9_0_0 - 2.43809523809522*G0_0_1_9_0_1 - 0.748359788359785*G0_0_1_10_1_0 - 0.748359788359784*G0_0_1_10_1_1 + 3.54708994708993*G0_0_1_11_1_0 + 0.0372486772486776*G0_0_1_12_1_1 + 5.7269841269841*G0_0_1_13_1_0 + 8.68571428571425*G0_0_1_13_1_1 - 0.47492063492063*G0_0_1_14_1_0 + 0.0761904761904759*G0_0_1_14_1_1 + 0.993015873015867*G0_0_1_15_1_0 + 0.721269841269837*G0_0_1_15_1_1 + 0.474920634920632*G0_0_1_16_1_0 - 0.0101587301587314*G0_0_1_16_1_1 + 2.09015873015872*G0_0_1_17_1_0 + 2.36190476190475*G0_0_1_17_1_1 - 4.88888888888886*G0_0_1_18_1_0 - 8.68571428571425*G0_0_1_18_1_1 - 6.71999999999997*G0_0_1_19_1_0 - 2.43809523809522*G0_0_1_19_1_1 - 0.667089947089944*G0_1_0_0_0_0 - 0.667089947089943*G0_1_0_0_0_1 + 1.82010582010582*G0_1_0_1_0_0 - 0.044021164021161*G0_1_0_2_0_1 + 0.723809523809517*G0_1_0_3_0_0 + 2.84444444444444*G0_1_0_3_0_1 - 0.175238095238093*G0_1_0_4_0_0 - 0.431746031746037*G0_1_0_4_0_1 + 0.297142857142855*G0_1_0_5_0_0 + 0.325079365079361*G0_1_0_5_0_1 + 0.175238095238093*G0_1_0_6_0_0 + 0.386031746031743*G0_1_0_6_0_1 + 2.89777777777776*G0_1_0_7_0_0 + 2.86984126984126*G0_1_0_7_0_1 - 4.05079365079364*G0_1_0_8_0_0 - 2.84444444444444*G0_1_0_8_0_1 - 1.02095238095237*G0_1_0_9_0_0 - 2.43809523809522*G0_1_0_9_0_1 - 0.667089947089944*G0_1_0_10_1_0 - 0.667089947089943*G0_1_0_10_1_1 + 1.82010582010582*G0_1_0_11_1_0 - 0.044021164021161*G0_1_0_12_1_1 + 0.723809523809517*G0_1_0_13_1_0 + 2.84444444444444*G0_1_0_13_1_1 - 0.175238095238093*G0_1_0_14_1_0 - 0.431746031746037*G0_1_0_14_1_1 + 0.297142857142855*G0_1_0_15_1_0 + 0.325079365079361*G0_1_0_15_1_1 + 0.175238095238093*G0_1_0_16_1_0 + 0.386031746031743*G0_1_0_16_1_1 + 2.89777777777776*G0_1_0_17_1_0 + 2.86984126984126*G0_1_0_17_1_1 - 4.05079365079364*G0_1_0_18_1_0 - 2.84444444444444*G0_1_0_18_1_1 - 1.02095238095237*G0_1_0_19_1_0 - 2.43809523809522*G0_1_0_19_1_1 - 0.711111111111106*G0_1_1_0_0_0 - 0.711111111111106*G0_1_1_0_0_1 - 0.711111111111107*G0_1_1_2_0_1 + 1.93015873015872*G0_1_1_3_0_0 - 0.203174603174599*G0_1_1_4_0_0 + 2.43809523809523*G0_1_1_4_0_1 + 0.507936507936506*G0_1_1_5_0_0 + 0.711111111111107*G0_1_1_5_0_1 + 0.2031746031746*G0_1_1_6_0_0 + 0.711111111111106*G0_1_1_6_0_1 + 2.64126984126982*G0_1_1_7_0_0 + 2.43809523809522*G0_1_1_7_0_1 - 1.93015873015871*G0_1_1_8_0_0 - 2.43809523809523*G0_1_1_9_0_0 - 4.87619047619045*G0_1_1_9_0_1 - 0.711111111111106*G0_1_1_10_1_0 - 0.711111111111106*G0_1_1_10_1_1 - 0.711111111111107*G0_1_1_12_1_1 + 1.93015873015872*G0_1_1_13_1_0 - 0.203174603174599*G0_1_1_14_1_0 + 2.43809523809523*G0_1_1_14_1_1 + 0.507936507936506*G0_1_1_15_1_0 + 0.711111111111107*G0_1_1_15_1_1 + 0.2031746031746*G0_1_1_16_1_0 + 0.711111111111106*G0_1_1_16_1_1 + 2.64126984126982*G0_1_1_17_1_0 + 2.43809523809522*G0_1_1_17_1_1 - 1.93015873015871*G0_1_1_18_1_0 - 2.43809523809523*G0_1_1_19_1_0 - 4.87619047619045*G0_1_1_19_1_1; + A[125] = A[559] + 0.172698412698411*G0_0_0_0_0_0 + 0.172698412698411*G0_0_0_0_0_1 - 0.304761904761904*G0_0_0_1_0_0 - 1.62539682539681*G0_0_0_2_0_1 + 2.01142857142856*G0_0_0_3_0_0 + 0.279365079365075*G0_0_0_3_0_1 - 2.59047619047616*G0_0_0_4_0_0 + 0.462222222222227*G0_0_0_4_0_1 - 1.03619047619047*G0_0_0_5_0_0 - 0.980317460317451*G0_0_0_5_0_1 + 2.59047619047617*G0_0_0_6_0_0 + 2.43301587301585*G0_0_0_6_0_1 + 0.111746031746032*G0_0_0_7_0_0 + 0.0558730158730151*G0_0_0_7_0_1 + 0.0203174603174627*G0_0_0_8_0_0 - 0.279365079365076*G0_0_0_8_0_1 - 0.975238095238095*G0_0_0_9_0_0 - 0.518095238095242*G0_0_0_9_0_1 + 0.172698412698411*G0_0_0_10_1_0 + 0.172698412698411*G0_0_0_10_1_1 - 0.304761904761904*G0_0_0_11_1_0 - 1.62539682539681*G0_0_0_12_1_1 + 2.01142857142856*G0_0_0_13_1_0 + 0.279365079365075*G0_0_0_13_1_1 - 2.59047619047616*G0_0_0_14_1_0 + 0.462222222222227*G0_0_0_14_1_1 - 1.03619047619047*G0_0_0_15_1_0 - 0.980317460317451*G0_0_0_15_1_1 + 2.59047619047617*G0_0_0_16_1_0 + 2.43301587301585*G0_0_0_16_1_1 + 0.111746031746032*G0_0_0_17_1_0 + 0.0558730158730151*G0_0_0_17_1_1 + 0.0203174603174627*G0_0_0_18_1_0 - 0.279365079365076*G0_0_0_18_1_1 - 0.975238095238095*G0_0_0_19_1_0 - 0.518095238095242*G0_0_0_19_1_1 - 0.777142857142857*G0_0_1_1_0_0 + 0.777142857142856*G0_0_1_2_0_1 - 0.914285714285713*G0_0_1_3_0_0 - 1.69142857142857*G0_0_1_3_0_1 + 1.69142857142857*G0_0_1_4_0_0 + 0.914285714285713*G0_0_1_4_0_1 + 0.639999999999996*G0_0_1_5_0_0 + 0.639999999999999*G0_0_1_5_0_1 - 1.69142857142857*G0_0_1_6_0_0 - 1.41714285714285*G0_0_1_6_0_1 - 0.639999999999999*G0_0_1_7_0_0 - 0.640000000000003*G0_0_1_7_0_1 + 1.41714285714286*G0_0_1_8_0_0 + 1.69142857142857*G0_0_1_8_0_1 + 0.274285714285717*G0_0_1_9_0_0 - 0.274285714285713*G0_0_1_9_0_1 - 0.777142857142857*G0_0_1_11_1_0 + 0.777142857142856*G0_0_1_12_1_1 - 0.914285714285713*G0_0_1_13_1_0 - 1.69142857142857*G0_0_1_13_1_1 + 1.69142857142857*G0_0_1_14_1_0 + 0.914285714285713*G0_0_1_14_1_1 + 0.639999999999996*G0_0_1_15_1_0 + 0.639999999999999*G0_0_1_15_1_1 - 1.69142857142857*G0_0_1_16_1_0 - 1.41714285714285*G0_0_1_16_1_1 - 0.639999999999999*G0_0_1_17_1_0 - 0.640000000000003*G0_0_1_17_1_1 + 1.41714285714286*G0_0_1_18_1_0 + 1.69142857142857*G0_0_1_18_1_1 + 0.274285714285717*G0_0_1_19_1_0 - 0.274285714285713*G0_0_1_19_1_1 + 0.553650793650788*G0_1_0_1_0_0 - 0.553650793650789*G0_1_0_2_0_1 + 0.736507936507935*G0_1_0_3_0_0 + 1.29015873015872*G0_1_0_3_0_1 - 1.29015873015872*G0_1_0_4_0_0 - 0.736507936507925*G0_1_0_4_0_1 - 0.370793650793645*G0_1_0_5_0_0 - 0.370793650793645*G0_1_0_5_0_1 + 1.29015873015872*G0_1_0_6_0_0 + 0.924444444444434*G0_1_0_6_0_1 + 0.370793650793649*G0_1_0_7_0_0 + 0.370793650793649*G0_1_0_7_0_1 - 0.924444444444436*G0_1_0_8_0_0 - 1.29015873015872*G0_1_0_8_0_1 - 0.36571428571429*G0_1_0_9_0_0 + 0.365714285714277*G0_1_0_9_0_1 + 0.553650793650788*G0_1_0_11_1_0 - 0.553650793650789*G0_1_0_12_1_1 + 0.736507936507935*G0_1_0_13_1_0 + 1.29015873015872*G0_1_0_13_1_1 - 1.29015873015872*G0_1_0_14_1_0 - 0.736507936507925*G0_1_0_14_1_1 - 0.370793650793645*G0_1_0_15_1_0 - 0.370793650793645*G0_1_0_15_1_1 + 1.29015873015872*G0_1_0_16_1_0 + 0.924444444444434*G0_1_0_16_1_1 + 0.370793650793649*G0_1_0_17_1_0 + 0.370793650793649*G0_1_0_17_1_1 - 0.924444444444436*G0_1_0_18_1_0 - 1.29015873015872*G0_1_0_18_1_1 - 0.36571428571429*G0_1_0_19_1_0 + 0.365714285714277*G0_1_0_19_1_1 - 0.172698412698413*G0_1_1_0_0_0 - 0.172698412698413*G0_1_1_0_0_1 + 1.62539682539682*G0_1_1_1_0_0 + 0.304761904761905*G0_1_1_2_0_1 - 0.462222222222221*G0_1_1_3_0_0 + 2.59047619047617*G0_1_1_3_0_1 - 0.279365079365075*G0_1_1_4_0_0 - 2.01142857142856*G0_1_1_4_0_1 - 0.0558730158730157*G0_1_1_5_0_0 - 0.111746031746028*G0_1_1_5_0_1 + 0.279365079365075*G0_1_1_6_0_0 - 0.0203174603174636*G0_1_1_6_0_1 + 0.980317460317455*G0_1_1_7_0_0 + 1.03619047619047*G0_1_1_7_0_1 - 2.43301587301586*G0_1_1_8_0_0 - 2.59047619047617*G0_1_1_8_0_1 + 0.518095238095237*G0_1_1_9_0_0 + 0.975238095238089*G0_1_1_9_0_1 - 0.172698412698413*G0_1_1_10_1_0 - 0.172698412698413*G0_1_1_10_1_1 + 1.62539682539682*G0_1_1_11_1_0 + 0.304761904761905*G0_1_1_12_1_1 - 0.462222222222221*G0_1_1_13_1_0 + 2.59047619047617*G0_1_1_13_1_1 - 0.279365079365075*G0_1_1_14_1_0 - 2.01142857142856*G0_1_1_14_1_1 - 0.0558730158730157*G0_1_1_15_1_0 - 0.111746031746028*G0_1_1_15_1_1 + 0.279365079365075*G0_1_1_16_1_0 - 0.0203174603174636*G0_1_1_16_1_1 + 0.980317460317455*G0_1_1_17_1_0 + 1.03619047619047*G0_1_1_17_1_1 - 2.43301587301586*G0_1_1_18_1_0 - 2.59047619047617*G0_1_1_18_1_1 + 0.518095238095237*G0_1_1_19_1_0 + 0.975238095238089*G0_1_1_19_1_1; + A[588] = A[559] + 0.548571428571426*G0_0_1_0_0_0 + 0.548571428571426*G0_0_1_0_0_1 - 0.863492063492059*G0_0_1_1_0_0 + 0.467301587301587*G0_0_1_2_0_1 - 4.1142857142857*G0_0_1_3_0_0 - 2.92063492063491*G0_0_1_3_0_1 + 0.0609523809523787*G0_0_1_4_0_0 - 2.46349206349206*G0_0_1_4_0_1 - 0.944761904761902*G0_0_1_5_0_0 - 0.706031746031742*G0_0_1_5_0_1 - 0.0609523809523802*G0_0_1_6_0_0 - 0.30984126984127*G0_0_1_6_0_1 - 1.71682539682539*G0_0_1_7_0_0 - 1.95555555555555*G0_0_1_7_0_1 + 2.03174603174602*G0_0_1_8_0_0 + 2.92063492063491*G0_0_1_8_0_1 + 5.0590476190476*G0_0_1_9_0_0 + 4.41904761904761*G0_0_1_9_0_1 + 0.548571428571426*G0_0_1_10_1_0 + 0.548571428571426*G0_0_1_10_1_1 - 0.863492063492059*G0_0_1_11_1_0 + 0.467301587301587*G0_0_1_12_1_1 - 4.1142857142857*G0_0_1_13_1_0 - 2.92063492063491*G0_0_1_13_1_1 + 0.0609523809523787*G0_0_1_14_1_0 - 2.46349206349206*G0_0_1_14_1_1 - 0.944761904761902*G0_0_1_15_1_0 - 0.706031746031742*G0_0_1_15_1_1 - 0.0609523809523802*G0_0_1_16_1_0 - 0.30984126984127*G0_0_1_16_1_1 - 1.71682539682539*G0_0_1_17_1_0 - 1.95555555555555*G0_0_1_17_1_1 + 2.03174603174602*G0_0_1_18_1_0 + 2.92063492063491*G0_0_1_18_1_1 + 5.0590476190476*G0_0_1_19_1_0 + 4.41904761904761*G0_0_1_19_1_1 - 0.548571428571426*G0_1_0_0_0_0 - 0.548571428571426*G0_1_0_0_0_1 + 0.863492063492059*G0_1_0_1_0_0 - 0.467301587301587*G0_1_0_2_0_1 + 4.1142857142857*G0_1_0_3_0_0 + 2.92063492063491*G0_1_0_3_0_1 - 0.0609523809523787*G0_1_0_4_0_0 + 2.46349206349206*G0_1_0_4_0_1 + 0.944761904761902*G0_1_0_5_0_0 + 0.706031746031742*G0_1_0_5_0_1 + 0.0609523809523803*G0_1_0_6_0_0 + 0.30984126984127*G0_1_0_6_0_1 + 1.71682539682539*G0_1_0_7_0_0 + 1.95555555555555*G0_1_0_7_0_1 - 2.03174603174602*G0_1_0_8_0_0 - 2.92063492063491*G0_1_0_8_0_1 - 5.0590476190476*G0_1_0_9_0_0 - 4.41904761904761*G0_1_0_9_0_1 - 0.548571428571426*G0_1_0_10_1_0 - 0.548571428571426*G0_1_0_10_1_1 + 0.863492063492059*G0_1_0_11_1_0 - 0.467301587301587*G0_1_0_12_1_1 + 4.1142857142857*G0_1_0_13_1_0 + 2.92063492063491*G0_1_0_13_1_1 - 0.0609523809523787*G0_1_0_14_1_0 + 2.46349206349206*G0_1_0_14_1_1 + 0.944761904761902*G0_1_0_15_1_0 + 0.706031746031742*G0_1_0_15_1_1 + 0.0609523809523803*G0_1_0_16_1_0 + 0.30984126984127*G0_1_0_16_1_1 + 1.71682539682539*G0_1_0_17_1_0 + 1.95555555555555*G0_1_0_17_1_1 - 2.03174603174602*G0_1_0_18_1_0 - 2.92063492063491*G0_1_0_18_1_1 - 5.0590476190476*G0_1_0_19_1_0 - 4.41904761904761*G0_1_0_19_1_1; + A[334] = -A[559] - 0.181164021164019*G0_0_0_0_0_0 - 0.181164021164019*G0_0_0_0_0_1 - 0.296296296296296*G0_0_0_1_0_0 - 1.67280423280422*G0_0_0_2_0_1 + 2.05714285714284*G0_0_0_3_0_0 + 0.292063492063486*G0_0_0_3_0_1 - 3.30666666666665*G0_0_0_4_0_0 - 0.165079365079366*G0_0_0_4_0_1 + 0.167619047619047*G0_0_0_5_0_0 + 0.30222222222222*G0_0_0_5_0_1 + 3.30666666666665*G0_0_0_6_0_0 + 1.55174603174602*G0_0_0_6_0_1 + 0.833015873015866*G0_0_0_7_0_0 + 0.698412698412691*G0_0_0_7_0_1 - 0.35555555555555*G0_0_0_8_0_0 - 0.292063492063486*G0_0_0_8_0_1 - 2.22476190476189*G0_0_0_9_0_0 - 0.533333333333325*G0_0_0_9_0_1 - 0.181164021164019*G0_0_0_10_1_0 - 0.181164021164019*G0_0_0_10_1_1 - 0.296296296296296*G0_0_0_11_1_0 - 1.67280423280422*G0_0_0_12_1_1 + 2.05714285714284*G0_0_0_13_1_0 + 0.292063492063486*G0_0_0_13_1_1 - 3.30666666666665*G0_0_0_14_1_0 - 0.165079365079366*G0_0_0_14_1_1 + 0.167619047619047*G0_0_0_15_1_0 + 0.30222222222222*G0_0_0_15_1_1 + 3.30666666666665*G0_0_0_16_1_0 + 1.55174603174602*G0_0_0_16_1_1 + 0.833015873015866*G0_0_0_17_1_0 + 0.698412698412691*G0_0_0_17_1_1 - 0.35555555555555*G0_0_0_18_1_0 - 0.292063492063486*G0_0_0_18_1_1 - 2.22476190476189*G0_0_0_19_1_0 - 0.533333333333325*G0_0_0_19_1_1 - 0.761904761904761*G0_0_1_0_0_0 - 0.76190476190476*G0_0_1_0_0_1 + 1.95555555555556*G0_0_1_1_0_0 - 0.355555555555552*G0_0_1_2_0_1 + 3.79682539682538*G0_0_1_3_0_0 + 4.41904761904762*G0_0_1_3_0_1 - 0.0888888888888856*G0_0_1_4_0_0 + 1.59999999999999*G0_0_1_4_0_1 + 0.850793650793649*G0_0_1_5_0_0 + 0.558730158730158*G0_0_1_5_0_1 + 0.0888888888888869*G0_0_1_6_0_0 + 0.558730158730154*G0_0_1_6_0_1 + 2.98412698412698*G0_0_1_7_0_0 + 3.27619047619047*G0_0_1_7_0_1 - 4.17777777777777*G0_0_1_8_0_0 - 4.41904761904762*G0_0_1_8_0_1 - 4.64761904761903*G0_0_1_9_0_0 - 4.87619047619046*G0_0_1_9_0_1 - 0.761904761904761*G0_0_1_10_1_0 - 0.76190476190476*G0_0_1_10_1_1 + 1.95555555555556*G0_0_1_11_1_0 - 0.355555555555552*G0_0_1_12_1_1 + 3.79682539682538*G0_0_1_13_1_0 + 4.41904761904762*G0_0_1_13_1_1 - 0.0888888888888856*G0_0_1_14_1_0 + 1.59999999999999*G0_0_1_14_1_1 + 0.850793650793649*G0_0_1_15_1_0 + 0.558730158730158*G0_0_1_15_1_1 + 0.0888888888888869*G0_0_1_16_1_0 + 0.558730158730154*G0_0_1_16_1_1 + 2.98412698412698*G0_0_1_17_1_0 + 3.27619047619047*G0_0_1_17_1_1 - 4.17777777777777*G0_0_1_18_1_0 - 4.41904761904762*G0_0_1_18_1_1 - 4.64761904761903*G0_0_1_19_1_0 - 4.87619047619046*G0_0_1_19_1_1; + A[131] = -A[588] - 0.181164021164019*G0_0_0_0_0_0 - 0.181164021164019*G0_0_0_0_0_1 - 0.296296296296296*G0_0_0_1_0_0 - 1.67280423280422*G0_0_0_2_0_1 + 2.05714285714284*G0_0_0_3_0_0 + 0.292063492063486*G0_0_0_3_0_1 - 3.30666666666665*G0_0_0_4_0_0 - 0.165079365079366*G0_0_0_4_0_1 + 0.167619047619046*G0_0_0_5_0_0 + 0.30222222222222*G0_0_0_5_0_1 + 3.30666666666665*G0_0_0_6_0_0 + 1.55174603174602*G0_0_0_6_0_1 + 0.833015873015866*G0_0_0_7_0_0 + 0.698412698412691*G0_0_0_7_0_1 - 0.35555555555555*G0_0_0_8_0_0 - 0.292063492063486*G0_0_0_8_0_1 - 2.22476190476189*G0_0_0_9_0_0 - 0.533333333333325*G0_0_0_9_0_1 - 0.181164021164019*G0_0_0_10_1_0 - 0.181164021164019*G0_0_0_10_1_1 - 0.296296296296296*G0_0_0_11_1_0 - 1.67280423280422*G0_0_0_12_1_1 + 2.05714285714284*G0_0_0_13_1_0 + 0.292063492063486*G0_0_0_13_1_1 - 3.30666666666665*G0_0_0_14_1_0 - 0.165079365079366*G0_0_0_14_1_1 + 0.167619047619046*G0_0_0_15_1_0 + 0.30222222222222*G0_0_0_15_1_1 + 3.30666666666665*G0_0_0_16_1_0 + 1.55174603174602*G0_0_0_16_1_1 + 0.833015873015866*G0_0_0_17_1_0 + 0.698412698412691*G0_0_0_17_1_1 - 0.35555555555555*G0_0_0_18_1_0 - 0.292063492063486*G0_0_0_18_1_1 - 2.22476190476189*G0_0_0_19_1_0 - 0.533333333333325*G0_0_0_19_1_1 - 0.761904761904761*G0_1_0_0_0_0 - 0.76190476190476*G0_1_0_0_0_1 + 1.95555555555556*G0_1_0_1_0_0 - 0.355555555555552*G0_1_0_2_0_1 + 3.79682539682538*G0_1_0_3_0_0 + 4.41904761904762*G0_1_0_3_0_1 - 0.0888888888888856*G0_1_0_4_0_0 + 1.59999999999999*G0_1_0_4_0_1 + 0.850793650793649*G0_1_0_5_0_0 + 0.558730158730158*G0_1_0_5_0_1 + 0.088888888888887*G0_1_0_6_0_0 + 0.558730158730154*G0_1_0_6_0_1 + 2.98412698412698*G0_1_0_7_0_0 + 3.27619047619047*G0_1_0_7_0_1 - 4.17777777777777*G0_1_0_8_0_0 - 4.41904761904762*G0_1_0_8_0_1 - 4.64761904761903*G0_1_0_9_0_0 - 4.87619047619046*G0_1_0_9_0_1 - 0.761904761904761*G0_1_0_10_1_0 - 0.76190476190476*G0_1_0_10_1_1 + 1.95555555555556*G0_1_0_11_1_0 - 0.355555555555552*G0_1_0_12_1_1 + 3.79682539682538*G0_1_0_13_1_0 + 4.41904761904762*G0_1_0_13_1_1 - 0.0888888888888856*G0_1_0_14_1_0 + 1.59999999999999*G0_1_0_14_1_1 + 0.850793650793649*G0_1_0_15_1_0 + 0.558730158730158*G0_1_0_15_1_1 + 0.088888888888887*G0_1_0_16_1_0 + 0.558730158730154*G0_1_0_16_1_1 + 2.98412698412698*G0_1_0_17_1_0 + 3.27619047619047*G0_1_0_17_1_1 - 4.17777777777777*G0_1_0_18_1_0 - 4.41904761904762*G0_1_0_18_1_1 - 4.64761904761903*G0_1_0_19_1_0 - 4.87619047619046*G0_1_0_19_1_1; + A[247] = A[683] + 0.467301587301587*G0_0_1_0_0_0 + 0.467301587301587*G0_0_1_0_0_1 + 0.548571428571428*G0_0_1_1_0_0 + 0.863492063492063*G0_0_1_2_0_1 - 1.95555555555555*G0_0_1_3_0_0 - 0.238730158730156*G0_0_1_3_0_1 + 2.92063492063492*G0_0_1_4_0_0 + 0.888888888888888*G0_0_1_4_0_1 - 2.46349206349206*G0_0_1_5_0_0 - 2.52444444444444*G0_0_1_5_0_1 - 2.92063492063492*G0_0_1_6_0_0 + 1.19365079365079*G0_0_1_6_0_1 - 0.30984126984127*G0_0_1_7_0_0 - 0.248888888888885*G0_0_1_7_0_1 - 0.706031746031746*G0_0_1_8_0_0 + 0.238730158730157*G0_0_1_8_0_1 + 4.41904761904761*G0_0_1_9_0_0 - 0.640000000000002*G0_0_1_9_0_1 + 0.467301587301587*G0_0_1_10_1_0 + 0.467301587301587*G0_0_1_10_1_1 + 0.548571428571428*G0_0_1_11_1_0 + 0.863492063492063*G0_0_1_12_1_1 - 1.95555555555555*G0_0_1_13_1_0 - 0.238730158730156*G0_0_1_13_1_1 + 2.92063492063492*G0_0_1_14_1_0 + 0.888888888888888*G0_0_1_14_1_1 - 2.46349206349206*G0_0_1_15_1_0 - 2.52444444444444*G0_0_1_15_1_1 - 2.92063492063492*G0_0_1_16_1_0 + 1.19365079365079*G0_0_1_16_1_1 - 0.30984126984127*G0_0_1_17_1_0 - 0.248888888888885*G0_0_1_17_1_1 - 0.706031746031746*G0_0_1_18_1_0 + 0.238730158730157*G0_0_1_18_1_1 + 4.41904761904761*G0_0_1_19_1_0 - 0.640000000000002*G0_0_1_19_1_1 - 0.467301587301587*G0_1_0_0_0_0 - 0.467301587301587*G0_1_0_0_0_1 - 0.548571428571428*G0_1_0_1_0_0 - 0.863492063492063*G0_1_0_2_0_1 + 1.95555555555555*G0_1_0_3_0_0 + 0.238730158730156*G0_1_0_3_0_1 - 2.92063492063492*G0_1_0_4_0_0 - 0.888888888888888*G0_1_0_4_0_1 + 2.46349206349206*G0_1_0_5_0_0 + 2.52444444444444*G0_1_0_5_0_1 + 2.92063492063492*G0_1_0_6_0_0 - 1.19365079365079*G0_1_0_6_0_1 + 0.30984126984127*G0_1_0_7_0_0 + 0.248888888888885*G0_1_0_7_0_1 + 0.706031746031746*G0_1_0_8_0_0 - 0.238730158730157*G0_1_0_8_0_1 - 4.41904761904761*G0_1_0_9_0_0 + 0.640000000000002*G0_1_0_9_0_1 - 0.467301587301587*G0_1_0_10_1_0 - 0.467301587301587*G0_1_0_10_1_1 - 0.548571428571428*G0_1_0_11_1_0 - 0.863492063492063*G0_1_0_12_1_1 + 1.95555555555555*G0_1_0_13_1_0 + 0.238730158730156*G0_1_0_13_1_1 - 2.92063492063492*G0_1_0_14_1_0 - 0.888888888888888*G0_1_0_14_1_1 + 2.46349206349206*G0_1_0_15_1_0 + 2.52444444444444*G0_1_0_15_1_1 + 2.92063492063492*G0_1_0_16_1_0 - 1.19365079365079*G0_1_0_16_1_1 + 0.30984126984127*G0_1_0_17_1_0 + 0.248888888888885*G0_1_0_17_1_1 + 0.706031746031746*G0_1_0_18_1_0 - 0.238730158730157*G0_1_0_18_1_1 - 4.41904761904761*G0_1_0_19_1_0 + 0.640000000000002*G0_1_0_19_1_1; + A[94] = A[559]; + A[590] = A[125]; + A[712] = A[247]; + A[340] = A[805]; + A[154] = A[125] + 0.548571428571425*G0_0_1_0_0_0 + 0.548571428571425*G0_0_1_0_0_1 + 0.467301587301586*G0_0_1_1_0_0 - 0.863492063492058*G0_0_1_2_0_1 - 2.46349206349205*G0_0_1_3_0_0 + 0.0609523809523819*G0_0_1_3_0_1 - 2.92063492063491*G0_0_1_4_0_0 - 4.1142857142857*G0_0_1_4_0_1 - 1.95555555555554*G0_0_1_5_0_0 - 1.71682539682539*G0_0_1_5_0_1 + 2.92063492063491*G0_0_1_6_0_0 + 2.03174603174602*G0_0_1_6_0_1 - 0.706031746031741*G0_0_1_7_0_0 - 0.944761904761897*G0_0_1_7_0_1 - 0.309841269841269*G0_0_1_8_0_0 - 0.060952380952382*G0_0_1_8_0_1 + 4.4190476190476*G0_0_1_9_0_0 + 5.0590476190476*G0_0_1_9_0_1 + 0.548571428571425*G0_0_1_10_1_0 + 0.548571428571425*G0_0_1_10_1_1 + 0.467301587301586*G0_0_1_11_1_0 - 0.863492063492058*G0_0_1_12_1_1 - 2.46349206349205*G0_0_1_13_1_0 + 0.0609523809523819*G0_0_1_13_1_1 - 2.92063492063491*G0_0_1_14_1_0 - 4.1142857142857*G0_0_1_14_1_1 - 1.95555555555554*G0_0_1_15_1_0 - 1.71682539682539*G0_0_1_15_1_1 + 2.92063492063491*G0_0_1_16_1_0 + 2.03174603174602*G0_0_1_16_1_1 - 0.706031746031741*G0_0_1_17_1_0 - 0.944761904761897*G0_0_1_17_1_1 - 0.309841269841269*G0_0_1_18_1_0 - 0.060952380952382*G0_0_1_18_1_1 + 4.4190476190476*G0_0_1_19_1_0 + 5.0590476190476*G0_0_1_19_1_1 - 0.548571428571425*G0_1_0_0_0_0 - 0.548571428571425*G0_1_0_0_0_1 - 0.467301587301586*G0_1_0_1_0_0 + 0.863492063492058*G0_1_0_2_0_1 + 2.46349206349205*G0_1_0_3_0_0 - 0.0609523809523819*G0_1_0_3_0_1 + 2.92063492063491*G0_1_0_4_0_0 + 4.1142857142857*G0_1_0_4_0_1 + 1.95555555555554*G0_1_0_5_0_0 + 1.71682539682539*G0_1_0_5_0_1 - 2.92063492063491*G0_1_0_6_0_0 - 2.03174603174602*G0_1_0_6_0_1 + 0.706031746031741*G0_1_0_7_0_0 + 0.944761904761897*G0_1_0_7_0_1 + 0.309841269841269*G0_1_0_8_0_0 + 0.060952380952382*G0_1_0_8_0_1 - 4.4190476190476*G0_1_0_9_0_0 - 5.0590476190476*G0_1_0_9_0_1 - 0.548571428571425*G0_1_0_10_1_0 - 0.548571428571425*G0_1_0_10_1_1 - 0.467301587301586*G0_1_0_11_1_0 + 0.863492063492058*G0_1_0_12_1_1 + 2.46349206349205*G0_1_0_13_1_0 - 0.0609523809523819*G0_1_0_13_1_1 + 2.92063492063491*G0_1_0_14_1_0 + 4.1142857142857*G0_1_0_14_1_1 + 1.95555555555554*G0_1_0_15_1_0 + 1.71682539682539*G0_1_0_15_1_1 - 2.92063492063491*G0_1_0_16_1_0 - 2.03174603174602*G0_1_0_16_1_1 + 0.706031746031741*G0_1_0_17_1_0 + 0.944761904761897*G0_1_0_17_1_1 + 0.309841269841269*G0_1_0_18_1_0 + 0.060952380952382*G0_1_0_18_1_1 - 4.4190476190476*G0_1_0_19_1_0 - 5.0590476190476*G0_1_0_19_1_1; + A[709] = -A[154] - 0.761904761904759*G0_1_0_0_0_0 - 0.76190476190476*G0_1_0_0_0_1 - 0.355555555555553*G0_1_0_1_0_0 + 1.95555555555554*G0_1_0_2_0_1 + 1.6*G0_1_0_3_0_0 - 0.0888888888888847*G0_1_0_3_0_1 + 4.41904761904759*G0_1_0_4_0_0 + 3.79682539682538*G0_1_0_4_0_1 + 3.27619047619046*G0_1_0_5_0_0 + 2.98412698412697*G0_1_0_5_0_1 - 4.41904761904759*G0_1_0_6_0_0 - 4.17777777777776*G0_1_0_6_0_1 + 0.558730158730156*G0_1_0_7_0_0 + 0.850793650793643*G0_1_0_7_0_1 + 0.558730158730156*G0_1_0_8_0_0 + 0.0888888888888848*G0_1_0_8_0_1 - 4.87619047619046*G0_1_0_9_0_0 - 4.64761904761902*G0_1_0_9_0_1 - 0.761904761904759*G0_1_0_10_1_0 - 0.76190476190476*G0_1_0_10_1_1 - 0.355555555555553*G0_1_0_11_1_0 + 1.95555555555554*G0_1_0_12_1_1 + 1.6*G0_1_0_13_1_0 - 0.0888888888888847*G0_1_0_13_1_1 + 4.41904761904759*G0_1_0_14_1_0 + 3.79682539682538*G0_1_0_14_1_1 + 3.27619047619046*G0_1_0_15_1_0 + 2.98412698412697*G0_1_0_15_1_1 - 4.41904761904759*G0_1_0_16_1_0 - 4.17777777777776*G0_1_0_16_1_1 + 0.558730158730156*G0_1_0_17_1_0 + 0.850793650793643*G0_1_0_17_1_1 + 0.558730158730156*G0_1_0_18_1_0 + 0.0888888888888848*G0_1_0_18_1_1 - 4.87619047619046*G0_1_0_19_1_0 - 4.64761904761902*G0_1_0_19_1_1 - 0.181164021164021*G0_1_1_0_0_0 - 0.181164021164021*G0_1_1_0_0_1 - 1.67280423280423*G0_1_1_1_0_0 - 0.296296296296297*G0_1_1_2_0_1 - 0.165079365079364*G0_1_1_3_0_0 - 3.30666666666666*G0_1_1_3_0_1 + 0.292063492063489*G0_1_1_4_0_0 + 2.05714285714285*G0_1_1_4_0_1 + 0.698412698412695*G0_1_1_5_0_0 + 0.833015873015873*G0_1_1_5_0_1 - 0.292063492063488*G0_1_1_6_0_0 - 0.355555555555555*G0_1_1_6_0_1 + 0.302222222222217*G0_1_1_7_0_0 + 0.167619047619039*G0_1_1_7_0_1 + 1.55174603174604*G0_1_1_8_0_0 + 3.30666666666667*G0_1_1_8_0_1 - 0.533333333333331*G0_1_1_9_0_0 - 2.22476190476189*G0_1_1_9_0_1 - 0.181164021164021*G0_1_1_10_1_0 - 0.181164021164021*G0_1_1_10_1_1 - 1.67280423280423*G0_1_1_11_1_0 - 0.296296296296297*G0_1_1_12_1_1 - 0.165079365079364*G0_1_1_13_1_0 - 3.30666666666666*G0_1_1_13_1_1 + 0.292063492063489*G0_1_1_14_1_0 + 2.05714285714285*G0_1_1_14_1_1 + 0.698412698412695*G0_1_1_15_1_0 + 0.833015873015873*G0_1_1_15_1_1 - 0.292063492063488*G0_1_1_16_1_0 - 0.355555555555555*G0_1_1_16_1_1 + 0.302222222222217*G0_1_1_17_1_0 + 0.167619047619039*G0_1_1_17_1_1 + 1.55174603174604*G0_1_1_18_1_0 + 3.30666666666667*G0_1_1_18_1_1 - 0.533333333333331*G0_1_1_19_1_0 - 2.22476190476189*G0_1_1_19_1_1; + A[799] = A[334]; + A[128] = -A[125] - 0.761904761904759*G0_0_1_0_0_0 - 0.76190476190476*G0_0_1_0_0_1 - 0.355555555555553*G0_0_1_1_0_0 + 1.95555555555554*G0_0_1_2_0_1 + 1.6*G0_0_1_3_0_0 - 0.0888888888888847*G0_0_1_3_0_1 + 4.4190476190476*G0_0_1_4_0_0 + 3.79682539682538*G0_0_1_4_0_1 + 3.27619047619046*G0_0_1_5_0_0 + 2.98412698412697*G0_0_1_5_0_1 - 4.41904761904759*G0_0_1_6_0_0 - 4.17777777777776*G0_0_1_6_0_1 + 0.558730158730156*G0_0_1_7_0_0 + 0.850793650793643*G0_0_1_7_0_1 + 0.558730158730156*G0_0_1_8_0_0 + 0.0888888888888848*G0_0_1_8_0_1 - 4.87619047619046*G0_0_1_9_0_0 - 4.64761904761902*G0_0_1_9_0_1 - 0.761904761904759*G0_0_1_10_1_0 - 0.76190476190476*G0_0_1_10_1_1 - 0.355555555555553*G0_0_1_11_1_0 + 1.95555555555554*G0_0_1_12_1_1 + 1.6*G0_0_1_13_1_0 - 0.0888888888888847*G0_0_1_13_1_1 + 4.4190476190476*G0_0_1_14_1_0 + 3.79682539682538*G0_0_1_14_1_1 + 3.27619047619046*G0_0_1_15_1_0 + 2.98412698412697*G0_0_1_15_1_1 - 4.41904761904759*G0_0_1_16_1_0 - 4.17777777777776*G0_0_1_16_1_1 + 0.558730158730156*G0_0_1_17_1_0 + 0.850793650793643*G0_0_1_17_1_1 + 0.558730158730156*G0_0_1_18_1_0 + 0.0888888888888848*G0_0_1_18_1_1 - 4.87619047619046*G0_0_1_19_1_0 - 4.64761904761902*G0_0_1_19_1_1 - 0.181164021164021*G0_1_1_0_0_0 - 0.181164021164021*G0_1_1_0_0_1 - 1.67280423280423*G0_1_1_1_0_0 - 0.296296296296297*G0_1_1_2_0_1 - 0.165079365079364*G0_1_1_3_0_0 - 3.30666666666666*G0_1_1_3_0_1 + 0.292063492063489*G0_1_1_4_0_0 + 2.05714285714285*G0_1_1_4_0_1 + 0.698412698412695*G0_1_1_5_0_0 + 0.833015873015873*G0_1_1_5_0_1 - 0.292063492063488*G0_1_1_6_0_0 - 0.355555555555555*G0_1_1_6_0_1 + 0.302222222222217*G0_1_1_7_0_0 + 0.167619047619039*G0_1_1_7_0_1 + 1.55174603174604*G0_1_1_8_0_0 + 3.30666666666667*G0_1_1_8_0_1 - 0.533333333333331*G0_1_1_9_0_0 - 2.22476190476189*G0_1_1_9_0_1 - 0.181164021164021*G0_1_1_10_1_0 - 0.181164021164021*G0_1_1_10_1_1 - 1.67280423280423*G0_1_1_11_1_0 - 0.296296296296297*G0_1_1_12_1_1 - 0.165079365079364*G0_1_1_13_1_0 - 3.30666666666666*G0_1_1_13_1_1 + 0.292063492063489*G0_1_1_14_1_0 + 2.05714285714285*G0_1_1_14_1_1 + 0.698412698412695*G0_1_1_15_1_0 + 0.833015873015873*G0_1_1_15_1_1 - 0.292063492063488*G0_1_1_16_1_0 - 0.355555555555555*G0_1_1_16_1_1 + 0.302222222222217*G0_1_1_17_1_0 + 0.167619047619039*G0_1_1_17_1_1 + 1.55174603174604*G0_1_1_18_1_0 + 3.30666666666667*G0_1_1_18_1_1 - 0.533333333333331*G0_1_1_19_1_0 - 2.22476190476189*G0_1_1_19_1_1; + A[244] = A[709]; + A[123] = A[588]; + A[776] = A[805] + 0.467301587301585*G0_0_1_0_0_0 + 0.467301587301585*G0_0_1_0_0_1 + 0.863492063492055*G0_0_1_1_0_0 + 0.548571428571425*G0_0_1_2_0_1 + 0.888888888888883*G0_0_1_3_0_0 + 2.9206349206349*G0_0_1_3_0_1 - 0.238730158730159*G0_0_1_4_0_0 - 1.95555555555555*G0_0_1_4_0_1 - 0.24888888888889*G0_0_1_5_0_0 - 0.309841269841266*G0_0_1_5_0_1 + 0.238730158730159*G0_0_1_6_0_0 - 0.706031746031744*G0_0_1_6_0_1 - 2.52444444444444*G0_0_1_7_0_0 - 2.46349206349206*G0_0_1_7_0_1 + 1.1936507936508*G0_0_1_8_0_0 - 2.9206349206349*G0_0_1_8_0_1 - 0.639999999999994*G0_0_1_9_0_0 + 4.41904761904761*G0_0_1_9_0_1 + 0.467301587301585*G0_0_1_10_1_0 + 0.467301587301585*G0_0_1_10_1_1 + 0.863492063492055*G0_0_1_11_1_0 + 0.548571428571425*G0_0_1_12_1_1 + 0.888888888888883*G0_0_1_13_1_0 + 2.9206349206349*G0_0_1_13_1_1 - 0.238730158730159*G0_0_1_14_1_0 - 1.95555555555555*G0_0_1_14_1_1 - 0.24888888888889*G0_0_1_15_1_0 - 0.309841269841266*G0_0_1_15_1_1 + 0.238730158730159*G0_0_1_16_1_0 - 0.706031746031744*G0_0_1_16_1_1 - 2.52444444444444*G0_0_1_17_1_0 - 2.46349206349206*G0_0_1_17_1_1 + 1.1936507936508*G0_0_1_18_1_0 - 2.9206349206349*G0_0_1_18_1_1 - 0.639999999999994*G0_0_1_19_1_0 + 4.41904761904761*G0_0_1_19_1_1 - 0.467301587301585*G0_1_0_0_0_0 - 0.467301587301584*G0_1_0_0_0_1 - 0.863492063492056*G0_1_0_1_0_0 - 0.548571428571425*G0_1_0_2_0_1 - 0.888888888888883*G0_1_0_3_0_0 - 2.9206349206349*G0_1_0_3_0_1 + 0.238730158730159*G0_1_0_4_0_0 + 1.95555555555555*G0_1_0_4_0_1 + 0.24888888888889*G0_1_0_5_0_0 + 0.309841269841266*G0_1_0_5_0_1 - 0.238730158730159*G0_1_0_6_0_0 + 0.706031746031744*G0_1_0_6_0_1 + 2.52444444444444*G0_1_0_7_0_0 + 2.46349206349206*G0_1_0_7_0_1 - 1.1936507936508*G0_1_0_8_0_0 + 2.9206349206349*G0_1_0_8_0_1 + 0.639999999999994*G0_1_0_9_0_0 - 4.41904761904761*G0_1_0_9_0_1 - 0.467301587301585*G0_1_0_10_1_0 - 0.467301587301584*G0_1_0_10_1_1 - 0.863492063492056*G0_1_0_11_1_0 - 0.548571428571425*G0_1_0_12_1_1 - 0.888888888888883*G0_1_0_13_1_0 - 2.9206349206349*G0_1_0_13_1_1 + 0.238730158730159*G0_1_0_14_1_0 + 1.95555555555555*G0_1_0_14_1_1 + 0.24888888888889*G0_1_0_15_1_0 + 0.309841269841266*G0_1_0_15_1_1 - 0.238730158730159*G0_1_0_16_1_0 + 0.706031746031744*G0_1_0_16_1_1 + 2.52444444444444*G0_1_0_17_1_0 + 2.46349206349206*G0_1_0_17_1_1 - 1.1936507936508*G0_1_0_18_1_0 + 2.9206349206349*G0_1_0_18_1_1 + 0.639999999999994*G0_1_0_19_1_0 - 4.41904761904761*G0_1_0_19_1_1; + A[303] = -A[776] + 1.31724867724867*G0_0_0_0_0_0 + 1.31724867724867*G0_0_0_0_0_1 - 2.25185185185184*G0_0_0_1_0_0 - 0.580740740740739*G0_0_0_2_0_1 - 0.304761904761904*G0_0_0_3_0_0 - 4.12698412698411*G0_0_0_3_0_1 + 0.426666666666666*G0_0_0_4_0_0 + 2.57777777777777*G0_0_0_4_0_1 + 2.22476190476189*G0_0_0_5_0_0 - 0.993015873015873*G0_0_0_5_0_1 - 0.426666666666666*G0_0_0_6_0_0 + 0.256507936507939*G0_0_0_6_0_1 - 1.45269841269841*G0_0_0_7_0_0 + 1.76507936507936*G0_0_0_7_0_1 + 2.38730158730158*G0_0_0_8_0_0 + 4.12698412698411*G0_0_0_8_0_1 - 1.91999999999999*G0_0_0_9_0_0 - 4.34285714285713*G0_0_0_9_0_1 + 1.31724867724867*G0_0_0_10_1_0 + 1.31724867724867*G0_0_0_10_1_1 - 2.25185185185184*G0_0_0_11_1_0 - 0.580740740740739*G0_0_0_12_1_1 - 0.304761904761904*G0_0_0_13_1_0 - 4.12698412698411*G0_0_0_13_1_1 + 0.426666666666666*G0_0_0_14_1_0 + 2.57777777777777*G0_0_0_14_1_1 + 2.22476190476189*G0_0_0_15_1_0 - 0.993015873015873*G0_0_0_15_1_1 - 0.426666666666666*G0_0_0_16_1_0 + 0.256507936507939*G0_0_0_16_1_1 - 1.45269841269841*G0_0_0_17_1_0 + 1.76507936507936*G0_0_0_17_1_1 + 2.38730158730158*G0_0_0_18_1_0 + 4.12698412698411*G0_0_0_18_1_1 - 1.91999999999999*G0_0_0_19_1_0 - 4.34285714285713*G0_0_0_19_1_1 - 0.355555555555553*G0_1_0_0_0_0 - 0.355555555555553*G0_1_0_0_0_1 - 1.95555555555555*G0_1_0_1_0_0 - 0.761904761904758*G0_1_0_2_0_1 - 0.241269841269842*G0_1_0_3_0_0 - 4.4190476190476*G0_1_0_3_0_1 + 0.292063492063494*G0_1_0_4_0_0 + 3.27619047619046*G0_1_0_4_0_1 + 0.469841269841269*G0_1_0_5_0_0 + 0.558730158730155*G0_1_0_5_0_1 - 0.292063492063494*G0_1_0_6_0_0 + 0.558730158730156*G0_1_0_6_0_1 + 1.68888888888888*G0_1_0_7_0_0 + 1.59999999999999*G0_1_0_7_0_1 + 0.622222222222219*G0_1_0_8_0_0 + 4.4190476190476*G0_1_0_8_0_1 - 0.228571428571426*G0_1_0_9_0_0 - 4.87619047619046*G0_1_0_9_0_1 - 0.355555555555553*G0_1_0_10_1_0 - 0.355555555555553*G0_1_0_10_1_1 - 1.95555555555555*G0_1_0_11_1_0 - 0.761904761904758*G0_1_0_12_1_1 - 0.241269841269842*G0_1_0_13_1_0 - 4.4190476190476*G0_1_0_13_1_1 + 0.292063492063494*G0_1_0_14_1_0 + 3.27619047619046*G0_1_0_14_1_1 + 0.469841269841269*G0_1_0_15_1_0 + 0.558730158730155*G0_1_0_15_1_1 - 0.292063492063494*G0_1_0_16_1_0 + 0.558730158730156*G0_1_0_16_1_1 + 1.68888888888888*G0_1_0_17_1_0 + 1.59999999999999*G0_1_0_17_1_1 + 0.622222222222219*G0_1_0_18_1_0 + 4.4190476190476*G0_1_0_18_1_1 - 0.228571428571426*G0_1_0_19_1_0 - 4.87619047619046*G0_1_0_19_1_1; + A[619] = A[154]; + A[565] = -A[805] + 1.31724867724867*G0_0_0_0_0_0 + 1.31724867724867*G0_0_0_0_0_1 - 2.25185185185184*G0_0_0_1_0_0 - 0.580740740740739*G0_0_0_2_0_1 - 0.304761904761904*G0_0_0_3_0_0 - 4.12698412698411*G0_0_0_3_0_1 + 0.426666666666666*G0_0_0_4_0_0 + 2.57777777777777*G0_0_0_4_0_1 + 2.22476190476189*G0_0_0_5_0_0 - 0.993015873015873*G0_0_0_5_0_1 - 0.426666666666666*G0_0_0_6_0_0 + 0.256507936507939*G0_0_0_6_0_1 - 1.45269841269841*G0_0_0_7_0_0 + 1.76507936507936*G0_0_0_7_0_1 + 2.38730158730158*G0_0_0_8_0_0 + 4.12698412698411*G0_0_0_8_0_1 - 1.91999999999999*G0_0_0_9_0_0 - 4.34285714285713*G0_0_0_9_0_1 + 1.31724867724867*G0_0_0_10_1_0 + 1.31724867724867*G0_0_0_10_1_1 - 2.25185185185184*G0_0_0_11_1_0 - 0.580740740740739*G0_0_0_12_1_1 - 0.304761904761904*G0_0_0_13_1_0 - 4.12698412698411*G0_0_0_13_1_1 + 0.426666666666666*G0_0_0_14_1_0 + 2.57777777777777*G0_0_0_14_1_1 + 2.22476190476189*G0_0_0_15_1_0 - 0.993015873015873*G0_0_0_15_1_1 - 0.426666666666666*G0_0_0_16_1_0 + 0.256507936507939*G0_0_0_16_1_1 - 1.45269841269841*G0_0_0_17_1_0 + 1.76507936507936*G0_0_0_17_1_1 + 2.38730158730158*G0_0_0_18_1_0 + 4.12698412698411*G0_0_0_18_1_1 - 1.91999999999999*G0_0_0_19_1_0 - 4.34285714285713*G0_0_0_19_1_1 - 0.355555555555553*G0_0_1_0_0_0 - 0.355555555555553*G0_0_1_0_0_1 - 1.95555555555555*G0_0_1_1_0_0 - 0.761904761904758*G0_0_1_2_0_1 - 0.241269841269842*G0_0_1_3_0_0 - 4.4190476190476*G0_0_1_3_0_1 + 0.292063492063494*G0_0_1_4_0_0 + 3.27619047619046*G0_0_1_4_0_1 + 0.469841269841269*G0_0_1_5_0_0 + 0.558730158730155*G0_0_1_5_0_1 - 0.292063492063494*G0_0_1_6_0_0 + 0.558730158730156*G0_0_1_6_0_1 + 1.68888888888888*G0_0_1_7_0_0 + 1.59999999999999*G0_0_1_7_0_1 + 0.622222222222219*G0_0_1_8_0_0 + 4.4190476190476*G0_0_1_8_0_1 - 0.228571428571426*G0_0_1_9_0_0 - 4.87619047619046*G0_0_1_9_0_1 - 0.355555555555553*G0_0_1_10_1_0 - 0.355555555555553*G0_0_1_10_1_1 - 1.95555555555555*G0_0_1_11_1_0 - 0.761904761904758*G0_0_1_12_1_1 - 0.241269841269842*G0_0_1_13_1_0 - 4.4190476190476*G0_0_1_13_1_1 + 0.292063492063494*G0_0_1_14_1_0 + 3.27619047619046*G0_0_1_14_1_1 + 0.469841269841269*G0_0_1_15_1_0 + 0.558730158730155*G0_0_1_15_1_1 - 0.292063492063494*G0_0_1_16_1_0 + 0.558730158730156*G0_0_1_16_1_1 + 1.68888888888888*G0_0_1_17_1_0 + 1.59999999999999*G0_0_1_17_1_1 + 0.622222222222219*G0_0_1_18_1_0 + 4.4190476190476*G0_0_1_18_1_1 - 0.228571428571426*G0_0_1_19_1_0 - 4.87619047619046*G0_0_1_19_1_1; + A[862] = A[397]; + A[157] = A[215] - 0.111746031746032*G0_0_1_0_0_0 - 0.111746031746032*G0_0_1_0_0_1 + 0.213333333333335*G0_0_1_1_0_0 + 1.09206349206349*G0_0_1_2_0_1 - 1.32063492063491*G0_0_1_3_0_0 - 0.053333333333328*G0_0_1_3_0_1 + 1.49841269841269*G0_0_1_4_0_0 - 0.647619047619044*G0_0_1_4_0_1 + 0.863492063492059*G0_0_1_5_0_0 + 0.835555555555551*G0_0_1_5_0_1 - 1.49841269841269*G0_0_1_6_0_0 - 1.81587301587301*G0_0_1_6_0_1 - 0.248888888888886*G0_0_1_7_0_0 - 0.220952380952379*G0_0_1_7_0_1 + 0.147301587301583*G0_0_1_8_0_0 + 0.0533333333333281*G0_0_1_8_0_1 + 0.457142857142853*G0_0_1_9_0_0 + 0.868571428571423*G0_0_1_9_0_1 - 0.111746031746032*G0_0_1_10_1_0 - 0.111746031746032*G0_0_1_10_1_1 + 0.213333333333335*G0_0_1_11_1_0 + 1.09206349206349*G0_0_1_12_1_1 - 1.32063492063491*G0_0_1_13_1_0 - 0.053333333333328*G0_0_1_13_1_1 + 1.49841269841269*G0_0_1_14_1_0 - 0.647619047619044*G0_0_1_14_1_1 + 0.863492063492059*G0_0_1_15_1_0 + 0.835555555555551*G0_0_1_15_1_1 - 1.49841269841269*G0_0_1_16_1_0 - 1.81587301587301*G0_0_1_16_1_1 - 0.248888888888886*G0_0_1_17_1_0 - 0.220952380952379*G0_0_1_17_1_1 + 0.147301587301583*G0_0_1_18_1_0 + 0.0533333333333281*G0_0_1_18_1_1 + 0.457142857142853*G0_0_1_19_1_0 + 0.868571428571423*G0_0_1_19_1_1 + 0.111746031746032*G0_1_0_0_0_0 + 0.111746031746032*G0_1_0_0_0_1 - 0.213333333333335*G0_1_0_1_0_0 - 1.09206349206349*G0_1_0_2_0_1 + 1.32063492063491*G0_1_0_3_0_0 + 0.053333333333328*G0_1_0_3_0_1 - 1.49841269841269*G0_1_0_4_0_0 + 0.647619047619044*G0_1_0_4_0_1 - 0.863492063492059*G0_1_0_5_0_0 - 0.835555555555552*G0_1_0_5_0_1 + 1.49841269841269*G0_1_0_6_0_0 + 1.81587301587301*G0_1_0_6_0_1 + 0.248888888888886*G0_1_0_7_0_0 + 0.220952380952379*G0_1_0_7_0_1 - 0.147301587301583*G0_1_0_8_0_0 - 0.0533333333333282*G0_1_0_8_0_1 - 0.457142857142853*G0_1_0_9_0_0 - 0.868571428571423*G0_1_0_9_0_1 + 0.111746031746032*G0_1_0_10_1_0 + 0.111746031746032*G0_1_0_10_1_1 - 0.213333333333335*G0_1_0_11_1_0 - 1.09206349206349*G0_1_0_12_1_1 + 1.32063492063491*G0_1_0_13_1_0 + 0.053333333333328*G0_1_0_13_1_1 - 1.49841269841269*G0_1_0_14_1_0 + 0.647619047619044*G0_1_0_14_1_1 - 0.863492063492059*G0_1_0_15_1_0 - 0.835555555555552*G0_1_0_15_1_1 + 1.49841269841269*G0_1_0_16_1_0 + 1.81587301587301*G0_1_0_16_1_1 + 0.248888888888886*G0_1_0_17_1_0 + 0.220952380952379*G0_1_0_17_1_1 - 0.147301587301583*G0_1_0_18_1_0 - 0.0533333333333282*G0_1_0_18_1_1 - 0.457142857142853*G0_1_0_19_1_0 - 0.868571428571423*G0_1_0_19_1_1; + A[100] = A[565]; + A[133] = A[394] - 0.579047619047616*G0_0_1_0_0_0 - 0.579047619047616*G0_0_1_0_0_1 + 0.60952380952381*G0_0_1_1_0_0 - 0.639999999999993*G0_0_1_2_0_1 + 2.05714285714285*G0_0_1_3_0_0 + 1.44761904761905*G0_0_1_3_0_1 - 0.868571428571417*G0_0_1_4_0_0 + 0.990476190476184*G0_0_1_4_0_1 + 0.777142857142859*G0_0_1_5_0_0 + 0.746666666666664*G0_0_1_5_0_1 + 0.868571428571418*G0_0_1_6_0_0 + 0.472380952380943*G0_0_1_6_0_1 + 2.17904761904761*G0_0_1_7_0_0 + 2.2095238095238*G0_0_1_7_0_1 - 2.2095238095238*G0_0_1_8_0_0 - 1.44761904761905*G0_0_1_8_0_1 - 2.83428571428571*G0_0_1_9_0_0 - 3.19999999999998*G0_0_1_9_0_1 - 0.579047619047616*G0_0_1_10_1_0 - 0.579047619047616*G0_0_1_10_1_1 + 0.60952380952381*G0_0_1_11_1_0 - 0.639999999999993*G0_0_1_12_1_1 + 2.05714285714285*G0_0_1_13_1_0 + 1.44761904761905*G0_0_1_13_1_1 - 0.868571428571417*G0_0_1_14_1_0 + 0.990476190476184*G0_0_1_14_1_1 + 0.777142857142859*G0_0_1_15_1_0 + 0.746666666666664*G0_0_1_15_1_1 + 0.868571428571418*G0_0_1_16_1_0 + 0.472380952380943*G0_0_1_16_1_1 + 2.17904761904761*G0_0_1_17_1_0 + 2.2095238095238*G0_0_1_17_1_1 - 2.2095238095238*G0_0_1_18_1_0 - 1.44761904761905*G0_0_1_18_1_1 - 2.83428571428571*G0_0_1_19_1_0 - 3.19999999999998*G0_0_1_19_1_1 + 0.579047619047616*G0_1_0_0_0_0 + 0.579047619047616*G0_1_0_0_0_1 - 0.60952380952381*G0_1_0_1_0_0 + 0.639999999999992*G0_1_0_2_0_1 - 2.05714285714285*G0_1_0_3_0_0 - 1.44761904761905*G0_1_0_3_0_1 + 0.868571428571418*G0_1_0_4_0_0 - 0.990476190476183*G0_1_0_4_0_1 - 0.777142857142859*G0_1_0_5_0_0 - 0.746666666666664*G0_1_0_5_0_1 - 0.868571428571418*G0_1_0_6_0_0 - 0.472380952380943*G0_1_0_6_0_1 - 2.1790476190476*G0_1_0_7_0_0 - 2.2095238095238*G0_1_0_7_0_1 + 2.2095238095238*G0_1_0_8_0_0 + 1.44761904761905*G0_1_0_8_0_1 + 2.8342857142857*G0_1_0_9_0_0 + 3.19999999999998*G0_1_0_9_0_1 + 0.579047619047616*G0_1_0_10_1_0 + 0.579047619047616*G0_1_0_10_1_1 - 0.60952380952381*G0_1_0_11_1_0 + 0.639999999999992*G0_1_0_12_1_1 - 2.05714285714285*G0_1_0_13_1_0 - 1.44761904761905*G0_1_0_13_1_1 + 0.868571428571418*G0_1_0_14_1_0 - 0.990476190476183*G0_1_0_14_1_1 - 0.777142857142859*G0_1_0_15_1_0 - 0.746666666666664*G0_1_0_15_1_1 - 0.868571428571418*G0_1_0_16_1_0 - 0.472380952380943*G0_1_0_16_1_1 - 2.1790476190476*G0_1_0_17_1_0 - 2.2095238095238*G0_1_0_17_1_1 + 2.2095238095238*G0_1_0_18_1_0 + 1.44761904761905*G0_1_0_18_1_1 + 2.8342857142857*G0_1_0_19_1_0 + 3.19999999999998*G0_1_0_19_1_1; + A[622] = A[157]; + A[542] = 0.0; + A[664] = 0.0; + A[691] = 0.0; + A[266] = 0.0; + A[337] = A[802]; + A[297] = 0.0; + A[749] = A[429] + 0.406349206349212*G0_0_1_0_0_0 + 0.406349206349212*G0_0_1_0_0_1 - 0.243809523809523*G0_0_1_1_0_0 - 0.0203174603174651*G0_0_1_2_0_1 + 0.264126984126981*G0_0_1_3_0_0 + 0.060952380952381*G0_0_1_3_0_1 - 0.223492063492069*G0_0_1_4_0_0 - 0.243809523809526*G0_0_1_4_0_1 + 0.22349206349206*G0_0_1_5_0_0 - 0.284444444444459*G0_0_1_5_0_1 + 0.223492063492069*G0_0_1_6_0_0 - 0.101587301587288*G0_0_1_6_0_1 - 1.23936507936508*G0_0_1_7_0_0 - 0.731428571428563*G0_0_1_7_0_1 + 1.07682539682539*G0_0_1_8_0_0 - 0.0609523809523808*G0_0_1_8_0_1 - 0.487619047619041*G0_0_1_9_0_0 + 0.975238095238089*G0_0_1_9_0_1 + 0.406349206349212*G0_0_1_10_1_0 + 0.406349206349212*G0_0_1_10_1_1 - 0.243809523809523*G0_0_1_11_1_0 - 0.0203174603174651*G0_0_1_12_1_1 + 0.264126984126981*G0_0_1_13_1_0 + 0.060952380952381*G0_0_1_13_1_1 - 0.223492063492069*G0_0_1_14_1_0 - 0.243809523809526*G0_0_1_14_1_1 + 0.22349206349206*G0_0_1_15_1_0 - 0.284444444444459*G0_0_1_15_1_1 + 0.223492063492069*G0_0_1_16_1_0 - 0.101587301587288*G0_0_1_16_1_1 - 1.23936507936508*G0_0_1_17_1_0 - 0.731428571428563*G0_0_1_17_1_1 + 1.07682539682539*G0_0_1_18_1_0 - 0.0609523809523808*G0_0_1_18_1_1 - 0.487619047619041*G0_0_1_19_1_0 + 0.975238095238089*G0_0_1_19_1_1 - 0.406349206349213*G0_1_0_0_0_0 - 0.406349206349212*G0_1_0_0_0_1 + 0.243809523809523*G0_1_0_1_0_0 + 0.0203174603174651*G0_1_0_2_0_1 - 0.264126984126981*G0_1_0_3_0_0 - 0.0609523809523808*G0_1_0_3_0_1 + 0.223492063492069*G0_1_0_4_0_0 + 0.243809523809526*G0_1_0_4_0_1 - 0.22349206349206*G0_1_0_5_0_0 + 0.284444444444459*G0_1_0_5_0_1 - 0.223492063492069*G0_1_0_6_0_0 + 0.101587301587288*G0_1_0_6_0_1 + 1.23936507936508*G0_1_0_7_0_0 + 0.731428571428563*G0_1_0_7_0_1 - 1.07682539682539*G0_1_0_8_0_0 + 0.0609523809523806*G0_1_0_8_0_1 + 0.487619047619041*G0_1_0_9_0_0 - 0.975238095238089*G0_1_0_9_0_1 - 0.406349206349213*G0_1_0_10_1_0 - 0.406349206349212*G0_1_0_10_1_1 + 0.243809523809523*G0_1_0_11_1_0 + 0.0203174603174651*G0_1_0_12_1_1 - 0.264126984126981*G0_1_0_13_1_0 - 0.0609523809523808*G0_1_0_13_1_1 + 0.223492063492069*G0_1_0_14_1_0 + 0.243809523809526*G0_1_0_14_1_1 - 0.22349206349206*G0_1_0_15_1_0 + 0.284444444444459*G0_1_0_15_1_1 - 0.223492063492069*G0_1_0_16_1_0 + 0.101587301587288*G0_1_0_16_1_1 + 1.23936507936508*G0_1_0_17_1_0 + 0.731428571428563*G0_1_0_17_1_1 - 1.07682539682539*G0_1_0_18_1_0 + 0.0609523809523806*G0_1_0_18_1_1 + 0.487619047619041*G0_1_0_19_1_0 - 0.975238095238089*G0_1_0_19_1_1; + A[436] = 0.0; + A[360] = A[887] + 0.973544973544967*G0_0_0_0_0_0 + 0.973544973544967*G0_0_0_0_0_1 - 0.125291005291004*G0_0_0_1_0_0 - 0.023703703703703*G0_0_0_2_0_1 + 0.678095238095234*G0_0_0_3_0_0 + 0.372063492063489*G0_0_0_3_0_1 + 0.441904761904761*G0_0_0_4_0_0 + 0.646349206349203*G0_0_0_4_0_1 + 0.799999999999994*G0_0_0_5_0_0 - 1.26349206349206*G0_0_0_5_0_1 - 0.441904761904761*G0_0_0_6_0_0 + 0.313650793650792*G0_0_0_6_0_1 - 1.49841269841269*G0_0_0_7_0_0 + 0.565079365079361*G0_0_0_7_0_1 + 0.650158730158725*G0_0_0_8_0_0 - 0.37206349206349*G0_0_0_8_0_1 - 1.47809523809523*G0_0_0_9_0_0 - 1.21142857142856*G0_0_0_9_0_1 + 0.973544973544967*G0_0_0_10_1_0 + 0.973544973544967*G0_0_0_10_1_1 - 0.125291005291004*G0_0_0_11_1_0 - 0.023703703703703*G0_0_0_12_1_1 + 0.678095238095234*G0_0_0_13_1_0 + 0.372063492063489*G0_0_0_13_1_1 + 0.441904761904761*G0_0_0_14_1_0 + 0.646349206349203*G0_0_0_14_1_1 + 0.799999999999994*G0_0_0_15_1_0 - 1.26349206349206*G0_0_0_15_1_1 - 0.441904761904761*G0_0_0_16_1_0 + 0.313650793650792*G0_0_0_16_1_1 - 1.49841269841269*G0_0_0_17_1_0 + 0.565079365079361*G0_0_0_17_1_1 + 0.650158730158725*G0_0_0_18_1_0 - 0.37206349206349*G0_0_0_18_1_1 - 1.47809523809523*G0_0_0_19_1_0 - 1.21142857142856*G0_0_0_19_1_1 + 0.871957671957666*G0_0_1_0_0_0 + 0.871957671957666*G0_0_1_0_0_1 - 0.226878306878304*G0_0_1_1_0_0 - 0.023703703703698*G0_0_1_2_0_1 + 0.944761904761894*G0_0_1_3_0_0 + 0.302222222222219*G0_0_1_3_0_1 + 0.441904761904771*G0_0_1_4_0_0 + 0.881269841269839*G0_0_1_4_0_1 + 1.06666666666666*G0_0_1_5_0_0 - 0.926984126984119*G0_0_1_5_0_1 - 0.44190476190477*G0_0_1_6_0_0 + 0.0787301587301522*G0_0_1_6_0_1 - 1.39682539682539*G0_0_1_7_0_0 + 0.596825396825393*G0_0_1_7_0_1 + 0.751746031746025*G0_0_1_8_0_0 - 0.302222222222219*G0_0_1_8_0_1 - 2.01142857142856*G0_0_1_9_0_0 - 1.47809523809523*G0_0_1_9_0_1 + 0.871957671957666*G0_0_1_10_1_0 + 0.871957671957666*G0_0_1_10_1_1 - 0.226878306878304*G0_0_1_11_1_0 - 0.023703703703698*G0_0_1_12_1_1 + 0.944761904761894*G0_0_1_13_1_0 + 0.302222222222219*G0_0_1_13_1_1 + 0.441904761904771*G0_0_1_14_1_0 + 0.881269841269839*G0_0_1_14_1_1 + 1.06666666666666*G0_0_1_15_1_0 - 0.926984126984119*G0_0_1_15_1_1 - 0.44190476190477*G0_0_1_16_1_0 + 0.0787301587301522*G0_0_1_16_1_1 - 1.39682539682539*G0_0_1_17_1_0 + 0.596825396825393*G0_0_1_17_1_1 + 0.751746031746025*G0_0_1_18_1_0 - 0.302222222222219*G0_0_1_18_1_1 - 2.01142857142856*G0_0_1_19_1_0 - 1.47809523809523*G0_0_1_19_1_1 + 0.973544973544969*G0_1_0_0_0_0 + 0.973544973544969*G0_1_0_0_0_1 - 0.0237037037037036*G0_1_0_1_0_0 - 0.125291005291004*G0_1_0_2_0_1 + 0.646349206349203*G0_1_0_3_0_0 + 0.441904761904759*G0_1_0_3_0_1 + 0.372063492063491*G0_1_0_4_0_0 + 0.678095238095236*G0_1_0_4_0_1 + 0.565079365079362*G0_1_0_5_0_0 - 1.49841269841269*G0_1_0_5_0_1 - 0.372063492063491*G0_1_0_6_0_0 + 0.650158730158728*G0_1_0_6_0_1 - 1.26349206349206*G0_1_0_7_0_0 + 0.799999999999996*G0_1_0_7_0_1 + 0.313650793650792*G0_1_0_8_0_0 - 0.441904761904759*G0_1_0_8_0_1 - 1.21142857142856*G0_1_0_9_0_0 - 1.47809523809523*G0_1_0_9_0_1 + 0.973544973544969*G0_1_0_10_1_0 + 0.973544973544969*G0_1_0_10_1_1 - 0.0237037037037036*G0_1_0_11_1_0 - 0.125291005291004*G0_1_0_12_1_1 + 0.646349206349203*G0_1_0_13_1_0 + 0.441904761904759*G0_1_0_13_1_1 + 0.372063492063491*G0_1_0_14_1_0 + 0.678095238095236*G0_1_0_14_1_1 + 0.565079365079362*G0_1_0_15_1_0 - 1.49841269841269*G0_1_0_15_1_1 - 0.372063492063491*G0_1_0_16_1_0 + 0.650158730158728*G0_1_0_16_1_1 - 1.26349206349206*G0_1_0_17_1_0 + 0.799999999999996*G0_1_0_17_1_1 + 0.313650793650792*G0_1_0_18_1_0 - 0.441904761904759*G0_1_0_18_1_1 - 1.21142857142856*G0_1_0_19_1_0 - 1.47809523809523*G0_1_0_19_1_1 + 0.848253968253964*G0_1_1_0_0_0 + 0.848253968253965*G0_1_1_0_0_1 + 0.848253968253965*G0_1_1_2_0_1 - 0.10920634920635*G0_1_1_3_0_0 + 2.43555555555555*G0_1_1_4_0_0 + 1.47809523809523*G0_1_1_4_0_1 + 1.58730158730158*G0_1_1_5_0_0 - 0.848253968253964*G0_1_1_5_0_1 - 2.43555555555555*G0_1_1_6_0_0 - 0.848253968253965*G0_1_1_6_0_1 - 0.957460317460314*G0_1_1_7_0_0 + 1.47809523809523*G0_1_1_7_0_1 + 0.109206349206348*G0_1_1_8_0_0 - 1.47809523809523*G0_1_1_9_0_0 - 2.95619047619046*G0_1_1_9_0_1 + 0.848253968253964*G0_1_1_10_1_0 + 0.848253968253965*G0_1_1_10_1_1 + 0.848253968253965*G0_1_1_12_1_1 - 0.10920634920635*G0_1_1_13_1_0 + 2.43555555555555*G0_1_1_14_1_0 + 1.47809523809523*G0_1_1_14_1_1 + 1.58730158730158*G0_1_1_15_1_0 - 0.848253968253964*G0_1_1_15_1_1 - 2.43555555555555*G0_1_1_16_1_0 - 0.848253968253965*G0_1_1_16_1_1 - 0.957460317460314*G0_1_1_17_1_0 + 1.47809523809523*G0_1_1_17_1_1 + 0.109206349206348*G0_1_1_18_1_0 - 1.47809523809523*G0_1_1_19_1_0 - 2.95619047619046*G0_1_1_19_1_1; + A[316] = 0.0; + A[774] = A[309]; + A[471] = A[645] + 2.80423280423279*G0_0_1_0_0_0 + 2.80423280423279*G0_0_1_0_0_1 - 0.423280423280421*G0_0_1_1_0_0 - 0.423280423280421*G0_0_1_2_0_1 + 0.14920634920635*G0_0_1_3_0_0 + 0.149206349206347*G0_0_1_3_0_1 + 0.14920634920635*G0_0_1_4_0_0 + 0.149206349206351*G0_0_1_4_0_1 + 0.860317460317457*G0_0_1_5_0_0 - 4.25714285714284*G0_0_1_5_0_1 - 0.14920634920635*G0_0_1_6_0_0 + 1.87619047619047*G0_0_1_6_0_1 - 4.25714285714283*G0_0_1_7_0_0 + 0.860317460317456*G0_0_1_7_0_1 + 1.87619047619046*G0_0_1_8_0_0 - 0.149206349206347*G0_0_1_8_0_1 - 1.00952380952381*G0_0_1_9_0_0 - 1.00952380952381*G0_0_1_9_0_1 + 2.80423280423279*G0_0_1_10_1_0 + 2.80423280423279*G0_0_1_10_1_1 - 0.423280423280421*G0_0_1_11_1_0 - 0.423280423280421*G0_0_1_12_1_1 + 0.14920634920635*G0_0_1_13_1_0 + 0.149206349206347*G0_0_1_13_1_1 + 0.14920634920635*G0_0_1_14_1_0 + 0.149206349206351*G0_0_1_14_1_1 + 0.860317460317457*G0_0_1_15_1_0 - 4.25714285714284*G0_0_1_15_1_1 - 0.14920634920635*G0_0_1_16_1_0 + 1.87619047619047*G0_0_1_16_1_1 - 4.25714285714283*G0_0_1_17_1_0 + 0.860317460317456*G0_0_1_17_1_1 + 1.87619047619046*G0_0_1_18_1_0 - 0.149206349206347*G0_0_1_18_1_1 - 1.00952380952381*G0_0_1_19_1_0 - 1.00952380952381*G0_0_1_19_1_1 - 2.80423280423279*G0_1_0_0_0_0 - 2.80423280423279*G0_1_0_0_0_1 + 0.423280423280421*G0_1_0_1_0_0 + 0.423280423280421*G0_1_0_2_0_1 - 0.14920634920635*G0_1_0_3_0_0 - 0.149206349206347*G0_1_0_3_0_1 - 0.14920634920635*G0_1_0_4_0_0 - 0.149206349206351*G0_1_0_4_0_1 - 0.860317460317457*G0_1_0_5_0_0 + 4.25714285714284*G0_1_0_5_0_1 + 0.14920634920635*G0_1_0_6_0_0 - 1.87619047619047*G0_1_0_6_0_1 + 4.25714285714283*G0_1_0_7_0_0 - 0.860317460317456*G0_1_0_7_0_1 - 1.87619047619046*G0_1_0_8_0_0 + 0.149206349206347*G0_1_0_8_0_1 + 1.00952380952381*G0_1_0_9_0_0 + 1.00952380952381*G0_1_0_9_0_1 - 2.80423280423279*G0_1_0_10_1_0 - 2.80423280423279*G0_1_0_10_1_1 + 0.423280423280421*G0_1_0_11_1_0 + 0.423280423280421*G0_1_0_12_1_1 - 0.14920634920635*G0_1_0_13_1_0 - 0.149206349206347*G0_1_0_13_1_1 - 0.14920634920635*G0_1_0_14_1_0 - 0.149206349206351*G0_1_0_14_1_1 - 0.860317460317457*G0_1_0_15_1_0 + 4.25714285714284*G0_1_0_15_1_1 + 0.14920634920635*G0_1_0_16_1_0 - 1.87619047619047*G0_1_0_16_1_1 + 4.25714285714283*G0_1_0_17_1_0 - 0.860317460317456*G0_1_0_17_1_1 - 1.87619047619046*G0_1_0_18_1_0 + 0.149206349206347*G0_1_0_18_1_1 + 1.00952380952381*G0_1_0_19_1_0 + 1.00952380952381*G0_1_0_19_1_1; + A[395] = A[860]; + A[359] = 0.0; + A[6] = A[471]; + A[723] = 0.0; + A[37] = A[502]; + A[752] = 0.0; + A[865] = A[224] - 0.396190476190475*G0_0_0_0_0_0 - 0.396190476190476*G0_0_0_0_0_1 - 0.761904761904753*G0_0_0_1_0_0 + 2.56*G0_0_0_2_0_1 - 5.21142857142855*G0_0_0_3_0_0 - 4.49523809523807*G0_0_0_3_0_1 + 7.58857142857142*G0_0_0_4_0_0 + 3.55047619047618*G0_0_0_4_0_1 - 5.57714285714283*G0_0_0_5_0_0 - 2.36190476190475*G0_0_0_5_0_1 - 7.58857142857142*G0_0_0_6_0_0 + 0.198095238095226*G0_0_0_6_0_1 - 0.243809523809518*G0_0_0_7_0_0 - 3.4590476190476*G0_0_0_7_0_1 + 1.40190476190474*G0_0_0_8_0_0 + 4.49523809523807*G0_0_0_8_0_1 + 10.7885714285714*G0_0_0_9_0_0 - 0.0914285714285885*G0_0_0_9_0_1 - 0.396190476190475*G0_0_0_10_1_0 - 0.396190476190476*G0_0_0_10_1_1 - 0.761904761904753*G0_0_0_11_1_0 + 2.56*G0_0_0_12_1_1 - 5.21142857142855*G0_0_0_13_1_0 - 4.49523809523807*G0_0_0_13_1_1 + 7.58857142857142*G0_0_0_14_1_0 + 3.55047619047618*G0_0_0_14_1_1 - 5.57714285714283*G0_0_0_15_1_0 - 2.36190476190475*G0_0_0_15_1_1 - 7.58857142857142*G0_0_0_16_1_0 + 0.198095238095226*G0_0_0_16_1_1 - 0.243809523809518*G0_0_0_17_1_0 - 3.4590476190476*G0_0_0_17_1_1 + 1.40190476190474*G0_0_0_18_1_0 + 4.49523809523807*G0_0_0_18_1_1 + 10.7885714285714*G0_0_0_19_1_0 - 0.0914285714285885*G0_0_0_19_1_1 - 2.2095238095238*G0_0_1_1_0_0 + 2.2095238095238*G0_0_1_2_0_1 - 3.1238095238095*G0_0_1_3_0_0 - 5.3333333333333*G0_0_1_3_0_1 + 5.33333333333331*G0_0_1_4_0_0 + 3.12380952380951*G0_0_1_4_0_1 + 1.29523809523809*G0_0_1_5_0_0 + 1.2952380952381*G0_0_1_5_0_1 - 5.33333333333331*G0_0_1_6_0_0 - 3.50476190476189*G0_0_1_6_0_1 - 1.29523809523808*G0_0_1_7_0_0 - 1.29523809523808*G0_0_1_7_0_1 + 3.50476190476188*G0_0_1_8_0_0 + 5.3333333333333*G0_0_1_8_0_1 + 1.82857142857141*G0_0_1_9_0_0 - 1.82857142857143*G0_0_1_9_0_1 - 2.2095238095238*G0_0_1_11_1_0 + 2.2095238095238*G0_0_1_12_1_1 - 3.1238095238095*G0_0_1_13_1_0 - 5.3333333333333*G0_0_1_13_1_1 + 5.33333333333331*G0_0_1_14_1_0 + 3.12380952380951*G0_0_1_14_1_1 + 1.29523809523809*G0_0_1_15_1_0 + 1.2952380952381*G0_0_1_15_1_1 - 5.33333333333331*G0_0_1_16_1_0 - 3.50476190476189*G0_0_1_16_1_1 - 1.29523809523808*G0_0_1_17_1_0 - 1.29523809523808*G0_0_1_17_1_1 + 3.50476190476188*G0_0_1_18_1_0 + 5.3333333333333*G0_0_1_18_1_1 + 1.82857142857141*G0_0_1_19_1_0 - 1.82857142857143*G0_0_1_19_1_1 - 2.23999999999998*G0_1_0_1_0_0 + 2.24*G0_1_0_2_0_1 - 4.57142857142855*G0_1_0_3_0_0 - 6.81142857142853*G0_1_0_3_0_1 + 6.81142857142856*G0_1_0_4_0_0 + 4.57142857142855*G0_1_0_4_0_1 - 0.091428571428569*G0_1_0_5_0_0 - 0.0914285714285811*G0_1_0_5_0_1 - 6.81142857142856*G0_1_0_6_0_0 - 2.14857142857142*G0_1_0_6_0_1 + 0.0914285714285688*G0_1_0_7_0_0 + 0.0914285714285821*G0_1_0_7_0_1 + 2.14857142857141*G0_1_0_8_0_0 + 6.81142857142854*G0_1_0_8_0_1 + 4.66285714285712*G0_1_0_9_0_0 - 4.66285714285714*G0_1_0_9_0_1 - 2.23999999999998*G0_1_0_11_1_0 + 2.24*G0_1_0_12_1_1 - 4.57142857142855*G0_1_0_13_1_0 - 6.81142857142853*G0_1_0_13_1_1 + 6.81142857142856*G0_1_0_14_1_0 + 4.57142857142855*G0_1_0_14_1_1 - 0.091428571428569*G0_1_0_15_1_0 - 0.0914285714285811*G0_1_0_15_1_1 - 6.81142857142856*G0_1_0_16_1_0 - 2.14857142857142*G0_1_0_16_1_1 + 0.0914285714285688*G0_1_0_17_1_0 + 0.0914285714285821*G0_1_0_17_1_1 + 2.14857142857141*G0_1_0_18_1_0 + 6.81142857142854*G0_1_0_18_1_1 + 4.66285714285712*G0_1_0_19_1_0 - 4.66285714285714*G0_1_0_19_1_1 + 0.396190476190475*G0_1_1_0_0_0 + 0.396190476190476*G0_1_1_0_0_1 - 2.55999999999998*G0_1_1_1_0_0 + 0.761904761904759*G0_1_1_2_0_1 - 3.55047619047617*G0_1_1_3_0_0 - 7.58857142857139*G0_1_1_3_0_1 + 4.49523809523808*G0_1_1_4_0_0 + 5.21142857142855*G0_1_1_4_0_1 + 3.4590476190476*G0_1_1_5_0_0 + 0.243809523809519*G0_1_1_5_0_1 - 4.49523809523808*G0_1_1_6_0_0 - 1.40190476190475*G0_1_1_6_0_1 + 2.36190476190475*G0_1_1_7_0_0 + 5.57714285714284*G0_1_1_7_0_1 - 0.198095238095247*G0_1_1_8_0_0 + 7.58857142857139*G0_1_1_8_0_1 + 0.0914285714285672*G0_1_1_9_0_0 - 10.7885714285714*G0_1_1_9_0_1 + 0.396190476190475*G0_1_1_10_1_0 + 0.396190476190476*G0_1_1_10_1_1 - 2.55999999999998*G0_1_1_11_1_0 + 0.761904761904759*G0_1_1_12_1_1 - 3.55047619047617*G0_1_1_13_1_0 - 7.58857142857139*G0_1_1_13_1_1 + 4.49523809523808*G0_1_1_14_1_0 + 5.21142857142855*G0_1_1_14_1_1 + 3.4590476190476*G0_1_1_15_1_0 + 0.243809523809519*G0_1_1_15_1_1 - 4.49523809523808*G0_1_1_16_1_0 - 1.40190476190475*G0_1_1_16_1_1 + 2.36190476190475*G0_1_1_17_1_0 + 5.57714285714284*G0_1_1_17_1_1 - 0.198095238095247*G0_1_1_18_1_0 + 7.58857142857139*G0_1_1_18_1_1 + 0.0914285714285672*G0_1_1_19_1_0 - 10.7885714285714*G0_1_1_19_1_1; + A[64] = A[67] + 0.450793650793649*G0_1_0_0_0_0 + 0.450793650793649*G0_1_0_0_0_1 - 0.45079365079365*G0_1_0_1_0_0 - 2.95555555555554*G0_1_0_2_0_1 + 2.10476190476189*G0_1_0_3_0_0 + 0.138095238095233*G0_1_0_3_0_1 - 5.40952380952377*G0_1_0_4_0_0 - 0.938095238095233*G0_1_0_4_0_1 - 2.10476190476189*G0_1_0_5_0_0 - 1.96666666666665*G0_1_0_5_0_1 + 5.40952380952377*G0_1_0_6_0_0 + 4.47142857142854*G0_1_0_6_0_1 - 0.138095238095238*G0_1_0_7_0_1 - 0.138095238095234*G0_1_0_8_0_1 + 1.07619047619047*G0_1_0_9_0_1 + 0.450793650793649*G0_1_0_10_1_0 + 0.450793650793649*G0_1_0_10_1_1 - 0.45079365079365*G0_1_0_11_1_0 - 2.95555555555554*G0_1_0_12_1_1 + 2.10476190476189*G0_1_0_13_1_0 + 0.138095238095233*G0_1_0_13_1_1 - 5.40952380952377*G0_1_0_14_1_0 - 0.938095238095233*G0_1_0_14_1_1 - 2.10476190476189*G0_1_0_15_1_0 - 1.96666666666665*G0_1_0_15_1_1 + 5.40952380952377*G0_1_0_16_1_0 + 4.47142857142854*G0_1_0_16_1_1 - 0.138095238095238*G0_1_0_17_1_1 - 0.138095238095234*G0_1_0_18_1_1 + 1.07619047619047*G0_1_0_19_1_1 + 0.592063492063489*G0_1_1_0_0_0 + 0.592063492063489*G0_1_1_0_0_1 + 0.141269841269842*G0_1_1_1_0_0 - 1.47777777777777*G0_1_1_2_0_1 + 0.914285714285708*G0_1_1_3_0_0 + 0.733333333333331*G0_1_1_3_0_1 - 2.70476190476189*G0_1_1_4_0_0 - 0.9047619047619*G0_1_1_4_0_1 - 1.19047619047618*G0_1_1_5_0_0 - 1.78571428571427*G0_1_1_5_0_1 + 2.70476190476189*G0_1_1_6_0_0 + 2.67142857142855*G0_1_1_6_0_1 - 0.366666666666664*G0_1_1_7_0_0 + 0.228571428571429*G0_1_1_7_0_1 - 0.366666666666666*G0_1_1_8_0_0 - 0.733333333333331*G0_1_1_8_0_1 + 0.276190476190474*G0_1_1_9_0_0 + 0.676190476190472*G0_1_1_9_0_1 + 0.592063492063489*G0_1_1_10_1_0 + 0.592063492063489*G0_1_1_10_1_1 + 0.141269841269842*G0_1_1_11_1_0 - 1.47777777777777*G0_1_1_12_1_1 + 0.914285714285708*G0_1_1_13_1_0 + 0.733333333333331*G0_1_1_13_1_1 - 2.70476190476189*G0_1_1_14_1_0 - 0.9047619047619*G0_1_1_14_1_1 - 1.19047619047618*G0_1_1_15_1_0 - 1.78571428571427*G0_1_1_15_1_1 + 2.70476190476189*G0_1_1_16_1_0 + 2.67142857142855*G0_1_1_16_1_1 - 0.366666666666664*G0_1_1_17_1_0 + 0.228571428571429*G0_1_1_17_1_1 - 0.366666666666666*G0_1_1_18_1_0 - 0.733333333333331*G0_1_1_18_1_1 + 0.276190476190474*G0_1_1_19_1_0 + 0.676190476190472*G0_1_1_19_1_1; + A[159] = A[624]; + A[898] = A[869] - 0.975238095238091*G0_0_1_0_0_0 - 0.975238095238091*G0_0_1_0_0_1 + 0.975238095238089*G0_0_1_1_0_0 + 0.975238095238085*G0_0_1_2_0_1 + 0.853333333333341*G0_0_1_3_0_0 + 1.5847619047619*G0_0_1_3_0_1 + 1.58476190476189*G0_0_1_4_0_0 + 0.853333333333339*G0_0_1_4_0_1 + 2.80380952380952*G0_0_1_5_0_0 + 2.55999999999999*G0_0_1_5_0_1 - 1.58476190476189*G0_0_1_6_0_0 - 2.55999999999998*G0_0_1_6_0_1 + 2.56*G0_0_1_7_0_0 + 2.80380952380952*G0_0_1_7_0_1 - 2.55999999999999*G0_0_1_8_0_0 - 1.5847619047619*G0_0_1_8_0_1 - 3.65714285714286*G0_0_1_9_0_0 - 3.65714285714286*G0_0_1_9_0_1 - 0.975238095238091*G0_0_1_10_1_0 - 0.975238095238091*G0_0_1_10_1_1 + 0.975238095238089*G0_0_1_11_1_0 + 0.975238095238085*G0_0_1_12_1_1 + 0.853333333333341*G0_0_1_13_1_0 + 1.5847619047619*G0_0_1_13_1_1 + 1.58476190476189*G0_0_1_14_1_0 + 0.853333333333339*G0_0_1_14_1_1 + 2.80380952380952*G0_0_1_15_1_0 + 2.55999999999999*G0_0_1_15_1_1 - 1.58476190476189*G0_0_1_16_1_0 - 2.55999999999998*G0_0_1_16_1_1 + 2.56*G0_0_1_17_1_0 + 2.80380952380952*G0_0_1_17_1_1 - 2.55999999999999*G0_0_1_18_1_0 - 1.5847619047619*G0_0_1_18_1_1 - 3.65714285714286*G0_0_1_19_1_0 - 3.65714285714286*G0_0_1_19_1_1 + 0.975238095238092*G0_1_0_0_0_0 + 0.975238095238092*G0_1_0_0_0_1 - 0.975238095238089*G0_1_0_1_0_0 - 0.975238095238085*G0_1_0_2_0_1 - 0.853333333333342*G0_1_0_3_0_0 - 1.5847619047619*G0_1_0_3_0_1 - 1.58476190476189*G0_1_0_4_0_0 - 0.853333333333341*G0_1_0_4_0_1 - 2.80380952380952*G0_1_0_5_0_0 - 2.55999999999999*G0_1_0_5_0_1 + 1.58476190476189*G0_1_0_6_0_0 + 2.55999999999998*G0_1_0_6_0_1 - 2.56*G0_1_0_7_0_0 - 2.80380952380952*G0_1_0_7_0_1 + 2.55999999999999*G0_1_0_8_0_0 + 1.5847619047619*G0_1_0_8_0_1 + 3.65714285714286*G0_1_0_9_0_0 + 3.65714285714286*G0_1_0_9_0_1 + 0.975238095238092*G0_1_0_10_1_0 + 0.975238095238092*G0_1_0_10_1_1 - 0.975238095238089*G0_1_0_11_1_0 - 0.975238095238085*G0_1_0_12_1_1 - 0.853333333333342*G0_1_0_13_1_0 - 1.5847619047619*G0_1_0_13_1_1 - 1.58476190476189*G0_1_0_14_1_0 - 0.853333333333341*G0_1_0_14_1_1 - 2.80380952380952*G0_1_0_15_1_0 - 2.55999999999999*G0_1_0_15_1_1 + 1.58476190476189*G0_1_0_16_1_0 + 2.55999999999998*G0_1_0_16_1_1 - 2.56*G0_1_0_17_1_0 - 2.80380952380952*G0_1_0_17_1_1 + 2.55999999999999*G0_1_0_18_1_0 + 1.5847619047619*G0_1_0_18_1_1 + 3.65714285714286*G0_1_0_19_1_0 + 3.65714285714286*G0_1_0_19_1_1; + A[897] = A[898] + 1.95047619047618*G0_0_0_0_0_0 + 1.95047619047618*G0_0_0_0_0_1 + 1.95047619047618*G0_0_0_1_0_0 - 8.77714285714282*G0_0_0_3_0_0 - 0.487619047619043*G0_0_0_3_0_1 - 6.33904761904759*G0_0_0_4_0_1 - 8.77714285714283*G0_0_0_5_0_0 - 8.28952380952378*G0_0_0_5_0_1 + 6.3390476190476*G0_0_0_6_0_1 - 1.95047619047618*G0_0_0_7_0_0 - 2.43809523809522*G0_0_0_7_0_1 - 1.95047619047619*G0_0_0_8_0_0 + 0.487619047619043*G0_0_0_8_0_1 + 17.5542857142856*G0_0_0_9_0_0 + 8.77714285714281*G0_0_0_9_0_1 + 1.95047619047618*G0_0_0_10_1_0 + 1.95047619047618*G0_0_0_10_1_1 + 1.95047619047618*G0_0_0_11_1_0 - 8.77714285714282*G0_0_0_13_1_0 - 0.487619047619043*G0_0_0_13_1_1 - 6.33904761904759*G0_0_0_14_1_1 - 8.77714285714283*G0_0_0_15_1_0 - 8.28952380952378*G0_0_0_15_1_1 + 6.3390476190476*G0_0_0_16_1_1 - 1.95047619047618*G0_0_0_17_1_0 - 2.43809523809522*G0_0_0_17_1_1 - 1.95047619047619*G0_0_0_18_1_0 + 0.487619047619043*G0_0_0_18_1_1 + 17.5542857142856*G0_0_0_19_1_0 + 8.77714285714281*G0_0_0_19_1_1 + 1.66603174603174*G0_0_1_0_0_0 + 1.66603174603174*G0_0_1_0_0_1 + 0.284444444444445*G0_0_1_1_0_0 - 1.05650793650794*G0_0_1_2_0_1 - 6.58285714285711*G0_0_1_3_0_0 - 1.34095238095237*G0_0_1_3_0_1 - 5.11999999999999*G0_0_1_4_0_0 - 9.02095238095234*G0_0_1_4_0_1 - 2.19428571428571*G0_0_1_5_0_0 - 3.04761904761904*G0_0_1_5_0_1 + 5.11999999999999*G0_0_1_6_0_0 + 2.43809523809524*G0_0_1_6_0_1 - 2.80380952380951*G0_0_1_7_0_0 - 1.95047619047617*G0_0_1_7_0_1 + 0.853333333333326*G0_0_1_8_0_0 + 1.34095238095237*G0_0_1_8_0_1 + 8.77714285714282*G0_0_1_9_0_0 + 10.9714285714285*G0_0_1_9_0_1 + 1.66603174603174*G0_0_1_10_1_0 + 1.66603174603174*G0_0_1_10_1_1 + 0.284444444444445*G0_0_1_11_1_0 - 1.05650793650794*G0_0_1_12_1_1 - 6.58285714285711*G0_0_1_13_1_0 - 1.34095238095237*G0_0_1_13_1_1 - 5.11999999999999*G0_0_1_14_1_0 - 9.02095238095234*G0_0_1_14_1_1 - 2.19428571428571*G0_0_1_15_1_0 - 3.04761904761904*G0_0_1_15_1_1 + 5.11999999999999*G0_0_1_16_1_0 + 2.43809523809524*G0_0_1_16_1_1 - 2.80380952380951*G0_0_1_17_1_0 - 1.95047619047617*G0_0_1_17_1_1 + 0.853333333333326*G0_0_1_18_1_0 + 1.34095238095237*G0_0_1_18_1_1 + 8.77714285714282*G0_0_1_19_1_0 + 10.9714285714285*G0_0_1_19_1_1 - 0.284444444444446*G0_1_0_0_0_0 - 0.284444444444445*G0_1_0_0_0_1 + 2.23492063492062*G0_1_0_1_0_0 + 0.893968253968243*G0_1_0_2_0_1 - 8.53333333333328*G0_1_0_3_0_0 - 1.9504761904762*G0_1_0_4_0_0 - 9.14285714285709*G0_1_0_4_0_1 - 0.24380952380952*G0_1_0_5_0_0 + 0.243809523809525*G0_1_0_5_0_1 + 1.95047619047619*G0_1_0_6_0_0 - 0.853333333333324*G0_1_0_6_0_1 + 2.31619047619048*G0_1_0_7_0_0 + 1.82857142857143*G0_1_0_7_0_1 - 4.26666666666665*G0_1_0_8_0_0 + 8.7771428571428*G0_1_0_9_0_0 + 7.31428571428566*G0_1_0_9_0_1 - 0.284444444444446*G0_1_0_10_1_0 - 0.284444444444445*G0_1_0_10_1_1 + 2.23492063492062*G0_1_0_11_1_0 + 0.893968253968243*G0_1_0_12_1_1 - 8.53333333333328*G0_1_0_13_1_0 - 1.9504761904762*G0_1_0_14_1_0 - 9.14285714285709*G0_1_0_14_1_1 - 0.24380952380952*G0_1_0_15_1_0 + 0.243809523809525*G0_1_0_15_1_1 + 1.95047619047619*G0_1_0_16_1_0 - 0.853333333333324*G0_1_0_16_1_1 + 2.31619047619048*G0_1_0_17_1_0 + 1.82857142857143*G0_1_0_17_1_1 - 4.26666666666665*G0_1_0_18_1_0 + 8.7771428571428*G0_1_0_19_1_0 + 7.31428571428566*G0_1_0_19_1_1 + 2.03174603174602*G0_1_1_0_0_0 + 2.03174603174602*G0_1_1_0_0_1 + 2.60063492063491*G0_1_1_1_0_0 - 0.0812698412698487*G0_1_1_2_0_1 - 7.19238095238091*G0_1_1_3_0_0 + 2.19428571428571*G0_1_1_3_0_1 - 3.5352380952381*G0_1_1_4_0_0 - 10.24*G0_1_1_4_0_1 - 0.853333333333328*G0_1_1_5_0_0 - 3.90095238095236*G0_1_1_5_0_1 + 3.53523809523809*G0_1_1_6_0_0 + 1.95047619047619*G0_1_1_6_0_1 - 1.58476190476189*G0_1_1_7_0_0 + 1.46285714285715*G0_1_1_7_0_1 - 3.04761904761904*G0_1_1_8_0_0 - 2.19428571428571*G0_1_1_8_0_1 + 8.04571428571423*G0_1_1_9_0_0 + 8.7771428571428*G0_1_1_9_0_1 + 2.03174603174602*G0_1_1_10_1_0 + 2.03174603174602*G0_1_1_10_1_1 + 2.60063492063491*G0_1_1_11_1_0 - 0.0812698412698487*G0_1_1_12_1_1 - 7.19238095238091*G0_1_1_13_1_0 + 2.19428571428571*G0_1_1_13_1_1 - 3.5352380952381*G0_1_1_14_1_0 - 10.24*G0_1_1_14_1_1 - 0.853333333333328*G0_1_1_15_1_0 - 3.90095238095236*G0_1_1_15_1_1 + 3.53523809523809*G0_1_1_16_1_0 + 1.95047619047619*G0_1_1_16_1_1 - 1.58476190476189*G0_1_1_17_1_0 + 1.46285714285715*G0_1_1_17_1_1 - 3.04761904761904*G0_1_1_18_1_0 - 2.19428571428571*G0_1_1_18_1_1 + 8.04571428571423*G0_1_1_19_1_0 + 8.7771428571428*G0_1_1_19_1_1; + A[373] = A[898] + 2.03174603174602*G0_0_0_0_0_0 + 2.03174603174602*G0_0_0_0_0_1 - 0.0812698412698398*G0_0_0_1_0_0 + 2.60063492063491*G0_0_0_2_0_1 - 10.2399999999999*G0_0_0_3_0_0 - 3.53523809523808*G0_0_0_3_0_1 + 2.1942857142857*G0_0_0_4_0_0 - 7.19238095238091*G0_0_0_4_0_1 + 1.46285714285714*G0_0_0_5_0_0 - 1.58476190476189*G0_0_0_5_0_1 - 2.19428571428571*G0_0_0_6_0_0 - 3.04761904761904*G0_0_0_6_0_1 - 3.90095238095235*G0_0_0_7_0_0 - 0.853333333333318*G0_0_0_7_0_1 + 1.95047619047617*G0_0_0_8_0_0 + 3.53523809523807*G0_0_0_8_0_1 + 8.7771428571428*G0_0_0_9_0_0 + 8.04571428571423*G0_0_0_9_0_1 + 2.03174603174602*G0_0_0_10_1_0 + 2.03174603174602*G0_0_0_10_1_1 - 0.0812698412698398*G0_0_0_11_1_0 + 2.60063492063491*G0_0_0_12_1_1 - 10.2399999999999*G0_0_0_13_1_0 - 3.53523809523808*G0_0_0_13_1_1 + 2.1942857142857*G0_0_0_14_1_0 - 7.19238095238091*G0_0_0_14_1_1 + 1.46285714285714*G0_0_0_15_1_0 - 1.58476190476189*G0_0_0_15_1_1 - 2.19428571428571*G0_0_0_16_1_0 - 3.04761904761904*G0_0_0_16_1_1 - 3.90095238095235*G0_0_0_17_1_0 - 0.853333333333318*G0_0_0_17_1_1 + 1.95047619047617*G0_0_0_18_1_0 + 3.53523809523807*G0_0_0_18_1_1 + 8.7771428571428*G0_0_0_19_1_0 + 8.04571428571423*G0_0_0_19_1_1 + 1.66603174603173*G0_0_1_0_0_0 + 1.66603174603173*G0_0_1_0_0_1 - 1.05650793650793*G0_0_1_1_0_0 + 0.284444444444447*G0_0_1_2_0_1 - 9.02095238095233*G0_0_1_3_0_0 - 5.11999999999997*G0_0_1_3_0_1 - 1.34095238095237*G0_0_1_4_0_0 - 6.58285714285711*G0_0_1_4_0_1 - 1.95047619047618*G0_0_1_5_0_0 - 2.8038095238095*G0_0_1_5_0_1 + 1.34095238095237*G0_0_1_6_0_0 + 0.853333333333322*G0_0_1_6_0_1 - 3.04761904761902*G0_0_1_7_0_0 - 2.1942857142857*G0_0_1_7_0_1 + 2.43809523809522*G0_0_1_8_0_0 + 5.11999999999997*G0_0_1_8_0_1 + 10.9714285714285*G0_0_1_9_0_0 + 8.77714285714281*G0_0_1_9_0_1 + 1.66603174603173*G0_0_1_10_1_0 + 1.66603174603173*G0_0_1_10_1_1 - 1.05650793650793*G0_0_1_11_1_0 + 0.284444444444447*G0_0_1_12_1_1 - 9.02095238095233*G0_0_1_13_1_0 - 5.11999999999997*G0_0_1_13_1_1 - 1.34095238095237*G0_0_1_14_1_0 - 6.58285714285711*G0_0_1_14_1_1 - 1.95047619047618*G0_0_1_15_1_0 - 2.8038095238095*G0_0_1_15_1_1 + 1.34095238095237*G0_0_1_16_1_0 + 0.853333333333322*G0_0_1_16_1_1 - 3.04761904761902*G0_0_1_17_1_0 - 2.1942857142857*G0_0_1_17_1_1 + 2.43809523809522*G0_0_1_18_1_0 + 5.11999999999997*G0_0_1_18_1_1 + 10.9714285714285*G0_0_1_19_1_0 + 8.77714285714281*G0_0_1_19_1_1 - 0.284444444444445*G0_1_0_0_0_0 - 0.284444444444445*G0_1_0_0_0_1 + 0.89396825396825*G0_1_0_1_0_0 + 2.23492063492062*G0_1_0_2_0_1 - 9.14285714285709*G0_1_0_3_0_0 - 1.95047619047618*G0_1_0_3_0_1 - 8.53333333333329*G0_1_0_4_0_1 + 1.82857142857143*G0_1_0_5_0_0 + 2.31619047619047*G0_1_0_5_0_1 - 4.26666666666664*G0_1_0_6_0_1 + 0.243809523809536*G0_1_0_7_0_0 - 0.243809523809504*G0_1_0_7_0_1 - 0.853333333333339*G0_1_0_8_0_0 + 1.95047619047618*G0_1_0_8_0_1 + 7.31428571428566*G0_1_0_9_0_0 + 8.77714285714279*G0_1_0_9_0_1 - 0.284444444444445*G0_1_0_10_1_0 - 0.284444444444445*G0_1_0_10_1_1 + 0.89396825396825*G0_1_0_11_1_0 + 2.23492063492062*G0_1_0_12_1_1 - 9.14285714285709*G0_1_0_13_1_0 - 1.95047619047618*G0_1_0_13_1_1 - 8.53333333333329*G0_1_0_14_1_1 + 1.82857142857143*G0_1_0_15_1_0 + 2.31619047619047*G0_1_0_15_1_1 - 4.26666666666664*G0_1_0_16_1_1 + 0.243809523809536*G0_1_0_17_1_0 - 0.243809523809504*G0_1_0_17_1_1 - 0.853333333333339*G0_1_0_18_1_0 + 1.95047619047618*G0_1_0_18_1_1 + 7.31428571428566*G0_1_0_19_1_0 + 8.77714285714279*G0_1_0_19_1_1 + 1.95047619047618*G0_1_1_0_0_0 + 1.95047619047618*G0_1_1_0_0_1 + 1.95047619047618*G0_1_1_2_0_1 - 6.33904761904758*G0_1_1_3_0_0 - 0.487619047619059*G0_1_1_4_0_0 - 8.77714285714282*G0_1_1_4_0_1 - 2.43809523809522*G0_1_1_5_0_0 - 1.95047619047618*G0_1_1_5_0_1 + 0.487619047619057*G0_1_1_6_0_0 - 1.95047619047618*G0_1_1_6_0_1 - 8.28952380952376*G0_1_1_7_0_0 - 8.77714285714281*G0_1_1_7_0_1 + 6.33904761904758*G0_1_1_8_0_0 + 8.7771428571428*G0_1_1_9_0_0 + 17.5542857142856*G0_1_1_9_0_1 + 1.95047619047618*G0_1_1_10_1_0 + 1.95047619047618*G0_1_1_10_1_1 + 1.95047619047618*G0_1_1_12_1_1 - 6.33904761904758*G0_1_1_13_1_0 - 0.487619047619059*G0_1_1_14_1_0 - 8.77714285714282*G0_1_1_14_1_1 - 2.43809523809522*G0_1_1_15_1_0 - 1.95047619047618*G0_1_1_15_1_1 + 0.487619047619057*G0_1_1_16_1_0 - 1.95047619047618*G0_1_1_16_1_1 - 8.28952380952376*G0_1_1_17_1_0 - 8.77714285714281*G0_1_1_17_1_1 + 6.33904761904758*G0_1_1_18_1_0 + 8.7771428571428*G0_1_1_19_1_0 + 17.5542857142856*G0_1_1_19_1_1; + A[432] = A[897]; + A[838] = A[373]; + A[402] = A[373] - 0.975238095238087*G0_0_1_0_0_0 - 0.975238095238087*G0_0_1_0_0_1 + 0.975238095238089*G0_0_1_1_0_0 + 0.975238095238088*G0_0_1_2_0_1 - 0.975238095238093*G0_0_1_3_0_0 + 1.58476190476189*G0_0_1_3_0_1 - 0.243809523809525*G0_0_1_4_0_0 - 2.80380952380951*G0_0_1_4_0_1 + 0.975238095238089*G0_0_1_5_0_0 + 2.55999999999998*G0_0_1_5_0_1 + 0.243809523809525*G0_0_1_6_0_0 - 2.55999999999998*G0_0_1_6_0_1 + 0.731428571428564*G0_0_1_7_0_0 - 0.853333333333328*G0_0_1_7_0_1 - 0.731428571428566*G0_0_1_8_0_0 - 1.58476190476189*G0_0_1_8_0_1 + 3.65714285714284*G0_0_1_9_0_1 - 0.975238095238087*G0_0_1_10_1_0 - 0.975238095238087*G0_0_1_10_1_1 + 0.975238095238089*G0_0_1_11_1_0 + 0.975238095238088*G0_0_1_12_1_1 - 0.975238095238093*G0_0_1_13_1_0 + 1.58476190476189*G0_0_1_13_1_1 - 0.243809523809525*G0_0_1_14_1_0 - 2.80380952380951*G0_0_1_14_1_1 + 0.975238095238089*G0_0_1_15_1_0 + 2.55999999999998*G0_0_1_15_1_1 + 0.243809523809525*G0_0_1_16_1_0 - 2.55999999999998*G0_0_1_16_1_1 + 0.731428571428564*G0_0_1_17_1_0 - 0.853333333333328*G0_0_1_17_1_1 - 0.731428571428566*G0_0_1_18_1_0 - 1.58476190476189*G0_0_1_18_1_1 + 3.65714285714284*G0_0_1_19_1_1 + 0.975238095238087*G0_1_0_0_0_0 + 0.975238095238087*G0_1_0_0_0_1 - 0.975238095238089*G0_1_0_1_0_0 - 0.975238095238088*G0_1_0_2_0_1 + 0.975238095238093*G0_1_0_3_0_0 - 1.58476190476189*G0_1_0_3_0_1 + 0.243809523809525*G0_1_0_4_0_0 + 2.80380952380951*G0_1_0_4_0_1 - 0.975238095238089*G0_1_0_5_0_0 - 2.55999999999998*G0_1_0_5_0_1 - 0.243809523809525*G0_1_0_6_0_0 + 2.55999999999998*G0_1_0_6_0_1 - 0.731428571428564*G0_1_0_7_0_0 + 0.853333333333328*G0_1_0_7_0_1 + 0.731428571428566*G0_1_0_8_0_0 + 1.58476190476189*G0_1_0_8_0_1 - 3.65714285714284*G0_1_0_9_0_1 + 0.975238095238087*G0_1_0_10_1_0 + 0.975238095238087*G0_1_0_10_1_1 - 0.975238095238089*G0_1_0_11_1_0 - 0.975238095238088*G0_1_0_12_1_1 + 0.975238095238093*G0_1_0_13_1_0 - 1.58476190476189*G0_1_0_13_1_1 + 0.243809523809525*G0_1_0_14_1_0 + 2.80380952380951*G0_1_0_14_1_1 - 0.975238095238089*G0_1_0_15_1_0 - 2.55999999999998*G0_1_0_15_1_1 - 0.243809523809525*G0_1_0_16_1_0 + 2.55999999999998*G0_1_0_16_1_1 - 0.731428571428564*G0_1_0_17_1_0 + 0.853333333333328*G0_1_0_17_1_1 + 0.731428571428566*G0_1_0_18_1_0 + 1.58476190476189*G0_1_0_18_1_1 - 3.65714285714284*G0_1_0_19_1_1; + A[115] = 0.0; + A[138] = 0.0; + A[596] = A[131]; + A[217] = A[775] + 2.92698412698412*G0_0_0_0_0_0 + 2.92698412698412*G0_0_0_0_0_1 - 2.31746031746031*G0_0_0_1_0_0 + 2.33777777777777*G0_0_0_2_0_1 - 5.13142857142855*G0_0_0_3_0_0 - 6.59047619047616*G0_0_0_3_0_1 + 8.44571428571425*G0_0_0_4_0_0 + 5.24952380952379*G0_0_0_4_0_1 + 0.559999999999987*G0_0_0_5_0_0 - 4.96380952380951*G0_0_0_5_0_1 - 8.44571428571425*G0_0_0_6_0_0 - 0.300952380952371*G0_0_0_6_0_1 - 3.89333333333331*G0_0_0_7_0_0 + 1.63047619047618*G0_0_0_7_0_1 + 3.2838095238095*G0_0_0_8_0_0 + 6.59047619047616*G0_0_0_8_0_1 + 4.57142857142856*G0_0_0_9_0_0 - 6.87999999999998*G0_0_0_9_0_1 + 2.92698412698412*G0_0_0_10_1_0 + 2.92698412698412*G0_0_0_10_1_1 - 2.31746031746031*G0_0_0_11_1_0 + 2.33777777777777*G0_0_0_12_1_1 - 5.13142857142855*G0_0_0_13_1_0 - 6.59047619047616*G0_0_0_13_1_1 + 8.44571428571425*G0_0_0_14_1_0 + 5.24952380952379*G0_0_0_14_1_1 + 0.559999999999987*G0_0_0_15_1_0 - 4.96380952380951*G0_0_0_15_1_1 - 8.44571428571425*G0_0_0_16_1_0 - 0.300952380952371*G0_0_0_16_1_1 - 3.89333333333331*G0_0_0_17_1_0 + 1.63047619047618*G0_0_0_17_1_1 + 3.2838095238095*G0_0_0_18_1_0 + 6.59047619047616*G0_0_0_18_1_1 + 4.57142857142856*G0_0_0_19_1_0 - 6.87999999999998*G0_0_0_19_1_1 - 2.63238095238094*G0_0_1_1_0_0 + 2.63238095238094*G0_0_1_2_0_1 - 4.35238095238093*G0_0_1_3_0_0 - 6.98476190476187*G0_0_1_3_0_1 + 6.98476190476188*G0_0_1_4_0_0 + 4.35238095238094*G0_0_1_4_0_1 + 0.912380952380943*G0_0_1_5_0_0 + 0.912380952380939*G0_0_1_5_0_1 - 6.98476190476188*G0_0_1_6_0_0 - 3.54476190476188*G0_0_1_6_0_1 - 0.912380952380947*G0_0_1_7_0_0 - 0.912380952380941*G0_0_1_7_0_1 + 3.54476190476188*G0_0_1_8_0_0 + 6.98476190476187*G0_0_1_8_0_1 + 3.43999999999999*G0_0_1_9_0_0 - 3.44*G0_0_1_9_0_1 - 2.63238095238094*G0_0_1_11_1_0 + 2.63238095238094*G0_0_1_12_1_1 - 4.35238095238093*G0_0_1_13_1_0 - 6.98476190476187*G0_0_1_13_1_1 + 6.98476190476188*G0_0_1_14_1_0 + 4.35238095238094*G0_0_1_14_1_1 + 0.912380952380943*G0_0_1_15_1_0 + 0.912380952380939*G0_0_1_15_1_1 - 6.98476190476188*G0_0_1_16_1_0 - 3.54476190476188*G0_0_1_16_1_1 - 0.912380952380947*G0_0_1_17_1_0 - 0.912380952380941*G0_0_1_17_1_1 + 3.54476190476188*G0_0_1_18_1_0 + 6.98476190476187*G0_0_1_18_1_1 + 3.43999999999999*G0_0_1_19_1_0 - 3.44*G0_0_1_19_1_1 - 2.63238095238094*G0_1_0_1_0_0 + 2.63238095238094*G0_1_0_2_0_1 - 4.35238095238093*G0_1_0_3_0_0 - 6.98476190476187*G0_1_0_3_0_1 + 6.98476190476188*G0_1_0_4_0_0 + 4.35238095238094*G0_1_0_4_0_1 + 0.912380952380943*G0_1_0_5_0_0 + 0.912380952380939*G0_1_0_5_0_1 - 6.98476190476188*G0_1_0_6_0_0 - 3.54476190476188*G0_1_0_6_0_1 - 0.912380952380948*G0_1_0_7_0_0 - 0.912380952380941*G0_1_0_7_0_1 + 3.54476190476188*G0_1_0_8_0_0 + 6.98476190476187*G0_1_0_8_0_1 + 3.43999999999999*G0_1_0_9_0_0 - 3.44*G0_1_0_9_0_1 - 2.63238095238094*G0_1_0_11_1_0 + 2.63238095238094*G0_1_0_12_1_1 - 4.35238095238093*G0_1_0_13_1_0 - 6.98476190476187*G0_1_0_13_1_1 + 6.98476190476188*G0_1_0_14_1_0 + 4.35238095238094*G0_1_0_14_1_1 + 0.912380952380943*G0_1_0_15_1_0 + 0.912380952380939*G0_1_0_15_1_1 - 6.98476190476188*G0_1_0_16_1_0 - 3.54476190476188*G0_1_0_16_1_1 - 0.912380952380948*G0_1_0_17_1_0 - 0.912380952380941*G0_1_0_17_1_1 + 3.54476190476188*G0_1_0_18_1_0 + 6.98476190476187*G0_1_0_18_1_1 + 3.43999999999999*G0_1_0_19_1_0 - 3.44*G0_1_0_19_1_1 - 2.92698412698411*G0_1_1_0_0_0 - 2.92698412698411*G0_1_1_0_0_1 - 2.33777777777776*G0_1_1_1_0_0 + 2.31746031746031*G0_1_1_2_0_1 - 5.24952380952378*G0_1_1_3_0_0 - 8.44571428571424*G0_1_1_3_0_1 + 6.59047619047616*G0_1_1_4_0_0 + 5.13142857142855*G0_1_1_4_0_1 - 1.63047619047619*G0_1_1_5_0_0 + 3.89333333333331*G0_1_1_5_0_1 - 6.59047619047616*G0_1_1_6_0_0 - 3.2838095238095*G0_1_1_6_0_1 + 4.9638095238095*G0_1_1_7_0_0 - 0.559999999999987*G0_1_1_7_0_1 + 0.300952380952367*G0_1_1_8_0_0 + 8.44571428571424*G0_1_1_8_0_1 + 6.87999999999997*G0_1_1_9_0_0 - 4.57142857142856*G0_1_1_9_0_1 - 2.92698412698411*G0_1_1_10_1_0 - 2.92698412698411*G0_1_1_10_1_1 - 2.33777777777776*G0_1_1_11_1_0 + 2.31746031746031*G0_1_1_12_1_1 - 5.24952380952378*G0_1_1_13_1_0 - 8.44571428571424*G0_1_1_13_1_1 + 6.59047619047616*G0_1_1_14_1_0 + 5.13142857142855*G0_1_1_14_1_1 - 1.63047619047619*G0_1_1_15_1_0 + 3.89333333333331*G0_1_1_15_1_1 - 6.59047619047616*G0_1_1_16_1_0 - 3.2838095238095*G0_1_1_16_1_1 + 4.9638095238095*G0_1_1_17_1_0 - 0.559999999999987*G0_1_1_17_1_1 + 0.300952380952367*G0_1_1_18_1_0 + 8.44571428571424*G0_1_1_18_1_1 + 6.87999999999997*G0_1_1_19_1_0 - 4.57142857142856*G0_1_1_19_1_1; + A[169] = 0.0; + A[629] = -A[254] + 1.11746031746031*G0_1_0_0_0_0 + 1.11746031746031*G0_1_0_0_0_1 + 1.11746031746032*G0_1_0_1_0_0 - 4.87619047619046*G0_1_0_3_0_0 - 0.203174603174598*G0_1_0_3_0_1 - 3.55555555555554*G0_1_0_4_0_1 - 4.87619047619046*G0_1_0_5_0_0 - 4.67301587301586*G0_1_0_5_0_1 + 3.55555555555554*G0_1_0_6_0_1 - 1.11746031746031*G0_1_0_7_0_0 - 1.32063492063491*G0_1_0_7_0_1 - 1.11746031746032*G0_1_0_8_0_0 + 0.203174603174599*G0_1_0_8_0_1 + 9.75238095238092*G0_1_0_9_0_0 + 4.87619047619045*G0_1_0_9_0_1 + 1.11746031746031*G0_1_0_10_1_0 + 1.11746031746031*G0_1_0_10_1_1 + 1.11746031746032*G0_1_0_11_1_0 - 4.87619047619046*G0_1_0_13_1_0 - 0.203174603174598*G0_1_0_13_1_1 - 3.55555555555554*G0_1_0_14_1_1 - 4.87619047619046*G0_1_0_15_1_0 - 4.67301587301586*G0_1_0_15_1_1 + 3.55555555555554*G0_1_0_16_1_1 - 1.11746031746031*G0_1_0_17_1_0 - 1.32063492063491*G0_1_0_17_1_1 - 1.11746031746032*G0_1_0_18_1_0 + 0.203174603174599*G0_1_0_18_1_1 + 9.75238095238092*G0_1_0_19_1_0 + 4.87619047619045*G0_1_0_19_1_1 + 0.921058201058197*G0_1_1_0_0_0 + 0.921058201058198*G0_1_1_0_0_1 + 0.196402116402115*G0_1_1_1_0_0 - 0.880423280423275*G0_1_1_2_0_1 - 3.86031746031744*G0_1_1_3_0_0 - 1.76761904761904*G0_1_1_3_0_1 - 1.72698412698412*G0_1_1_4_0_0 - 2.74285714285713*G0_1_1_4_0_1 - 1.01587301587301*G0_1_1_5_0_0 - 2.58031746031745*G0_1_1_5_0_1 + 1.72698412698412*G0_1_1_6_0_0 + 2.53968253968252*G0_1_1_6_0_1 + 0.690793650793646*G0_1_1_7_0_0 + 2.25523809523809*G0_1_1_7_0_1 - 1.80825396825396*G0_1_1_8_0_0 + 1.76761904761904*G0_1_1_8_0_1 + 4.87619047619045*G0_1_1_9_0_0 + 0.487619047619044*G0_1_1_9_0_1 + 0.921058201058197*G0_1_1_10_1_0 + 0.921058201058198*G0_1_1_10_1_1 + 0.196402116402115*G0_1_1_11_1_0 - 0.880423280423275*G0_1_1_12_1_1 - 3.86031746031744*G0_1_1_13_1_0 - 1.76761904761904*G0_1_1_13_1_1 - 1.72698412698412*G0_1_1_14_1_0 - 2.74285714285713*G0_1_1_14_1_1 - 1.01587301587301*G0_1_1_15_1_0 - 2.58031746031745*G0_1_1_15_1_1 + 1.72698412698412*G0_1_1_16_1_0 + 2.53968253968252*G0_1_1_16_1_1 + 0.690793650793646*G0_1_1_17_1_0 + 2.25523809523809*G0_1_1_17_1_1 - 1.80825396825396*G0_1_1_18_1_0 + 1.76761904761904*G0_1_1_18_1_1 + 4.87619047619045*G0_1_1_19_1_0 + 0.487619047619044*G0_1_1_19_1_1; + A[501] = A[36]; + A[204] = 0.0; + A[646] = A[181]; + A[570] = 0.0; + A[526] = A[61]; + A[239] = 0.0; + A[563] = A[98]; + A[241] = A[706]; + A[298] = 0.0; + A[447] = 0.0; + A[327] = 0.0; + A[468] = A[555] + 0.113015873015874*G0_0_1_1_0_0 + 0.0165079365079358*G0_0_1_2_0_1 - 0.0946031746031727*G0_0_1_3_0_0 + 0.147936507936509*G0_0_1_3_0_1 - 0.0184126984126998*G0_0_1_4_0_0 - 0.164444444444444*G0_0_1_4_0_1 - 0.0615873015873014*G0_0_1_5_0_0 - 0.0615873015873014*G0_0_1_5_0_1 + 0.0184126984126997*G0_0_1_6_0_0 + 0.0450793650793658*G0_0_1_6_0_1 + 0.0615873015873025*G0_0_1_7_0_0 + 0.0615873015873024*G0_0_1_7_0_1 - 0.174603174603176*G0_0_1_8_0_0 - 0.147936507936509*G0_0_1_8_0_1 + 0.156190476190474*G0_0_1_9_0_0 + 0.102857142857142*G0_0_1_9_0_1 + 0.113015873015874*G0_0_1_11_1_0 + 0.0165079365079358*G0_0_1_12_1_1 - 0.0946031746031727*G0_0_1_13_1_0 + 0.147936507936509*G0_0_1_13_1_1 - 0.0184126984126998*G0_0_1_14_1_0 - 0.164444444444444*G0_0_1_14_1_1 - 0.0615873015873014*G0_0_1_15_1_0 - 0.0615873015873014*G0_0_1_15_1_1 + 0.0184126984126997*G0_0_1_16_1_0 + 0.0450793650793658*G0_0_1_16_1_1 + 0.0615873015873025*G0_0_1_17_1_0 + 0.0615873015873024*G0_0_1_17_1_1 - 0.174603174603176*G0_0_1_18_1_0 - 0.147936507936509*G0_0_1_18_1_1 + 0.156190476190474*G0_0_1_19_1_0 + 0.102857142857142*G0_0_1_19_1_1 - 0.113015873015874*G0_1_0_1_0_0 - 0.0165079365079358*G0_1_0_2_0_1 + 0.0946031746031727*G0_1_0_3_0_0 - 0.147936507936509*G0_1_0_3_0_1 + 0.0184126984126998*G0_1_0_4_0_0 + 0.164444444444444*G0_1_0_4_0_1 + 0.0615873015873014*G0_1_0_5_0_0 + 0.0615873015873014*G0_1_0_5_0_1 - 0.0184126984126997*G0_1_0_6_0_0 - 0.0450793650793658*G0_1_0_6_0_1 - 0.0615873015873024*G0_1_0_7_0_0 - 0.0615873015873024*G0_1_0_7_0_1 + 0.174603174603176*G0_1_0_8_0_0 + 0.147936507936509*G0_1_0_8_0_1 - 0.156190476190474*G0_1_0_9_0_0 - 0.102857142857142*G0_1_0_9_0_1 - 0.113015873015874*G0_1_0_11_1_0 - 0.0165079365079358*G0_1_0_12_1_1 + 0.0946031746031727*G0_1_0_13_1_0 - 0.147936507936509*G0_1_0_13_1_1 + 0.0184126984126998*G0_1_0_14_1_0 + 0.164444444444444*G0_1_0_14_1_1 + 0.0615873015873014*G0_1_0_15_1_0 + 0.0615873015873014*G0_1_0_15_1_1 - 0.0184126984126997*G0_1_0_16_1_0 - 0.0450793650793658*G0_1_0_16_1_1 - 0.0615873015873024*G0_1_0_17_1_0 - 0.0615873015873024*G0_1_0_17_1_1 + 0.174603174603176*G0_1_0_18_1_0 + 0.147936507936509*G0_1_0_18_1_1 - 0.156190476190474*G0_1_0_19_1_0 - 0.102857142857142*G0_1_0_19_1_1; + A[476] = -A[468] + 0.59047619047619*G0_0_0_0_0_0 + 0.59047619047619*G0_0_0_0_0_1 - 0.285714285714285*G0_0_0_1_0_0 - 0.0876190476190473*G0_0_0_2_0_1 + 0.0939682539682533*G0_0_0_3_0_0 - 0.26031746031746*G0_0_0_3_0_1 + 0.0711111111111119*G0_0_0_4_0_0 + 0.227301587301587*G0_0_0_4_0_1 + 0.325079365079364*G0_0_0_5_0_0 - 0.754285714285715*G0_0_0_5_0_1 - 0.0711111111111119*G0_0_0_6_0_0 + 0.251428571428572*G0_0_0_6_0_1 - 1.01714285714286*G0_0_0_7_0_0 + 0.0622222222222223*G0_0_0_7_0_1 + 0.712380952380951*G0_0_0_8_0_0 + 0.26031746031746*G0_0_0_8_0_1 - 0.419047619047617*G0_0_0_9_0_0 - 0.28952380952381*G0_0_0_9_0_1 + 0.59047619047619*G0_0_0_10_1_0 + 0.59047619047619*G0_0_0_10_1_1 - 0.285714285714285*G0_0_0_11_1_0 - 0.0876190476190473*G0_0_0_12_1_1 + 0.0939682539682533*G0_0_0_13_1_0 - 0.26031746031746*G0_0_0_13_1_1 + 0.0711111111111119*G0_0_0_14_1_0 + 0.227301587301587*G0_0_0_14_1_1 + 0.325079365079364*G0_0_0_15_1_0 - 0.754285714285715*G0_0_0_15_1_1 - 0.0711111111111119*G0_0_0_16_1_0 + 0.251428571428572*G0_0_0_16_1_1 - 1.01714285714286*G0_0_0_17_1_0 + 0.0622222222222223*G0_0_0_17_1_1 + 0.712380952380951*G0_0_0_18_1_0 + 0.26031746031746*G0_0_0_18_1_1 - 0.419047619047617*G0_0_0_19_1_0 - 0.28952380952381*G0_0_0_19_1_1 + 0.59047619047619*G0_1_0_0_0_0 + 0.59047619047619*G0_1_0_0_0_1 - 0.285714285714285*G0_1_0_1_0_0 - 0.0876190476190469*G0_1_0_2_0_1 + 0.0939682539682528*G0_1_0_3_0_0 - 0.26031746031746*G0_1_0_3_0_1 + 0.0711111111111124*G0_1_0_4_0_0 + 0.227301587301587*G0_1_0_4_0_1 + 0.325079365079364*G0_1_0_5_0_0 - 0.754285714285715*G0_1_0_5_0_1 - 0.0711111111111124*G0_1_0_6_0_0 + 0.251428571428572*G0_1_0_6_0_1 - 1.01714285714286*G0_1_0_7_0_0 + 0.062222222222222*G0_1_0_7_0_1 + 0.712380952380951*G0_1_0_8_0_0 + 0.26031746031746*G0_1_0_8_0_1 - 0.419047619047617*G0_1_0_9_0_0 - 0.289523809523809*G0_1_0_9_0_1 + 0.59047619047619*G0_1_0_10_1_0 + 0.59047619047619*G0_1_0_10_1_1 - 0.285714285714285*G0_1_0_11_1_0 - 0.0876190476190469*G0_1_0_12_1_1 + 0.0939682539682528*G0_1_0_13_1_0 - 0.26031746031746*G0_1_0_13_1_1 + 0.0711111111111124*G0_1_0_14_1_0 + 0.227301587301587*G0_1_0_14_1_1 + 0.325079365079364*G0_1_0_15_1_0 - 0.754285714285715*G0_1_0_15_1_1 - 0.0711111111111124*G0_1_0_16_1_0 + 0.251428571428572*G0_1_0_16_1_1 - 1.01714285714286*G0_1_0_17_1_0 + 0.062222222222222*G0_1_0_17_1_1 + 0.712380952380951*G0_1_0_18_1_0 + 0.26031746031746*G0_1_0_18_1_1 - 0.419047619047617*G0_1_0_19_1_0 - 0.289523809523809*G0_1_0_19_1_1; + A[11] = A[476]; + A[348] = 0.0; + A[29] = 0.0; + A[730] = 0.0; + A[381] = 0.0; + A[833] = A[368]; + A[54] = 0.0; + A[761] = 0.0; + A[414] = 0.0; + A[856] = A[43] - 0.101587301587301*G0_0_1_0_0_0 - 0.101587301587301*G0_0_1_0_0_1 - 0.101587301587301*G0_0_1_2_0_1 + 0.234920634920634*G0_0_1_3_0_0 - 0.0698412698412698*G0_0_1_4_0_0 + 0.266666666666664*G0_0_1_4_0_1 + 0.0317460317460318*G0_0_1_5_0_0 + 0.101587301587301*G0_0_1_5_0_1 + 0.0698412698412699*G0_0_1_6_0_0 + 0.101587301587301*G0_0_1_6_0_1 + 0.336507936507934*G0_0_1_7_0_0 + 0.266666666666665*G0_0_1_7_0_1 - 0.234920634920634*G0_0_1_8_0_0 - 0.266666666666666*G0_0_1_9_0_0 - 0.533333333333329*G0_0_1_9_0_1 - 0.101587301587301*G0_0_1_10_1_0 - 0.101587301587301*G0_0_1_10_1_1 - 0.101587301587301*G0_0_1_12_1_1 + 0.234920634920634*G0_0_1_13_1_0 - 0.0698412698412698*G0_0_1_14_1_0 + 0.266666666666664*G0_0_1_14_1_1 + 0.0317460317460318*G0_0_1_15_1_0 + 0.101587301587301*G0_0_1_15_1_1 + 0.0698412698412699*G0_0_1_16_1_0 + 0.101587301587301*G0_0_1_16_1_1 + 0.336507936507934*G0_0_1_17_1_0 + 0.266666666666665*G0_0_1_17_1_1 - 0.234920634920634*G0_0_1_18_1_0 - 0.266666666666666*G0_0_1_19_1_0 - 0.533333333333329*G0_0_1_19_1_1 + 0.101587301587301*G0_1_0_0_0_0 + 0.101587301587301*G0_1_0_0_0_1 + 0.101587301587301*G0_1_0_2_0_1 - 0.234920634920634*G0_1_0_3_0_0 + 0.0698412698412698*G0_1_0_4_0_0 - 0.266666666666664*G0_1_0_4_0_1 - 0.0317460317460318*G0_1_0_5_0_0 - 0.101587301587301*G0_1_0_5_0_1 - 0.0698412698412699*G0_1_0_6_0_0 - 0.101587301587301*G0_1_0_6_0_1 - 0.336507936507934*G0_1_0_7_0_0 - 0.266666666666665*G0_1_0_7_0_1 + 0.234920634920634*G0_1_0_8_0_0 + 0.266666666666666*G0_1_0_9_0_0 + 0.533333333333329*G0_1_0_9_0_1 + 0.101587301587301*G0_1_0_10_1_0 + 0.101587301587301*G0_1_0_10_1_1 + 0.101587301587301*G0_1_0_12_1_1 - 0.234920634920634*G0_1_0_13_1_0 + 0.0698412698412698*G0_1_0_14_1_0 - 0.266666666666664*G0_1_0_14_1_1 - 0.0317460317460318*G0_1_0_15_1_0 - 0.101587301587301*G0_1_0_15_1_1 - 0.0698412698412699*G0_1_0_16_1_0 - 0.101587301587301*G0_1_0_16_1_1 - 0.336507936507934*G0_1_0_17_1_0 - 0.266666666666665*G0_1_0_17_1_1 + 0.234920634920634*G0_1_0_18_1_0 + 0.266666666666666*G0_1_0_19_1_0 + 0.533333333333329*G0_1_0_19_1_1; + A[780] = 0.0; + A[891] = A[426]; + A[823] = 0.0; + A[145] = 0.0; + A[854] = 0.0; + A[178] = 0.0; + A[885] = A[420]; + A[492] = 0.0; + A[199] = 0.0; + A[655] = A[306] - 1.09206349206349*G0_0_1_0_0_0 - 1.09206349206349*G0_0_1_0_0_1 + 0.11174603174603*G0_0_1_1_0_0 + 0.213333333333332*G0_0_1_2_0_1 + 0.220952380952378*G0_0_1_3_0_0 - 0.0279365079365102*G0_0_1_3_0_1 - 0.0533333333333345*G0_0_1_4_0_0 + 0.0939682539682531*G0_0_1_4_0_1 + 0.647619047619043*G0_0_1_5_0_0 + 2.14603174603174*G0_0_1_5_0_1 + 0.0533333333333346*G0_0_1_6_0_0 - 1.26730158730158*G0_0_1_6_0_1 + 1.81587301587301*G0_0_1_7_0_0 + 0.317460317460315*G0_0_1_7_0_1 - 0.835555555555552*G0_0_1_8_0_0 + 0.0279365079365098*G0_0_1_8_0_1 - 0.868571428571422*G0_0_1_9_0_0 - 0.411428571428567*G0_0_1_9_0_1 - 1.09206349206349*G0_0_1_10_1_0 - 1.09206349206349*G0_0_1_10_1_1 + 0.11174603174603*G0_0_1_11_1_0 + 0.213333333333332*G0_0_1_12_1_1 + 0.220952380952378*G0_0_1_13_1_0 - 0.0279365079365102*G0_0_1_13_1_1 - 0.0533333333333345*G0_0_1_14_1_0 + 0.0939682539682531*G0_0_1_14_1_1 + 0.647619047619043*G0_0_1_15_1_0 + 2.14603174603174*G0_0_1_15_1_1 + 0.0533333333333346*G0_0_1_16_1_0 - 1.26730158730158*G0_0_1_16_1_1 + 1.81587301587301*G0_0_1_17_1_0 + 0.317460317460315*G0_0_1_17_1_1 - 0.835555555555552*G0_0_1_18_1_0 + 0.0279365079365098*G0_0_1_18_1_1 - 0.868571428571422*G0_0_1_19_1_0 - 0.411428571428567*G0_0_1_19_1_1 + 1.09206349206349*G0_1_0_0_0_0 + 1.09206349206349*G0_1_0_0_0_1 - 0.11174603174603*G0_1_0_1_0_0 - 0.213333333333332*G0_1_0_2_0_1 - 0.220952380952378*G0_1_0_3_0_0 + 0.0279365079365103*G0_1_0_3_0_1 + 0.0533333333333346*G0_1_0_4_0_0 - 0.0939682539682531*G0_1_0_4_0_1 - 0.647619047619043*G0_1_0_5_0_0 - 2.14603174603174*G0_1_0_5_0_1 - 0.0533333333333346*G0_1_0_6_0_0 + 1.26730158730158*G0_1_0_6_0_1 - 1.81587301587301*G0_1_0_7_0_0 - 0.317460317460315*G0_1_0_7_0_1 + 0.835555555555553*G0_1_0_8_0_0 - 0.0279365079365099*G0_1_0_8_0_1 + 0.868571428571421*G0_1_0_9_0_0 + 0.411428571428567*G0_1_0_9_0_1 + 1.09206349206349*G0_1_0_10_1_0 + 1.09206349206349*G0_1_0_10_1_1 - 0.11174603174603*G0_1_0_11_1_0 - 0.213333333333332*G0_1_0_12_1_1 - 0.220952380952378*G0_1_0_13_1_0 + 0.0279365079365103*G0_1_0_13_1_1 + 0.0533333333333346*G0_1_0_14_1_0 - 0.0939682539682531*G0_1_0_14_1_1 - 0.647619047619043*G0_1_0_15_1_0 - 2.14603174603174*G0_1_0_15_1_1 - 0.0533333333333346*G0_1_0_16_1_0 + 1.26730158730158*G0_1_0_16_1_1 - 1.81587301587301*G0_1_0_17_1_0 - 0.317460317460315*G0_1_0_17_1_1 + 0.835555555555553*G0_1_0_18_1_0 - 0.0279365079365099*G0_1_0_18_1_1 + 0.868571428571421*G0_1_0_19_1_0 + 0.411428571428567*G0_1_0_19_1_1; + A[579] = 0.0; + A[519] = 0.0; + A[236] = 0.0; + A[682] = A[217]; + A[602] = 0.0; + A[554] = 0.0; + A[713] = -A[245] - 0.406349206349206*G0_0_1_0_0_0 - 0.406349206349206*G0_0_1_0_0_1 + 0.406349206349206*G0_0_1_1_0_0 + 1.93015873015872*G0_0_1_2_0_1 - 1.93015873015872*G0_0_1_3_0_0 + 0.0507936507936547*G0_0_1_3_0_1 + 2.64126984126982*G0_0_1_4_0_0 - 0.863492063492061*G0_0_1_4_0_1 + 1.93015873015872*G0_0_1_5_0_0 + 1.98095238095237*G0_0_1_5_0_1 - 2.64126984126983*G0_0_1_6_0_0 - 3.50476190476189*G0_0_1_6_0_1 - 0.0507936507936502*G0_0_1_7_0_1 - 0.0507936507936545*G0_0_1_8_0_1 + 0.914285714285711*G0_0_1_9_0_1 - 0.406349206349206*G0_0_1_10_1_0 - 0.406349206349206*G0_0_1_10_1_1 + 0.406349206349206*G0_0_1_11_1_0 + 1.93015873015872*G0_0_1_12_1_1 - 1.93015873015872*G0_0_1_13_1_0 + 0.0507936507936547*G0_0_1_13_1_1 + 2.64126984126982*G0_0_1_14_1_0 - 0.863492063492061*G0_0_1_14_1_1 + 1.93015873015872*G0_0_1_15_1_0 + 1.98095238095237*G0_0_1_15_1_1 - 2.64126984126983*G0_0_1_16_1_0 - 3.50476190476189*G0_0_1_16_1_1 - 0.0507936507936502*G0_0_1_17_1_1 - 0.0507936507936545*G0_0_1_18_1_1 + 0.914285714285711*G0_0_1_19_1_1 - 0.778835978835975*G0_1_1_0_0_0 - 0.778835978835975*G0_1_1_0_0_1 + 0.677248677248678*G0_1_1_1_0_0 + 2.7089947089947*G0_1_1_2_0_1 - 2.38730158730158*G0_1_1_3_0_0 + 0.101587301587307*G0_1_1_3_0_1 + 4.92698412698411*G0_1_1_4_0_0 + 0.406349206349207*G0_1_1_4_0_1 - 0.355555555555559*G0_1_1_5_0_0 + 1.32063492063491*G0_1_1_5_0_1 - 4.92698412698411*G0_1_1_6_0_0 - 3.25079365079363*G0_1_1_6_0_1 + 0.0507936507936511*G0_1_1_7_0_0 - 1.62539682539682*G0_1_1_7_0_1 + 0.050793650793645*G0_1_1_8_0_0 - 0.101587301587306*G0_1_1_8_0_1 + 2.74285714285714*G0_1_1_9_0_0 + 1.21904761904761*G0_1_1_9_0_1 - 0.778835978835975*G0_1_1_10_1_0 - 0.778835978835975*G0_1_1_10_1_1 + 0.677248677248678*G0_1_1_11_1_0 + 2.7089947089947*G0_1_1_12_1_1 - 2.38730158730158*G0_1_1_13_1_0 + 0.101587301587307*G0_1_1_13_1_1 + 4.92698412698411*G0_1_1_14_1_0 + 0.406349206349207*G0_1_1_14_1_1 - 0.355555555555559*G0_1_1_15_1_0 + 1.32063492063491*G0_1_1_15_1_1 - 4.92698412698411*G0_1_1_16_1_0 - 3.25079365079363*G0_1_1_16_1_1 + 0.0507936507936511*G0_1_1_17_1_0 - 1.62539682539682*G0_1_1_17_1_1 + 0.050793650793645*G0_1_1_18_1_0 - 0.101587301587306*G0_1_1_18_1_1 + 2.74285714285714*G0_1_1_19_1_0 + 1.21904761904761*G0_1_1_19_1_1; + A[186] = -A[713] - 3.1153439153439*G0_0_0_0_0_0 - 3.1153439153439*G0_0_0_0_0_1 + 1.65248677248677*G0_0_0_1_0_0 + 7.13820105820101*G0_0_0_2_0_1 - 5.40444444444441*G0_0_0_3_0_0 - 0.65015873015872*G0_0_0_3_0_1 + 13.9784126984126*G0_0_0_4_0_0 + 3.73841269841268*G0_0_0_4_0_1 + 1.015873015873*G0_0_0_5_0_0 + 5.48571428571425*G0_0_0_5_0_1 - 13.9784126984126*G0_0_0_6_0_0 - 9.50857142857137*G0_0_0_6_0_1 + 3.65714285714284*G0_0_0_7_0_0 - 0.812698412698407*G0_0_0_7_0_1 - 2.19428571428571*G0_0_0_8_0_0 + 0.650158730158723*G0_0_0_8_0_1 + 4.38857142857141*G0_0_0_9_0_0 - 2.92571428571427*G0_0_0_9_0_1 - 3.1153439153439*G0_0_0_10_1_0 - 3.1153439153439*G0_0_0_10_1_1 + 1.65248677248677*G0_0_0_11_1_0 + 7.13820105820101*G0_0_0_12_1_1 - 5.40444444444441*G0_0_0_13_1_0 - 0.65015873015872*G0_0_0_13_1_1 + 13.9784126984126*G0_0_0_14_1_0 + 3.73841269841268*G0_0_0_14_1_1 + 1.015873015873*G0_0_0_15_1_0 + 5.48571428571425*G0_0_0_15_1_1 - 13.9784126984126*G0_0_0_16_1_0 - 9.50857142857137*G0_0_0_16_1_1 + 3.65714285714284*G0_0_0_17_1_0 - 0.812698412698407*G0_0_0_17_1_1 - 2.19428571428571*G0_0_0_18_1_0 + 0.650158730158723*G0_0_0_18_1_1 + 4.38857142857141*G0_0_0_19_1_0 - 2.92571428571427*G0_0_0_19_1_1 - 0.609523809523811*G0_0_1_0_0_0 - 0.609523809523811*G0_0_1_0_0_1 + 0.670476190476189*G0_0_1_1_0_0 + 4.63238095238093*G0_0_1_2_0_1 - 2.86476190476189*G0_0_1_3_0_0 - 0.24380952380952*G0_0_1_3_0_1 + 9.20380952380947*G0_0_1_4_0_0 + 2.62095238095237*G0_0_1_4_0_1 + 2.74285714285712*G0_0_1_5_0_0 + 2.43809523809523*G0_0_1_5_0_1 - 9.20380952380948*G0_0_1_6_0_0 - 6.46095238095235*G0_0_1_6_0_1 + 0.304761904761901*G0_0_1_7_0_1 - 0.0609523809523865*G0_0_1_8_0_0 + 0.243809523809521*G0_0_1_8_0_1 + 0.121904761904766*G0_0_1_9_0_0 - 2.92571428571427*G0_0_1_9_0_1 - 0.609523809523811*G0_0_1_10_1_0 - 0.609523809523811*G0_0_1_10_1_1 + 0.670476190476189*G0_0_1_11_1_0 + 4.63238095238093*G0_0_1_12_1_1 - 2.86476190476189*G0_0_1_13_1_0 - 0.24380952380952*G0_0_1_13_1_1 + 9.20380952380947*G0_0_1_14_1_0 + 2.62095238095237*G0_0_1_14_1_1 + 2.74285714285712*G0_0_1_15_1_0 + 2.43809523809523*G0_0_1_15_1_1 - 9.20380952380948*G0_0_1_16_1_0 - 6.46095238095235*G0_0_1_16_1_1 + 0.304761904761901*G0_0_1_17_1_1 - 0.0609523809523865*G0_0_1_18_1_0 + 0.243809523809521*G0_0_1_18_1_1 + 0.121904761904766*G0_0_1_19_1_0 - 2.92571428571427*G0_0_1_19_1_1 - 0.609523809523811*G0_1_0_0_0_0 - 0.609523809523811*G0_1_0_0_0_1 + 0.670476190476189*G0_1_0_1_0_0 + 4.63238095238093*G0_1_0_2_0_1 - 2.86476190476189*G0_1_0_3_0_0 - 0.24380952380952*G0_1_0_3_0_1 + 9.20380952380947*G0_1_0_4_0_0 + 2.62095238095237*G0_1_0_4_0_1 + 2.74285714285712*G0_1_0_5_0_0 + 2.43809523809523*G0_1_0_5_0_1 - 9.20380952380948*G0_1_0_6_0_0 - 6.46095238095235*G0_1_0_6_0_1 + 0.304761904761901*G0_1_0_7_0_1 - 0.0609523809523865*G0_1_0_8_0_0 + 0.243809523809521*G0_1_0_8_0_1 + 0.121904761904766*G0_1_0_9_0_0 - 2.92571428571427*G0_1_0_9_0_1 - 0.609523809523811*G0_1_0_10_1_0 - 0.609523809523811*G0_1_0_10_1_1 + 0.670476190476189*G0_1_0_11_1_0 + 4.63238095238093*G0_1_0_12_1_1 - 2.86476190476189*G0_1_0_13_1_0 - 0.24380952380952*G0_1_0_13_1_1 + 9.20380952380947*G0_1_0_14_1_0 + 2.62095238095237*G0_1_0_14_1_1 + 2.74285714285712*G0_1_0_15_1_0 + 2.43809523809523*G0_1_0_15_1_1 - 9.20380952380948*G0_1_0_16_1_0 - 6.46095238095235*G0_1_0_16_1_1 + 0.304761904761901*G0_1_0_17_1_1 - 0.0609523809523865*G0_1_0_18_1_0 + 0.243809523809521*G0_1_0_18_1_1 + 0.121904761904766*G0_1_0_19_1_0 - 2.92571428571427*G0_1_0_19_1_1 - 5.24190476190474*G0_1_1_0_0_0 - 5.24190476190474*G0_1_1_0_0_1 + 1.34095238095238*G0_1_1_1_0_0 + 5.24190476190474*G0_1_1_2_0_1 - 3.1695238095238*G0_1_1_3_0_0 - 0.487619047619039*G0_1_1_3_0_1 + 8.89904761904758*G0_1_1_4_0_0 + 2.31619047619046*G0_1_1_4_0_1 + 8.89904761904757*G0_1_1_5_0_1 - 8.89904761904758*G0_1_1_6_0_0 - 8.89904761904757*G0_1_1_6_0_1 + 6.58285714285711*G0_1_1_7_0_0 - 2.31619047619047*G0_1_1_7_0_1 - 2.68190476190475*G0_1_1_8_0_0 + 0.487619047619041*G0_1_1_8_0_1 + 3.16952380952381*G0_1_1_9_0_0 - 5.24190476190474*G0_1_1_10_1_0 - 5.24190476190474*G0_1_1_10_1_1 + 1.34095238095238*G0_1_1_11_1_0 + 5.24190476190474*G0_1_1_12_1_1 - 3.1695238095238*G0_1_1_13_1_0 - 0.487619047619039*G0_1_1_13_1_1 + 8.89904761904758*G0_1_1_14_1_0 + 2.31619047619046*G0_1_1_14_1_1 + 8.89904761904757*G0_1_1_15_1_1 - 8.89904761904758*G0_1_1_16_1_0 - 8.89904761904757*G0_1_1_16_1_1 + 6.58285714285711*G0_1_1_17_1_0 - 2.31619047619047*G0_1_1_17_1_1 - 2.68190476190475*G0_1_1_18_1_0 + 0.487619047619041*G0_1_1_18_1_1 + 3.16952380952381*G0_1_1_19_1_0; + A[633] = 0.0; + A[248] = A[713]; + A[668] = 0.0; + A[275] = A[740]; + A[703] = 0.0; + A[302] = A[767]; + A[477] = A[360] + 0.101587301587301*G0_0_1_1_0_0 - 0.101587301587301*G0_0_1_2_0_1 - 0.0317460317460302*G0_0_1_3_0_0 + 0.0698412698412698*G0_0_1_3_0_1 - 0.0698412698412693*G0_0_1_4_0_0 + 0.0317460317460325*G0_0_1_4_0_1 - 0.234920634920632*G0_0_1_5_0_0 - 0.234920634920637*G0_0_1_5_0_1 + 0.0698412698412694*G0_0_1_6_0_0 + 0.336507936507935*G0_0_1_6_0_1 + 0.234920634920631*G0_0_1_7_0_0 + 0.234920634920635*G0_0_1_7_0_1 - 0.336507936507933*G0_0_1_8_0_0 - 0.0698412698412698*G0_0_1_8_0_1 + 0.266666666666662*G0_0_1_9_0_0 - 0.266666666666668*G0_0_1_9_0_1 + 0.101587301587301*G0_0_1_11_1_0 - 0.101587301587301*G0_0_1_12_1_1 - 0.0317460317460302*G0_0_1_13_1_0 + 0.0698412698412698*G0_0_1_13_1_1 - 0.0698412698412693*G0_0_1_14_1_0 + 0.0317460317460325*G0_0_1_14_1_1 - 0.234920634920632*G0_0_1_15_1_0 - 0.234920634920637*G0_0_1_15_1_1 + 0.0698412698412694*G0_0_1_16_1_0 + 0.336507936507935*G0_0_1_16_1_1 + 0.234920634920631*G0_0_1_17_1_0 + 0.234920634920635*G0_0_1_17_1_1 - 0.336507936507933*G0_0_1_18_1_0 - 0.0698412698412698*G0_0_1_18_1_1 + 0.266666666666662*G0_0_1_19_1_0 - 0.266666666666668*G0_0_1_19_1_1 - 0.101587301587301*G0_1_0_1_0_0 + 0.101587301587301*G0_1_0_2_0_1 + 0.0317460317460302*G0_1_0_3_0_0 - 0.0698412698412698*G0_1_0_3_0_1 + 0.0698412698412693*G0_1_0_4_0_0 - 0.0317460317460325*G0_1_0_4_0_1 + 0.234920634920632*G0_1_0_5_0_0 + 0.234920634920636*G0_1_0_5_0_1 - 0.0698412698412694*G0_1_0_6_0_0 - 0.336507936507936*G0_1_0_6_0_1 - 0.234920634920631*G0_1_0_7_0_0 - 0.234920634920635*G0_1_0_7_0_1 + 0.336507936507933*G0_1_0_8_0_0 + 0.0698412698412698*G0_1_0_8_0_1 - 0.266666666666662*G0_1_0_9_0_0 + 0.266666666666668*G0_1_0_9_0_1 - 0.101587301587301*G0_1_0_11_1_0 + 0.101587301587301*G0_1_0_12_1_1 + 0.0317460317460302*G0_1_0_13_1_0 - 0.0698412698412698*G0_1_0_13_1_1 + 0.0698412698412693*G0_1_0_14_1_0 - 0.0317460317460325*G0_1_0_14_1_1 + 0.234920634920632*G0_1_0_15_1_0 + 0.234920634920636*G0_1_0_15_1_1 - 0.0698412698412694*G0_1_0_16_1_0 - 0.336507936507936*G0_1_0_16_1_1 - 0.234920634920631*G0_1_0_17_1_0 - 0.234920634920635*G0_1_0_17_1_1 + 0.336507936507933*G0_1_0_18_1_0 + 0.0698412698412698*G0_1_0_18_1_1 - 0.266666666666662*G0_1_0_19_1_0 + 0.266666666666668*G0_1_0_19_1_1; + A[341] = A[806]; + A[20] = 0.0; + A[424] = A[134] - 0.579047619047616*G0_0_1_0_0_0 - 0.579047619047616*G0_0_1_0_0_1 - 0.639999999999998*G0_0_1_1_0_0 + 0.609523809523811*G0_0_1_2_0_1 + 0.990476190476181*G0_0_1_3_0_0 - 0.868571428571427*G0_0_1_3_0_1 + 1.44761904761905*G0_0_1_4_0_0 + 2.05714285714284*G0_0_1_4_0_1 + 2.2095238095238*G0_0_1_5_0_0 + 2.17904761904761*G0_0_1_5_0_1 - 1.44761904761905*G0_0_1_6_0_0 - 2.20952380952381*G0_0_1_6_0_1 + 0.746666666666656*G0_0_1_7_0_0 + 0.777142857142844*G0_0_1_7_0_1 + 0.472380952380958*G0_0_1_8_0_0 + 0.868571428571427*G0_0_1_8_0_1 - 3.19999999999998*G0_0_1_9_0_0 - 2.83428571428569*G0_0_1_9_0_1 - 0.579047619047616*G0_0_1_10_1_0 - 0.579047619047616*G0_0_1_10_1_1 - 0.639999999999998*G0_0_1_11_1_0 + 0.609523809523811*G0_0_1_12_1_1 + 0.990476190476181*G0_0_1_13_1_0 - 0.868571428571427*G0_0_1_13_1_1 + 1.44761904761905*G0_0_1_14_1_0 + 2.05714285714284*G0_0_1_14_1_1 + 2.2095238095238*G0_0_1_15_1_0 + 2.17904761904761*G0_0_1_15_1_1 - 1.44761904761905*G0_0_1_16_1_0 - 2.20952380952381*G0_0_1_16_1_1 + 0.746666666666656*G0_0_1_17_1_0 + 0.777142857142844*G0_0_1_17_1_1 + 0.472380952380958*G0_0_1_18_1_0 + 0.868571428571427*G0_0_1_18_1_1 - 3.19999999999998*G0_0_1_19_1_0 - 2.83428571428569*G0_0_1_19_1_1 + 0.579047619047615*G0_1_0_0_0_0 + 0.579047619047616*G0_1_0_0_0_1 + 0.639999999999998*G0_1_0_1_0_0 - 0.609523809523811*G0_1_0_2_0_1 - 0.99047619047618*G0_1_0_3_0_0 + 0.868571428571427*G0_1_0_3_0_1 - 1.44761904761905*G0_1_0_4_0_0 - 2.05714285714284*G0_1_0_4_0_1 - 2.2095238095238*G0_1_0_5_0_0 - 2.17904761904761*G0_1_0_5_0_1 + 1.44761904761905*G0_1_0_6_0_0 + 2.20952380952381*G0_1_0_6_0_1 - 0.746666666666655*G0_1_0_7_0_0 - 0.777142857142843*G0_1_0_7_0_1 - 0.472380952380958*G0_1_0_8_0_0 - 0.868571428571427*G0_1_0_8_0_1 + 3.19999999999998*G0_1_0_9_0_0 + 2.83428571428569*G0_1_0_9_0_1 + 0.579047619047615*G0_1_0_10_1_0 + 0.579047619047616*G0_1_0_10_1_1 + 0.639999999999998*G0_1_0_11_1_0 - 0.609523809523811*G0_1_0_12_1_1 - 0.99047619047618*G0_1_0_13_1_0 + 0.868571428571427*G0_1_0_13_1_1 - 1.44761904761905*G0_1_0_14_1_0 - 2.05714285714284*G0_1_0_14_1_1 - 2.2095238095238*G0_1_0_15_1_0 - 2.17904761904761*G0_1_0_15_1_1 + 1.44761904761905*G0_1_0_16_1_0 + 2.20952380952381*G0_1_0_16_1_1 - 0.746666666666655*G0_1_0_17_1_0 - 0.777142857142843*G0_1_0_17_1_1 - 0.472380952380958*G0_1_0_18_1_0 - 0.868571428571427*G0_1_0_18_1_1 + 3.19999999999998*G0_1_0_19_1_0 + 2.83428571428569*G0_1_0_19_1_1; + A[372] = -3.49460317460315*G0_0_0_0_0_0 - 3.49460317460315*G0_0_0_0_0_1 + 1.54412698412698*G0_0_0_1_0_0 - 0.77206349206349*G0_0_0_2_0_1 + 3.53523809523807*G0_0_0_3_0_0 + 1.95047619047618*G0_0_0_3_0_1 + 2.07238095238095*G0_0_0_4_0_0 + 5.9733333333333*G0_0_0_4_0_1 - 9.38666666666664*G0_0_0_5_0_0 - 0.609523809523822*G0_0_0_5_0_1 - 2.07238095238095*G0_0_0_6_0_0 + 4.87619047619047*G0_0_0_6_0_1 + 6.46095238095234*G0_0_0_7_0_0 - 2.31619047619047*G0_0_0_7_0_1 - 4.51047619047616*G0_0_0_8_0_0 - 1.95047619047618*G0_0_0_8_0_1 + 5.85142857142857*G0_0_0_9_0_0 - 3.65714285714283*G0_0_0_9_0_1 - 3.49460317460315*G0_0_0_10_1_0 - 3.49460317460315*G0_0_0_10_1_1 + 1.54412698412698*G0_0_0_11_1_0 - 0.77206349206349*G0_0_0_12_1_1 + 3.53523809523807*G0_0_0_13_1_0 + 1.95047619047618*G0_0_0_13_1_1 + 2.07238095238095*G0_0_0_14_1_0 + 5.9733333333333*G0_0_0_14_1_1 - 9.38666666666664*G0_0_0_15_1_0 - 0.609523809523822*G0_0_0_15_1_1 - 2.07238095238095*G0_0_0_16_1_0 + 4.87619047619047*G0_0_0_16_1_1 + 6.46095238095234*G0_0_0_17_1_0 - 2.31619047619047*G0_0_0_17_1_1 - 4.51047619047616*G0_0_0_18_1_0 - 1.95047619047618*G0_0_0_18_1_1 + 5.85142857142857*G0_0_0_19_1_0 - 3.65714285714283*G0_0_0_19_1_1 - 0.954920634920627*G0_0_1_0_0_0 - 0.954920634920627*G0_0_1_0_0_1 - 0.142222222222222*G0_0_1_1_0_0 - 0.142222222222221*G0_0_1_2_0_1 + 5.91238095238092*G0_0_1_3_0_0 + 1.8895238095238*G0_0_1_3_0_1 + 1.88952380952381*G0_0_1_4_0_0 + 5.91238095238092*G0_0_1_4_0_1 - 0.0609523809523859*G0_0_1_5_0_0 + 1.09714285714284*G0_0_1_5_0_1 - 1.8895238095238*G0_0_1_6_0_0 + 1.09714285714284*G0_0_1_7_0_0 - 0.0609523809523873*G0_0_1_7_0_1 - 1.8895238095238*G0_0_1_8_0_1 - 5.85142857142853*G0_0_1_9_0_0 - 5.85142857142854*G0_0_1_9_0_1 - 0.954920634920627*G0_0_1_10_1_0 - 0.954920634920627*G0_0_1_10_1_1 - 0.142222222222222*G0_0_1_11_1_0 - 0.142222222222221*G0_0_1_12_1_1 + 5.91238095238092*G0_0_1_13_1_0 + 1.8895238095238*G0_0_1_13_1_1 + 1.88952380952381*G0_0_1_14_1_0 + 5.91238095238092*G0_0_1_14_1_1 - 0.0609523809523859*G0_0_1_15_1_0 + 1.09714285714284*G0_0_1_15_1_1 - 1.8895238095238*G0_0_1_16_1_0 + 1.09714285714284*G0_0_1_17_1_0 - 0.0609523809523873*G0_0_1_17_1_1 - 1.8895238095238*G0_0_1_18_1_1 - 5.85142857142853*G0_0_1_19_1_0 - 5.85142857142854*G0_0_1_19_1_1 - 0.954920634920627*G0_1_0_0_0_0 - 0.954920634920627*G0_1_0_0_0_1 - 0.142222222222222*G0_1_0_1_0_0 - 0.142222222222221*G0_1_0_2_0_1 + 5.91238095238092*G0_1_0_3_0_0 + 1.8895238095238*G0_1_0_3_0_1 + 1.88952380952381*G0_1_0_4_0_0 + 5.91238095238092*G0_1_0_4_0_1 - 0.0609523809523859*G0_1_0_5_0_0 + 1.09714285714284*G0_1_0_5_0_1 - 1.8895238095238*G0_1_0_6_0_0 + 1.09714285714284*G0_1_0_7_0_0 - 0.0609523809523873*G0_1_0_7_0_1 - 1.8895238095238*G0_1_0_8_0_1 - 5.85142857142853*G0_1_0_9_0_0 - 5.85142857142854*G0_1_0_9_0_1 - 0.954920634920627*G0_1_0_10_1_0 - 0.954920634920627*G0_1_0_10_1_1 - 0.142222222222222*G0_1_0_11_1_0 - 0.142222222222221*G0_1_0_12_1_1 + 5.91238095238092*G0_1_0_13_1_0 + 1.8895238095238*G0_1_0_13_1_1 + 1.88952380952381*G0_1_0_14_1_0 + 5.91238095238092*G0_1_0_14_1_1 - 0.0609523809523859*G0_1_0_15_1_0 + 1.09714285714284*G0_1_0_15_1_1 - 1.8895238095238*G0_1_0_16_1_0 + 1.09714285714284*G0_1_0_17_1_0 - 0.0609523809523873*G0_1_0_17_1_1 - 1.8895238095238*G0_1_0_18_1_1 - 5.85142857142853*G0_1_0_19_1_0 - 5.85142857142854*G0_1_0_19_1_1 - 3.49460317460315*G0_1_1_0_0_0 - 3.49460317460316*G0_1_1_0_0_1 - 0.772063492063489*G0_1_1_1_0_0 + 1.54412698412698*G0_1_1_2_0_1 + 5.9733333333333*G0_1_1_3_0_0 + 2.07238095238095*G0_1_1_3_0_1 + 1.95047619047619*G0_1_1_4_0_0 + 3.53523809523808*G0_1_1_4_0_1 - 2.31619047619047*G0_1_1_5_0_0 + 6.46095238095234*G0_1_1_5_0_1 - 1.95047619047618*G0_1_1_6_0_0 - 4.51047619047617*G0_1_1_6_0_1 - 0.609523809523816*G0_1_1_7_0_0 - 9.38666666666663*G0_1_1_7_0_1 + 4.87619047619046*G0_1_1_8_0_0 - 2.07238095238094*G0_1_1_8_0_1 - 3.65714285714284*G0_1_1_9_0_0 + 5.85142857142855*G0_1_1_9_0_1 - 3.49460317460315*G0_1_1_10_1_0 - 3.49460317460316*G0_1_1_10_1_1 - 0.772063492063489*G0_1_1_11_1_0 + 1.54412698412698*G0_1_1_12_1_1 + 5.9733333333333*G0_1_1_13_1_0 + 2.07238095238095*G0_1_1_13_1_1 + 1.95047619047619*G0_1_1_14_1_0 + 3.53523809523808*G0_1_1_14_1_1 - 2.31619047619047*G0_1_1_15_1_0 + 6.46095238095234*G0_1_1_15_1_1 - 1.95047619047618*G0_1_1_16_1_0 - 4.51047619047617*G0_1_1_16_1_1 - 0.609523809523816*G0_1_1_17_1_0 - 9.38666666666663*G0_1_1_17_1_1 + 4.87619047619046*G0_1_1_18_1_0 - 2.07238095238094*G0_1_1_18_1_1 - 3.65714285714284*G0_1_1_19_1_0 + 5.85142857142855*G0_1_1_19_1_1; + A[47] = 0.0; + A[762] = 0.0; + A[451] = 0.0; + A[407] = 0.0; + A[82] = 0.0; + A[791] = 0.0; + A[10] = A[475]; + A[97] = A[562]; + A[812] = 0.0; + A[41] = A[506]; + A[120] = A[585]; + A[845] = 0.0; + A[155] = A[620]; + A[878] = 0.0; + A[483] = 0.0; + A[190] = A[655]; + A[584] = 0.0; + A[512] = 0.0; + A[229] = 0.0; + A[609] = 0.0; + A[549] = 0.0; + A[505] = A[40]; + A[642] = 0.0; + A[255] = 0.0; + A[663] = 0.0; + A[284] = A[749]; + A[700] = 0.0; + A[313] = A[865] - 0.639999999999994*G0_0_1_0_0_0 - 0.639999999999994*G0_0_1_0_0_1 - 0.609523809523807*G0_0_1_1_0_0 - 0.579047619047617*G0_0_1_2_0_1 + 0.761904761904756*G0_0_1_3_0_0 - 1.44761904761905*G0_0_1_3_0_1 + 0.0304761904761927*G0_0_1_4_0_0 + 2.2095238095238*G0_0_1_4_0_1 - 0.396190476190478*G0_0_1_5_0_0 + 0.472380952380942*G0_0_1_5_0_1 - 0.0304761904761923*G0_0_1_6_0_0 + 0.74666666666667*G0_0_1_6_0_1 + 1.85904761904761*G0_0_1_7_0_0 + 0.990476190476187*G0_0_1_7_0_1 - 0.609523809523806*G0_0_1_8_0_0 + 1.44761904761905*G0_0_1_8_0_1 - 0.365714285714278*G0_0_1_9_0_0 - 3.19999999999999*G0_0_1_9_0_1 - 0.639999999999994*G0_0_1_10_1_0 - 0.639999999999994*G0_0_1_10_1_1 - 0.609523809523807*G0_0_1_11_1_0 - 0.579047619047617*G0_0_1_12_1_1 + 0.761904761904756*G0_0_1_13_1_0 - 1.44761904761905*G0_0_1_13_1_1 + 0.0304761904761927*G0_0_1_14_1_0 + 2.2095238095238*G0_0_1_14_1_1 - 0.396190476190478*G0_0_1_15_1_0 + 0.472380952380942*G0_0_1_15_1_1 - 0.0304761904761923*G0_0_1_16_1_0 + 0.74666666666667*G0_0_1_16_1_1 + 1.85904761904761*G0_0_1_17_1_0 + 0.990476190476187*G0_0_1_17_1_1 - 0.609523809523806*G0_0_1_18_1_0 + 1.44761904761905*G0_0_1_18_1_1 - 0.365714285714278*G0_0_1_19_1_0 - 3.19999999999999*G0_0_1_19_1_1 + 0.639999999999994*G0_1_0_0_0_0 + 0.639999999999994*G0_1_0_0_0_1 + 0.609523809523808*G0_1_0_1_0_0 + 0.579047619047617*G0_1_0_2_0_1 - 0.761904761904756*G0_1_0_3_0_0 + 1.44761904761905*G0_1_0_3_0_1 - 0.0304761904761927*G0_1_0_4_0_0 - 2.2095238095238*G0_1_0_4_0_1 + 0.396190476190478*G0_1_0_5_0_0 - 0.472380952380942*G0_1_0_5_0_1 + 0.0304761904761923*G0_1_0_6_0_0 - 0.74666666666667*G0_1_0_6_0_1 - 1.85904761904761*G0_1_0_7_0_0 - 0.990476190476187*G0_1_0_7_0_1 + 0.609523809523806*G0_1_0_8_0_0 - 1.44761904761905*G0_1_0_8_0_1 + 0.365714285714278*G0_1_0_9_0_0 + 3.19999999999999*G0_1_0_9_0_1 + 0.639999999999994*G0_1_0_10_1_0 + 0.639999999999994*G0_1_0_10_1_1 + 0.609523809523808*G0_1_0_11_1_0 + 0.579047619047617*G0_1_0_12_1_1 - 0.761904761904756*G0_1_0_13_1_0 + 1.44761904761905*G0_1_0_13_1_1 - 0.0304761904761927*G0_1_0_14_1_0 - 2.2095238095238*G0_1_0_14_1_1 + 0.396190476190478*G0_1_0_15_1_0 - 0.472380952380942*G0_1_0_15_1_1 + 0.0304761904761923*G0_1_0_16_1_0 - 0.74666666666667*G0_1_0_16_1_1 - 1.85904761904761*G0_1_0_17_1_0 - 0.990476190476187*G0_1_0_17_1_1 + 0.609523809523806*G0_1_0_18_1_0 - 1.44761904761905*G0_1_0_18_1_1 + 0.365714285714278*G0_1_0_19_1_0 + 3.19999999999999*G0_1_0_19_1_1; + A[261] = 0.0; + A[330] = A[795]; + A[286] = 0.0; + A[744] = A[279]; + A[435] = 0.0; + A[371] = A[836]; + A[323] = 0.0; + A[771] = A[306]; + A[464] = 0.0; + A[400] = A[865]; + A[77] = 0.0; + A[798] = A[333]; + A[1] = A[466]; + A[102] = A[567]; + A[837] = A[372]; + A[42] = A[509] + 0.228571428571427*G0_0_0_0_0_0 + 0.228571428571427*G0_0_0_0_0_1 + 0.350476190476188*G0_0_0_2_0_1 - 0.274285714285712*G0_0_0_3_0_0 + 0.65523809523809*G0_0_0_4_0_0 + 0.0304761904761883*G0_0_0_4_0_1 + 0.426666666666663*G0_0_0_5_0_0 - 0.106666666666667*G0_0_0_5_0_1 - 0.65523809523809*G0_0_0_6_0_0 - 0.472380952380948*G0_0_0_6_0_1 - 0.50285714285714*G0_0_0_7_0_0 + 0.0304761904761907*G0_0_0_7_0_1 + 0.27428571428571*G0_0_0_8_0_0 - 0.15238095238095*G0_0_0_9_0_0 - 0.0609523809523788*G0_0_0_9_0_1 + 0.228571428571427*G0_0_0_10_1_0 + 0.228571428571427*G0_0_0_10_1_1 + 0.350476190476188*G0_0_0_12_1_1 - 0.274285714285712*G0_0_0_13_1_0 + 0.65523809523809*G0_0_0_14_1_0 + 0.0304761904761883*G0_0_0_14_1_1 + 0.426666666666663*G0_0_0_15_1_0 - 0.106666666666667*G0_0_0_15_1_1 - 0.65523809523809*G0_0_0_16_1_0 - 0.472380952380948*G0_0_0_16_1_1 - 0.50285714285714*G0_0_0_17_1_0 + 0.0304761904761907*G0_0_0_17_1_1 + 0.27428571428571*G0_0_0_18_1_0 - 0.15238095238095*G0_0_0_19_1_0 - 0.0609523809523788*G0_0_0_19_1_1 - 0.12190476190476*G0_0_1_0_0_0 - 0.121904761904761*G0_0_1_0_0_1 + 0.121904761904761*G0_0_1_2_0_1 + 0.12190476190476*G0_0_1_4_0_0 + 0.243809523809522*G0_0_1_5_0_0 + 0.365714285714282*G0_0_1_5_0_1 - 0.12190476190476*G0_0_1_6_0_0 - 0.365714285714282*G0_0_1_6_0_1 + 0.121904761904761*G0_0_1_7_0_0 - 0.243809523809523*G0_0_1_9_0_0 - 0.12190476190476*G0_0_1_10_1_0 - 0.121904761904761*G0_0_1_10_1_1 + 0.121904761904761*G0_0_1_12_1_1 + 0.12190476190476*G0_0_1_14_1_0 + 0.243809523809522*G0_0_1_15_1_0 + 0.365714285714282*G0_0_1_15_1_1 - 0.12190476190476*G0_0_1_16_1_0 - 0.365714285714282*G0_0_1_16_1_1 + 0.121904761904761*G0_0_1_17_1_0 - 0.243809523809523*G0_0_1_19_1_0; + A[135] = 0.0; + A[868] = A[403]; + A[71] = A[534] - 0.129523809523809*G0_1_0_0_0_0 - 0.129523809523809*G0_1_0_0_0_1 + 0.12952380952381*G0_1_0_1_0_0 + 0.12952380952381*G0_1_0_3_0_1 + 0.129523809523808*G0_1_0_5_0_1 + 0.388571428571427*G0_1_0_7_0_0 + 0.259047619047619*G0_1_0_7_0_1 - 0.388571428571428*G0_1_0_8_0_0 - 0.129523809523811*G0_1_0_8_0_1 - 0.259047619047618*G0_1_0_9_0_1 - 0.129523809523809*G0_1_0_10_1_0 - 0.129523809523809*G0_1_0_10_1_1 + 0.12952380952381*G0_1_0_11_1_0 + 0.12952380952381*G0_1_0_13_1_1 + 0.129523809523808*G0_1_0_15_1_1 + 0.388571428571427*G0_1_0_17_1_0 + 0.259047619047619*G0_1_0_17_1_1 - 0.388571428571428*G0_1_0_18_1_0 - 0.129523809523811*G0_1_0_18_1_1 - 0.259047619047618*G0_1_0_19_1_1 + 0.126984126984126*G0_1_1_0_0_0 + 0.126984126984126*G0_1_1_0_0_1 + 0.256507936507937*G0_1_1_1_0_0 - 0.0533333333333323*G0_1_1_3_0_0 + 0.421587301587302*G0_1_1_3_0_1 - 0.218412698412698*G0_1_1_4_0_1 - 0.0533333333333334*G0_1_1_5_0_0 - 0.345396825396824*G0_1_1_5_0_1 + 0.218412698412698*G0_1_1_6_0_1 + 0.00253968253968336*G0_1_1_7_0_0 + 0.294603174603174*G0_1_1_7_0_1 - 0.386031746031746*G0_1_1_8_0_0 - 0.421587301587302*G0_1_1_8_0_1 + 0.106666666666666*G0_1_1_9_0_0 - 0.0761904761904756*G0_1_1_9_0_1 + 0.126984126984126*G0_1_1_10_1_0 + 0.126984126984126*G0_1_1_10_1_1 + 0.256507936507937*G0_1_1_11_1_0 - 0.0533333333333323*G0_1_1_13_1_0 + 0.421587301587302*G0_1_1_13_1_1 - 0.218412698412698*G0_1_1_14_1_1 - 0.0533333333333334*G0_1_1_15_1_0 - 0.345396825396824*G0_1_1_15_1_1 + 0.218412698412698*G0_1_1_16_1_1 + 0.00253968253968336*G0_1_1_17_1_0 + 0.294603174603174*G0_1_1_17_1_1 - 0.386031746031746*G0_1_1_18_1_0 - 0.421587301587302*G0_1_1_18_1_1 + 0.106666666666666*G0_1_1_19_1_0 - 0.0761904761904756*G0_1_1_19_1_1; + A[63] = -A[71] - 0.0876190476190473*G0_1_0_0_0_0 - 0.0876190476190473*G0_1_0_0_0_1 + 0.285714285714286*G0_1_0_1_0_0 + 0.590476190476187*G0_1_0_2_0_1 - 0.452063492063488*G0_1_0_3_0_0 + 0.260317460317462*G0_1_0_3_0_1 + 1.07936507936507*G0_1_0_4_0_0 + 0.0622222222222222*G0_1_0_4_0_1 + 0.322539682539682*G0_1_0_5_0_0 + 0.25142857142857*G0_1_0_5_0_1 - 1.07936507936507*G0_1_0_6_0_0 - 0.754285714285711*G0_1_0_6_0_1 + 0.156190476190476*G0_1_0_7_0_0 + 0.227301587301588*G0_1_0_7_0_1 - 0.354285714285715*G0_1_0_8_0_0 - 0.260317460317462*G0_1_0_8_0_1 + 0.129523809523806*G0_1_0_9_0_0 - 0.28952380952381*G0_1_0_9_0_1 - 0.0876190476190473*G0_1_0_10_1_0 - 0.0876190476190473*G0_1_0_10_1_1 + 0.285714285714286*G0_1_0_11_1_0 + 0.590476190476187*G0_1_0_12_1_1 - 0.452063492063488*G0_1_0_13_1_0 + 0.260317460317462*G0_1_0_13_1_1 + 1.07936507936507*G0_1_0_14_1_0 + 0.0622222222222222*G0_1_0_14_1_1 + 0.322539682539682*G0_1_0_15_1_0 + 0.25142857142857*G0_1_0_15_1_1 - 1.07936507936507*G0_1_0_16_1_0 - 0.754285714285711*G0_1_0_16_1_1 + 0.156190476190476*G0_1_0_17_1_0 + 0.227301587301588*G0_1_0_17_1_1 - 0.354285714285715*G0_1_0_18_1_0 - 0.260317460317462*G0_1_0_18_1_1 + 0.129523809523806*G0_1_0_19_1_0 - 0.28952380952381*G0_1_0_19_1_1; + A[531] = -A[63] + 0.101587301587301*G0_1_0_0_0_0 + 0.101587301587301*G0_1_0_0_0_1 + 0.101587301587301*G0_1_0_1_0_0 - 0.0761904761904766*G0_1_0_3_0_0 + 0.165079365079364*G0_1_0_3_0_1 - 0.139682539682538*G0_1_0_4_0_1 - 0.0761904761904743*G0_1_0_5_0_0 - 0.241269841269839*G0_1_0_5_0_1 + 0.139682539682536*G0_1_0_6_0_1 - 0.101587301587301*G0_1_0_7_0_0 + 0.0634920634920642*G0_1_0_7_0_1 - 0.101587301587301*G0_1_0_8_0_0 - 0.165079365079364*G0_1_0_8_0_1 + 0.152380952380951*G0_1_0_9_0_0 + 0.0761904761904743*G0_1_0_9_0_1 + 0.101587301587301*G0_1_0_10_1_0 + 0.101587301587301*G0_1_0_10_1_1 + 0.101587301587301*G0_1_0_11_1_0 - 0.0761904761904766*G0_1_0_13_1_0 + 0.165079365079364*G0_1_0_13_1_1 - 0.139682539682538*G0_1_0_14_1_1 - 0.0761904761904743*G0_1_0_15_1_0 - 0.241269841269839*G0_1_0_15_1_1 + 0.139682539682536*G0_1_0_16_1_1 - 0.101587301587301*G0_1_0_17_1_0 + 0.0634920634920642*G0_1_0_17_1_1 - 0.101587301587301*G0_1_0_18_1_0 - 0.165079365079364*G0_1_0_18_1_1 + 0.152380952380951*G0_1_0_19_1_0 + 0.0761904761904743*G0_1_0_19_1_1 + 0.41100529100529*G0_1_1_0_0_0 + 0.41100529100529*G0_1_1_0_0_1 - 0.30941798941799*G0_1_1_1_0_0 - 0.649735449735448*G0_1_1_2_0_1 + 0.323809523809523*G0_1_1_3_0_0 - 0.370793650793652*G0_1_1_3_0_1 - 0.895238095238093*G0_1_1_4_0_0 + 0.13968253968254*G0_1_1_4_0_1 - 0.399999999999999*G0_1_1_5_0_0 - 0.935873015873013*G0_1_1_5_0_1 + 0.895238095238093*G0_1_1_6_0_0 + 1.17460317460317*G0_1_1_6_0_1 - 0.439365079365078*G0_1_1_7_0_0 + 0.0965079365079355*G0_1_1_7_0_1 + 0.337777777777778*G0_1_1_8_0_0 + 0.370793650793652*G0_1_1_8_0_1 + 0.076190476190476*G0_1_1_9_0_0 - 0.236190476190476*G0_1_1_9_0_1 + 0.41100529100529*G0_1_1_10_1_0 + 0.41100529100529*G0_1_1_10_1_1 - 0.30941798941799*G0_1_1_11_1_0 - 0.649735449735448*G0_1_1_12_1_1 + 0.323809523809523*G0_1_1_13_1_0 - 0.370793650793652*G0_1_1_13_1_1 - 0.895238095238093*G0_1_1_14_1_0 + 0.13968253968254*G0_1_1_14_1_1 - 0.399999999999999*G0_1_1_15_1_0 - 0.935873015873013*G0_1_1_15_1_1 + 0.895238095238093*G0_1_1_16_1_0 + 1.17460317460317*G0_1_1_16_1_1 - 0.439365079365078*G0_1_1_17_1_0 + 0.0965079365079355*G0_1_1_17_1_1 + 0.337777777777778*G0_1_1_18_1_0 + 0.370793650793652*G0_1_1_18_1_1 + 0.076190476190476*G0_1_1_19_1_0 - 0.236190476190476*G0_1_1_19_1_1; + A[797] = A[71] - 0.0165079365079364*G0_0_1_0_0_0 - 0.0165079365079364*G0_0_1_0_0_1 + 0.113015873015873*G0_0_1_1_0_0 - 0.0266666666666663*G0_0_1_3_0_0 + 0.147936507936509*G0_0_1_3_0_1 - 0.0615873015873018*G0_0_1_4_0_1 - 0.0266666666666663*G0_0_1_5_0_0 - 0.0450793650793651*G0_0_1_5_0_1 + 0.0615873015873014*G0_0_1_6_0_1 + 0.146031746031746*G0_0_1_7_0_0 + 0.164444444444445*G0_0_1_7_0_1 - 0.242539682539683*G0_0_1_8_0_0 - 0.147936507936509*G0_0_1_8_0_1 + 0.0533333333333326*G0_0_1_9_0_0 - 0.102857142857143*G0_0_1_9_0_1 - 0.0165079365079364*G0_0_1_10_1_0 - 0.0165079365079364*G0_0_1_10_1_1 + 0.113015873015873*G0_0_1_11_1_0 - 0.0266666666666663*G0_0_1_13_1_0 + 0.147936507936509*G0_0_1_13_1_1 - 0.0615873015873018*G0_0_1_14_1_1 - 0.0266666666666663*G0_0_1_15_1_0 - 0.0450793650793651*G0_0_1_15_1_1 + 0.0615873015873014*G0_0_1_16_1_1 + 0.146031746031746*G0_0_1_17_1_0 + 0.164444444444445*G0_0_1_17_1_1 - 0.242539682539683*G0_0_1_18_1_0 - 0.147936507936509*G0_0_1_18_1_1 + 0.0533333333333326*G0_0_1_19_1_0 - 0.102857142857143*G0_0_1_19_1_1 + 0.0165079365079364*G0_1_0_0_0_0 + 0.0165079365079364*G0_1_0_0_0_1 - 0.113015873015873*G0_1_0_1_0_0 + 0.0266666666666663*G0_1_0_3_0_0 - 0.147936507936509*G0_1_0_3_0_1 + 0.0615873015873018*G0_1_0_4_0_1 + 0.0266666666666663*G0_1_0_5_0_0 + 0.0450793650793651*G0_1_0_5_0_1 - 0.0615873015873014*G0_1_0_6_0_1 - 0.146031746031746*G0_1_0_7_0_0 - 0.164444444444445*G0_1_0_7_0_1 + 0.242539682539683*G0_1_0_8_0_0 + 0.147936507936509*G0_1_0_8_0_1 - 0.0533333333333326*G0_1_0_9_0_0 + 0.102857142857143*G0_1_0_9_0_1 + 0.0165079365079364*G0_1_0_10_1_0 + 0.0165079365079364*G0_1_0_10_1_1 - 0.113015873015873*G0_1_0_11_1_0 + 0.0266666666666663*G0_1_0_13_1_0 - 0.147936507936509*G0_1_0_13_1_1 + 0.0615873015873018*G0_1_0_14_1_1 + 0.0266666666666663*G0_1_0_15_1_0 + 0.0450793650793651*G0_1_0_15_1_1 - 0.0615873015873014*G0_1_0_16_1_1 - 0.146031746031746*G0_1_0_17_1_0 - 0.164444444444445*G0_1_0_17_1_1 + 0.242539682539683*G0_1_0_18_1_0 + 0.147936507936509*G0_1_0_18_1_1 - 0.0533333333333326*G0_1_0_19_1_0 + 0.102857142857143*G0_1_0_19_1_1; + A[92] = -A[797] - 0.0876190476190473*G0_0_1_0_0_0 - 0.0876190476190473*G0_0_1_0_0_1 + 0.285714285714286*G0_0_1_1_0_0 + 0.590476190476187*G0_0_1_2_0_1 - 0.452063492063488*G0_0_1_3_0_0 + 0.260317460317462*G0_0_1_3_0_1 + 1.07936507936507*G0_0_1_4_0_0 + 0.0622222222222222*G0_0_1_4_0_1 + 0.322539682539682*G0_0_1_5_0_0 + 0.25142857142857*G0_0_1_5_0_1 - 1.07936507936507*G0_0_1_6_0_0 - 0.75428571428571*G0_0_1_6_0_1 + 0.156190476190476*G0_0_1_7_0_0 + 0.227301587301588*G0_0_1_7_0_1 - 0.354285714285715*G0_0_1_8_0_0 - 0.260317460317462*G0_0_1_8_0_1 + 0.129523809523806*G0_0_1_9_0_0 - 0.28952380952381*G0_0_1_9_0_1 - 0.0876190476190473*G0_0_1_10_1_0 - 0.0876190476190473*G0_0_1_10_1_1 + 0.285714285714286*G0_0_1_11_1_0 + 0.590476190476187*G0_0_1_12_1_1 - 0.452063492063488*G0_0_1_13_1_0 + 0.260317460317462*G0_0_1_13_1_1 + 1.07936507936507*G0_0_1_14_1_0 + 0.0622222222222222*G0_0_1_14_1_1 + 0.322539682539682*G0_0_1_15_1_0 + 0.25142857142857*G0_0_1_15_1_1 - 1.07936507936507*G0_0_1_16_1_0 - 0.75428571428571*G0_0_1_16_1_1 + 0.156190476190476*G0_0_1_17_1_0 + 0.227301587301588*G0_0_1_17_1_1 - 0.354285714285715*G0_0_1_18_1_0 - 0.260317460317462*G0_0_1_18_1_1 + 0.129523809523806*G0_0_1_19_1_0 - 0.28952380952381*G0_0_1_19_1_1; + A[647] = -A[92] + 0.101587301587301*G0_0_1_0_0_0 + 0.101587301587301*G0_0_1_0_0_1 + 0.101587301587301*G0_0_1_1_0_0 - 0.0761904761904767*G0_0_1_3_0_0 + 0.165079365079364*G0_0_1_3_0_1 - 0.139682539682538*G0_0_1_4_0_1 - 0.0761904761904742*G0_0_1_5_0_0 - 0.241269841269839*G0_0_1_5_0_1 + 0.139682539682536*G0_0_1_6_0_1 - 0.101587301587301*G0_0_1_7_0_0 + 0.0634920634920642*G0_0_1_7_0_1 - 0.101587301587301*G0_0_1_8_0_0 - 0.165079365079364*G0_0_1_8_0_1 + 0.152380952380951*G0_0_1_9_0_0 + 0.0761904761904742*G0_0_1_9_0_1 + 0.101587301587301*G0_0_1_10_1_0 + 0.101587301587301*G0_0_1_10_1_1 + 0.101587301587301*G0_0_1_11_1_0 - 0.0761904761904767*G0_0_1_13_1_0 + 0.165079365079364*G0_0_1_13_1_1 - 0.139682539682538*G0_0_1_14_1_1 - 0.0761904761904742*G0_0_1_15_1_0 - 0.241269841269839*G0_0_1_15_1_1 + 0.139682539682536*G0_0_1_16_1_1 - 0.101587301587301*G0_0_1_17_1_0 + 0.0634920634920642*G0_0_1_17_1_1 - 0.101587301587301*G0_0_1_18_1_0 - 0.165079365079364*G0_0_1_18_1_1 + 0.152380952380951*G0_0_1_19_1_0 + 0.0761904761904742*G0_0_1_19_1_1 + 0.41100529100529*G0_1_1_0_0_0 + 0.41100529100529*G0_1_1_0_0_1 - 0.30941798941799*G0_1_1_1_0_0 - 0.649735449735448*G0_1_1_2_0_1 + 0.323809523809523*G0_1_1_3_0_0 - 0.370793650793652*G0_1_1_3_0_1 - 0.895238095238093*G0_1_1_4_0_0 + 0.13968253968254*G0_1_1_4_0_1 - 0.399999999999999*G0_1_1_5_0_0 - 0.935873015873013*G0_1_1_5_0_1 + 0.895238095238093*G0_1_1_6_0_0 + 1.17460317460317*G0_1_1_6_0_1 - 0.439365079365078*G0_1_1_7_0_0 + 0.0965079365079355*G0_1_1_7_0_1 + 0.337777777777778*G0_1_1_8_0_0 + 0.370793650793652*G0_1_1_8_0_1 + 0.076190476190476*G0_1_1_9_0_0 - 0.236190476190476*G0_1_1_9_0_1 + 0.41100529100529*G0_1_1_10_1_0 + 0.41100529100529*G0_1_1_10_1_1 - 0.30941798941799*G0_1_1_11_1_0 - 0.649735449735448*G0_1_1_12_1_1 + 0.323809523809523*G0_1_1_13_1_0 - 0.370793650793652*G0_1_1_13_1_1 - 0.895238095238093*G0_1_1_14_1_0 + 0.13968253968254*G0_1_1_14_1_1 - 0.399999999999999*G0_1_1_15_1_0 - 0.935873015873013*G0_1_1_15_1_1 + 0.895238095238093*G0_1_1_16_1_0 + 1.17460317460317*G0_1_1_16_1_1 - 0.439365079365078*G0_1_1_17_1_0 + 0.0965079365079355*G0_1_1_17_1_1 + 0.337777777777778*G0_1_1_18_1_0 + 0.370793650793652*G0_1_1_18_1_1 + 0.076190476190476*G0_1_1_19_1_0 - 0.236190476190476*G0_1_1_19_1_1; + A[557] = A[92]; + A[182] = A[647]; + A[66] = A[531]; + A[528] = A[63]; + A[737] = A[797] + 0.129523809523809*G0_0_1_0_0_0 + 0.129523809523809*G0_0_1_0_0_1 - 0.12952380952381*G0_0_1_1_0_0 - 0.12952380952381*G0_0_1_3_0_1 - 0.129523809523808*G0_0_1_5_0_1 - 0.388571428571427*G0_0_1_7_0_0 - 0.259047619047619*G0_0_1_7_0_1 + 0.388571428571428*G0_0_1_8_0_0 + 0.129523809523811*G0_0_1_8_0_1 + 0.259047619047618*G0_0_1_9_0_1 + 0.129523809523809*G0_0_1_10_1_0 + 0.129523809523809*G0_0_1_10_1_1 - 0.12952380952381*G0_0_1_11_1_0 - 0.12952380952381*G0_0_1_13_1_1 - 0.129523809523808*G0_0_1_15_1_1 - 0.388571428571427*G0_0_1_17_1_0 - 0.259047619047619*G0_0_1_17_1_1 + 0.388571428571428*G0_0_1_18_1_0 + 0.129523809523811*G0_0_1_18_1_1 + 0.259047619047618*G0_0_1_19_1_1 - 0.126984126984126*G0_1_1_0_0_0 - 0.126984126984126*G0_1_1_0_0_1 - 0.256507936507937*G0_1_1_1_0_0 + 0.0533333333333323*G0_1_1_3_0_0 - 0.421587301587302*G0_1_1_3_0_1 + 0.218412698412698*G0_1_1_4_0_1 + 0.0533333333333334*G0_1_1_5_0_0 + 0.345396825396824*G0_1_1_5_0_1 - 0.218412698412698*G0_1_1_6_0_1 - 0.00253968253968336*G0_1_1_7_0_0 - 0.294603174603174*G0_1_1_7_0_1 + 0.386031746031746*G0_1_1_8_0_0 + 0.421587301587302*G0_1_1_8_0_1 - 0.106666666666666*G0_1_1_9_0_0 + 0.0761904761904756*G0_1_1_9_0_1 - 0.126984126984126*G0_1_1_10_1_0 - 0.126984126984126*G0_1_1_10_1_1 - 0.256507936507937*G0_1_1_11_1_0 + 0.0533333333333323*G0_1_1_13_1_0 - 0.421587301587302*G0_1_1_13_1_1 + 0.218412698412698*G0_1_1_14_1_1 + 0.0533333333333334*G0_1_1_15_1_0 + 0.345396825396824*G0_1_1_15_1_1 - 0.218412698412698*G0_1_1_16_1_1 - 0.00253968253968336*G0_1_1_17_1_0 - 0.294603174603174*G0_1_1_17_1_1 + 0.386031746031746*G0_1_1_18_1_0 + 0.421587301587302*G0_1_1_18_1_1 - 0.106666666666666*G0_1_1_19_1_0 + 0.0761904761904756*G0_1_1_19_1_1; + A[164] = A[629]; + A[871] = 0.0; + A[108] = 0.0; + A[193] = A[658]; + A[141] = 0.0; + A[593] = A[128]; + A[218] = A[683]; + A[616] = A[151]; + A[540] = 0.0; + A[496] = A[31]; + A[651] = A[186]; + A[539] = A[887] - 0.101587301587301*G0_0_1_0_0_0 - 0.101587301587302*G0_0_1_0_0_1 - 0.1015873015873*G0_0_1_1_0_0 + 0.266666666666661*G0_0_1_3_0_0 - 0.06984126984127*G0_0_1_3_0_1 + 0.234920634920636*G0_0_1_4_0_1 + 0.266666666666668*G0_0_1_5_0_0 + 0.336507936507937*G0_0_1_5_0_1 - 0.23492063492064*G0_0_1_6_0_1 + 0.101587301587301*G0_0_1_7_0_0 + 0.031746031746032*G0_0_1_7_0_1 + 0.1015873015873*G0_0_1_8_0_0 + 0.06984126984127*G0_0_1_8_0_1 - 0.533333333333329*G0_0_1_9_0_0 - 0.266666666666668*G0_0_1_9_0_1 - 0.101587301587301*G0_0_1_10_1_0 - 0.101587301587302*G0_0_1_10_1_1 - 0.1015873015873*G0_0_1_11_1_0 + 0.266666666666661*G0_0_1_13_1_0 - 0.06984126984127*G0_0_1_13_1_1 + 0.234920634920636*G0_0_1_14_1_1 + 0.266666666666668*G0_0_1_15_1_0 + 0.336507936507937*G0_0_1_15_1_1 - 0.23492063492064*G0_0_1_16_1_1 + 0.101587301587301*G0_0_1_17_1_0 + 0.031746031746032*G0_0_1_17_1_1 + 0.1015873015873*G0_0_1_18_1_0 + 0.06984126984127*G0_0_1_18_1_1 - 0.533333333333329*G0_0_1_19_1_0 - 0.266666666666668*G0_0_1_19_1_1 + 0.101587301587301*G0_1_0_0_0_0 + 0.101587301587302*G0_1_0_0_0_1 + 0.1015873015873*G0_1_0_1_0_0 - 0.266666666666661*G0_1_0_3_0_0 + 0.06984126984127*G0_1_0_3_0_1 - 0.234920634920636*G0_1_0_4_0_1 - 0.266666666666668*G0_1_0_5_0_0 - 0.336507936507937*G0_1_0_5_0_1 + 0.23492063492064*G0_1_0_6_0_1 - 0.101587301587301*G0_1_0_7_0_0 - 0.031746031746032*G0_1_0_7_0_1 - 0.1015873015873*G0_1_0_8_0_0 - 0.06984126984127*G0_1_0_8_0_1 + 0.533333333333329*G0_1_0_9_0_0 + 0.266666666666668*G0_1_0_9_0_1 + 0.101587301587301*G0_1_0_10_1_0 + 0.101587301587302*G0_1_0_10_1_1 + 0.1015873015873*G0_1_0_11_1_0 - 0.266666666666661*G0_1_0_13_1_0 + 0.06984126984127*G0_1_0_13_1_1 - 0.234920634920636*G0_1_0_14_1_1 - 0.266666666666668*G0_1_0_15_1_0 - 0.336507936507937*G0_1_0_15_1_1 + 0.23492063492064*G0_1_0_16_1_1 - 0.101587301587301*G0_1_0_17_1_0 - 0.031746031746032*G0_1_0_17_1_1 - 0.1015873015873*G0_1_0_18_1_0 - 0.06984126984127*G0_1_0_18_1_1 + 0.533333333333329*G0_1_0_19_1_0 + 0.266666666666668*G0_1_0_19_1_1; + A[686] = A[221]; + A[566] = A[101]; + A[693] = 0.0; + A[268] = 0.0; + A[295] = 0.0; + A[442] = 0.0; + A[362] = A[827]; + A[473] = A[8]; + A[393] = -A[401] + 0.921058201058195*G0_0_0_0_0_0 + 0.921058201058196*G0_0_0_0_0_1 - 0.880423280423276*G0_0_0_1_0_0 + 0.196402116402115*G0_0_0_2_0_1 - 2.74285714285713*G0_0_0_3_0_0 - 1.72698412698412*G0_0_0_3_0_1 - 1.76761904761904*G0_0_0_4_0_0 - 3.86031746031745*G0_0_0_4_0_1 + 2.25523809523808*G0_0_0_5_0_0 + 0.690793650793647*G0_0_0_5_0_1 + 1.76761904761904*G0_0_0_6_0_0 - 1.80825396825396*G0_0_0_6_0_1 - 2.58031746031745*G0_0_0_7_0_0 - 1.01587301587301*G0_0_0_7_0_1 + 2.53968253968253*G0_0_0_8_0_0 + 1.72698412698412*G0_0_0_8_0_1 + 0.487619047619055*G0_0_0_9_0_0 + 4.87619047619046*G0_0_0_9_0_1 + 0.921058201058195*G0_0_0_10_1_0 + 0.921058201058196*G0_0_0_10_1_1 - 0.880423280423276*G0_0_0_11_1_0 + 0.196402116402115*G0_0_0_12_1_1 - 2.74285714285713*G0_0_0_13_1_0 - 1.72698412698412*G0_0_0_13_1_1 - 1.76761904761904*G0_0_0_14_1_0 - 3.86031746031745*G0_0_0_14_1_1 + 2.25523809523808*G0_0_0_15_1_0 + 0.690793650793647*G0_0_0_15_1_1 + 1.76761904761904*G0_0_0_16_1_0 - 1.80825396825396*G0_0_0_16_1_1 - 2.58031746031745*G0_0_0_17_1_0 - 1.01587301587301*G0_0_0_17_1_1 + 2.53968253968253*G0_0_0_18_1_0 + 1.72698412698412*G0_0_0_18_1_1 + 0.487619047619055*G0_0_0_19_1_0 + 4.87619047619046*G0_0_0_19_1_1 + 1.11746031746031*G0_1_0_0_0_0 + 1.11746031746031*G0_1_0_0_0_1 + 1.11746031746031*G0_1_0_2_0_1 - 3.55555555555554*G0_1_0_3_0_0 - 0.203174603174611*G0_1_0_4_0_0 - 4.87619047619046*G0_1_0_4_0_1 - 1.32063492063492*G0_1_0_5_0_0 - 1.11746031746031*G0_1_0_5_0_1 + 0.203174603174609*G0_1_0_6_0_0 - 1.11746031746031*G0_1_0_6_0_1 - 4.67301587301585*G0_1_0_7_0_0 - 4.87619047619046*G0_1_0_7_0_1 + 3.55555555555555*G0_1_0_8_0_0 + 4.87619047619046*G0_1_0_9_0_0 + 9.75238095238092*G0_1_0_9_0_1 + 1.11746031746031*G0_1_0_10_1_0 + 1.11746031746031*G0_1_0_10_1_1 + 1.11746031746031*G0_1_0_12_1_1 - 3.55555555555554*G0_1_0_13_1_0 - 0.203174603174611*G0_1_0_14_1_0 - 4.87619047619046*G0_1_0_14_1_1 - 1.32063492063492*G0_1_0_15_1_0 - 1.11746031746031*G0_1_0_15_1_1 + 0.203174603174609*G0_1_0_16_1_0 - 1.11746031746031*G0_1_0_16_1_1 - 4.67301587301585*G0_1_0_17_1_0 - 4.87619047619046*G0_1_0_17_1_1 + 3.55555555555555*G0_1_0_18_1_0 + 4.87619047619046*G0_1_0_19_1_0 + 9.75238095238092*G0_1_0_19_1_1; + A[103] = A[393] + 0.386031746031744*G0_0_1_0_0_0 + 0.386031746031744*G0_0_1_0_0_1 + 1.42222222222221*G0_0_1_1_0_0 + 0.731428571428565*G0_0_1_2_0_1 - 2.43809523809523*G0_0_1_3_0_0 + 1.93015873015871*G0_0_1_3_0_1 - 0.182857142857148*G0_0_1_4_0_0 - 3.86031746031744*G0_0_1_4_0_1 - 0.975238095238094*G0_0_1_5_0_0 - 0.95492063492063*G0_0_1_5_0_1 + 0.182857142857147*G0_0_1_6_0_0 - 0.162539682539679*G0_0_1_6_0_1 - 0.995555555555553*G0_0_1_7_0_0 - 1.01587301587302*G0_0_1_7_0_1 - 0.812698412698399*G0_0_1_8_0_0 - 1.93015873015871*G0_0_1_8_0_1 + 3.41333333333332*G0_0_1_9_0_0 + 4.87619047619046*G0_0_1_9_0_1 + 0.386031746031744*G0_0_1_10_1_0 + 0.386031746031744*G0_0_1_10_1_1 + 1.42222222222221*G0_0_1_11_1_0 + 0.731428571428565*G0_0_1_12_1_1 - 2.43809523809523*G0_0_1_13_1_0 + 1.93015873015871*G0_0_1_13_1_1 - 0.182857142857148*G0_0_1_14_1_0 - 3.86031746031744*G0_0_1_14_1_1 - 0.975238095238094*G0_0_1_15_1_0 - 0.95492063492063*G0_0_1_15_1_1 + 0.182857142857147*G0_0_1_16_1_0 - 0.162539682539679*G0_0_1_16_1_1 - 0.995555555555553*G0_0_1_17_1_0 - 1.01587301587302*G0_0_1_17_1_1 - 0.812698412698399*G0_0_1_18_1_0 - 1.93015873015871*G0_0_1_18_1_1 + 3.41333333333332*G0_0_1_19_1_0 + 4.87619047619046*G0_0_1_19_1_1 - 0.386031746031744*G0_1_0_0_0_0 - 0.386031746031744*G0_1_0_0_0_1 - 1.42222222222221*G0_1_0_1_0_0 - 0.731428571428565*G0_1_0_2_0_1 + 2.43809523809523*G0_1_0_3_0_0 - 1.93015873015871*G0_1_0_3_0_1 + 0.182857142857148*G0_1_0_4_0_0 + 3.86031746031744*G0_1_0_4_0_1 + 0.975238095238094*G0_1_0_5_0_0 + 0.95492063492063*G0_1_0_5_0_1 - 0.182857142857147*G0_1_0_6_0_0 + 0.16253968253968*G0_1_0_6_0_1 + 0.995555555555553*G0_1_0_7_0_0 + 1.01587301587302*G0_1_0_7_0_1 + 0.812698412698399*G0_1_0_8_0_0 + 1.93015873015871*G0_1_0_8_0_1 - 3.41333333333332*G0_1_0_9_0_0 - 4.87619047619046*G0_1_0_9_0_1 - 0.386031746031744*G0_1_0_10_1_0 - 0.386031746031744*G0_1_0_10_1_1 - 1.42222222222221*G0_1_0_11_1_0 - 0.731428571428565*G0_1_0_12_1_1 + 2.43809523809523*G0_1_0_13_1_0 - 1.93015873015871*G0_1_0_13_1_1 + 0.182857142857148*G0_1_0_14_1_0 + 3.86031746031744*G0_1_0_14_1_1 + 0.975238095238094*G0_1_0_15_1_0 + 0.95492063492063*G0_1_0_15_1_1 - 0.182857142857147*G0_1_0_16_1_0 + 0.16253968253968*G0_1_0_16_1_1 + 0.995555555555553*G0_1_0_17_1_0 + 1.01587301587302*G0_1_0_17_1_1 + 0.812698412698399*G0_1_0_18_1_0 + 1.93015873015871*G0_1_0_18_1_1 - 3.41333333333332*G0_1_0_19_1_0 - 4.87619047619046*G0_1_0_19_1_1; + A[808] = -A[103] + 0.921058201058195*G0_0_0_0_0_0 + 0.921058201058195*G0_0_0_0_0_1 - 0.880423280423276*G0_0_0_1_0_0 + 0.196402116402115*G0_0_0_2_0_1 - 2.74285714285713*G0_0_0_3_0_0 - 1.72698412698412*G0_0_0_3_0_1 - 1.76761904761905*G0_0_0_4_0_0 - 3.86031746031745*G0_0_0_4_0_1 + 2.25523809523808*G0_0_0_5_0_0 + 0.690793650793647*G0_0_0_5_0_1 + 1.76761904761904*G0_0_0_6_0_0 - 1.80825396825396*G0_0_0_6_0_1 - 2.58031746031745*G0_0_0_7_0_0 - 1.01587301587301*G0_0_0_7_0_1 + 2.53968253968253*G0_0_0_8_0_0 + 1.72698412698412*G0_0_0_8_0_1 + 0.487619047619056*G0_0_0_9_0_0 + 4.87619047619046*G0_0_0_9_0_1 + 0.921058201058195*G0_0_0_10_1_0 + 0.921058201058195*G0_0_0_10_1_1 - 0.880423280423276*G0_0_0_11_1_0 + 0.196402116402115*G0_0_0_12_1_1 - 2.74285714285713*G0_0_0_13_1_0 - 1.72698412698412*G0_0_0_13_1_1 - 1.76761904761905*G0_0_0_14_1_0 - 3.86031746031745*G0_0_0_14_1_1 + 2.25523809523808*G0_0_0_15_1_0 + 0.690793650793647*G0_0_0_15_1_1 + 1.76761904761904*G0_0_0_16_1_0 - 1.80825396825396*G0_0_0_16_1_1 - 2.58031746031745*G0_0_0_17_1_0 - 1.01587301587301*G0_0_0_17_1_1 + 2.53968253968253*G0_0_0_18_1_0 + 1.72698412698412*G0_0_0_18_1_1 + 0.487619047619056*G0_0_0_19_1_0 + 4.87619047619046*G0_0_0_19_1_1 + 1.11746031746031*G0_0_1_0_0_0 + 1.11746031746031*G0_0_1_0_0_1 + 1.11746031746031*G0_0_1_2_0_1 - 3.55555555555554*G0_0_1_3_0_0 - 0.203174603174611*G0_0_1_4_0_0 - 4.87619047619046*G0_0_1_4_0_1 - 1.32063492063492*G0_0_1_5_0_0 - 1.11746031746031*G0_0_1_5_0_1 + 0.20317460317461*G0_0_1_6_0_0 - 1.11746031746031*G0_0_1_6_0_1 - 4.67301587301585*G0_0_1_7_0_0 - 4.87619047619046*G0_0_1_7_0_1 + 3.55555555555555*G0_0_1_8_0_0 + 4.87619047619046*G0_0_1_9_0_0 + 9.75238095238092*G0_0_1_9_0_1 + 1.11746031746031*G0_0_1_10_1_0 + 1.11746031746031*G0_0_1_10_1_1 + 1.11746031746031*G0_0_1_12_1_1 - 3.55555555555554*G0_0_1_13_1_0 - 0.203174603174611*G0_0_1_14_1_0 - 4.87619047619046*G0_0_1_14_1_1 - 1.32063492063492*G0_0_1_15_1_0 - 1.11746031746031*G0_0_1_15_1_1 + 0.20317460317461*G0_0_1_16_1_0 - 1.11746031746031*G0_0_1_16_1_1 - 4.67301587301585*G0_0_1_17_1_0 - 4.87619047619046*G0_0_1_17_1_1 + 3.55555555555555*G0_0_1_18_1_0 + 4.87619047619046*G0_0_1_19_1_0 + 9.75238095238092*G0_0_1_19_1_1; + A[568] = A[103]; + A[809] = A[344]; + A[24] = 0.0; + A[725] = 0.0; + A[384] = 0.0; + A[826] = A[361]; + A[35] = A[500]; + A[750] = 0.0; + A[419] = 0.0; + A[867] = A[402]; + A[62] = A[527]; + A[787] = 0.0; + A[896] = A[431]; + A[117] = 0.0; + A[184] = A[126] + 0.0203174603174641*G0_0_1_0_0_0 + 0.0203174603174639*G0_0_1_0_0_1 - 0.132063492063493*G0_0_1_1_0_0 - 0.0152380952380974*G0_0_1_2_0_1 + 0.0761904761904703*G0_0_1_3_0_0 - 0.19555555555556*G0_0_1_3_0_1 + 0.060952380952378*G0_0_1_4_0_0 + 0.215873015873012*G0_0_1_4_0_1 + 0.0457142857142804*G0_0_1_5_0_0 + 0.0126984126984037*G0_0_1_5_0_1 - 0.060952380952378*G0_0_1_6_0_0 - 0.0177777777777703*G0_0_1_6_0_1 - 0.0812698412698458*G0_0_1_7_0_0 - 0.0482539682539693*G0_0_1_7_0_1 + 0.193015873015875*G0_0_1_8_0_0 + 0.19555555555556*G0_0_1_8_0_1 - 0.12190476190475*G0_0_1_9_0_0 - 0.167619047619043*G0_0_1_9_0_1 + 0.0203174603174641*G0_0_1_10_1_0 + 0.0203174603174639*G0_0_1_10_1_1 - 0.132063492063493*G0_0_1_11_1_0 - 0.0152380952380974*G0_0_1_12_1_1 + 0.0761904761904703*G0_0_1_13_1_0 - 0.19555555555556*G0_0_1_13_1_1 + 0.060952380952378*G0_0_1_14_1_0 + 0.215873015873012*G0_0_1_14_1_1 + 0.0457142857142804*G0_0_1_15_1_0 + 0.0126984126984037*G0_0_1_15_1_1 - 0.060952380952378*G0_0_1_16_1_0 - 0.0177777777777703*G0_0_1_16_1_1 - 0.0812698412698458*G0_0_1_17_1_0 - 0.0482539682539693*G0_0_1_17_1_1 + 0.193015873015875*G0_0_1_18_1_0 + 0.19555555555556*G0_0_1_18_1_1 - 0.12190476190475*G0_0_1_19_1_0 - 0.167619047619043*G0_0_1_19_1_1 - 0.020317460317464*G0_1_0_0_0_0 - 0.0203174603174639*G0_1_0_0_0_1 + 0.132063492063493*G0_1_0_1_0_0 + 0.0152380952380974*G0_1_0_2_0_1 - 0.0761904761904704*G0_1_0_3_0_0 + 0.19555555555556*G0_1_0_3_0_1 - 0.0609523809523781*G0_1_0_4_0_0 - 0.215873015873012*G0_1_0_4_0_1 - 0.0457142857142805*G0_1_0_5_0_0 - 0.0126984126984036*G0_1_0_5_0_1 + 0.0609523809523781*G0_1_0_6_0_0 + 0.0177777777777702*G0_1_0_6_0_1 + 0.0812698412698457*G0_1_0_7_0_0 + 0.0482539682539693*G0_1_0_7_0_1 - 0.193015873015875*G0_1_0_8_0_0 - 0.19555555555556*G0_1_0_8_0_1 + 0.121904761904751*G0_1_0_9_0_0 + 0.167619047619043*G0_1_0_9_0_1 - 0.020317460317464*G0_1_0_10_1_0 - 0.0203174603174639*G0_1_0_10_1_1 + 0.132063492063493*G0_1_0_11_1_0 + 0.0152380952380974*G0_1_0_12_1_1 - 0.0761904761904704*G0_1_0_13_1_0 + 0.19555555555556*G0_1_0_13_1_1 - 0.0609523809523781*G0_1_0_14_1_0 - 0.215873015873012*G0_1_0_14_1_1 - 0.0457142857142805*G0_1_0_15_1_0 - 0.0126984126984036*G0_1_0_15_1_1 + 0.0609523809523781*G0_1_0_16_1_0 + 0.0177777777777702*G0_1_0_16_1_1 + 0.0812698412698457*G0_1_0_17_1_0 + 0.0482539682539693*G0_1_0_17_1_1 - 0.193015873015875*G0_1_0_18_1_0 - 0.19555555555556*G0_1_0_18_1_1 + 0.121904761904751*G0_1_0_19_1_0 + 0.167619047619043*G0_1_0_19_1_1; + A[192] = A[184] + 2.57523809523808*G0_0_0_0_0_0 + 2.57523809523808*G0_0_0_0_0_1 - 1.14285714285714*G0_0_0_1_0_0 - 0.0304761904761853*G0_0_0_2_0_1 + 1.03619047619047*G0_0_0_3_0_0 - 1.02095238095237*G0_0_0_4_0_0 - 1.09714285714285*G0_0_0_4_0_1 + 5.54666666666665*G0_0_0_5_0_0 - 0.609523809523799*G0_0_0_5_0_1 + 1.02095238095237*G0_0_0_6_0_0 - 1.9352380952381*G0_0_0_6_0_1 - 4.96761904761902*G0_0_0_7_0_0 + 1.18857142857142*G0_0_0_7_0_1 + 3.53523809523808*G0_0_0_8_0_0 - 6.58285714285712*G0_0_0_9_0_0 - 0.0914285714285707*G0_0_0_9_0_1 + 2.57523809523808*G0_0_0_10_1_0 + 2.57523809523808*G0_0_0_10_1_1 - 1.14285714285714*G0_0_0_11_1_0 - 0.0304761904761853*G0_0_0_12_1_1 + 1.03619047619047*G0_0_0_13_1_0 - 1.02095238095237*G0_0_0_14_1_0 - 1.09714285714285*G0_0_0_14_1_1 + 5.54666666666665*G0_0_0_15_1_0 - 0.609523809523799*G0_0_0_15_1_1 + 1.02095238095237*G0_0_0_16_1_0 - 1.9352380952381*G0_0_0_16_1_1 - 4.96761904761902*G0_0_0_17_1_0 + 1.18857142857142*G0_0_0_17_1_1 + 3.53523809523808*G0_0_0_18_1_0 - 6.58285714285712*G0_0_0_19_1_0 - 0.0914285714285707*G0_0_0_19_1_1 + 1.01841269841269*G0_0_1_0_0_0 + 1.01841269841269*G0_0_1_0_0_1 + 0.124444444444444*G0_0_1_1_0_0 - 0.698412698412692*G0_0_1_2_0_1 - 0.68571428571428*G0_0_1_3_0_0 + 0.0228571428571446*G0_0_1_3_0_1 - 1.25714285714285*G0_0_1_4_0_0 - 1.14285714285714*G0_0_1_4_0_1 - 1.91999999999998*G0_0_1_5_0_1 + 1.25714285714285*G0_0_1_6_0_0 + 1.59999999999998*G0_0_1_6_0_1 - 0.731428571428565*G0_0_1_7_0_0 + 1.18857142857142*G0_0_1_7_0_1 - 0.411428571428568*G0_0_1_8_0_0 - 0.0228571428571451*G0_0_1_8_0_1 + 0.685714285714274*G0_0_1_9_0_0 - 0.0457142857142807*G0_0_1_9_0_1 + 1.01841269841269*G0_0_1_10_1_0 + 1.01841269841269*G0_0_1_10_1_1 + 0.124444444444444*G0_0_1_11_1_0 - 0.698412698412692*G0_0_1_12_1_1 - 0.68571428571428*G0_0_1_13_1_0 + 0.0228571428571446*G0_0_1_13_1_1 - 1.25714285714285*G0_0_1_14_1_0 - 1.14285714285714*G0_0_1_14_1_1 - 1.91999999999998*G0_0_1_15_1_1 + 1.25714285714285*G0_0_1_16_1_0 + 1.59999999999998*G0_0_1_16_1_1 - 0.731428571428565*G0_0_1_17_1_0 + 1.18857142857142*G0_0_1_17_1_1 - 0.411428571428568*G0_0_1_18_1_0 - 0.0228571428571451*G0_0_1_18_1_1 + 0.685714285714274*G0_0_1_19_1_0 - 0.0457142857142807*G0_0_1_19_1_1 - 0.383492063492055*G0_1_0_0_0_0 - 0.383492063492056*G0_1_0_0_0_1 - 0.393650793650793*G0_1_0_1_0_0 + 0.0177777777777772*G0_1_0_2_0_1 + 0.365714285714283*G0_1_0_3_0_0 - 0.152380952380951*G0_1_0_3_0_1 - 1.37904761904761*G0_1_0_4_0_0 - 1.27238095238095*G0_1_0_4_0_1 + 2.48380952380952*G0_1_0_5_0_0 + 2.46095238095236*G0_1_0_5_0_1 + 1.37904761904761*G0_1_0_6_0_0 - 2.09523809523808*G0_1_0_6_0_1 + 0.0228571428571464*G0_1_0_7_0_1 + 0.777142857142858*G0_1_0_8_0_0 + 0.15238095238095*G0_1_0_8_0_1 - 2.8495238095238*G0_1_0_9_0_0 + 1.2495238095238*G0_1_0_9_0_1 - 0.383492063492055*G0_1_0_10_1_0 - 0.383492063492056*G0_1_0_10_1_1 - 0.393650793650793*G0_1_0_11_1_0 + 0.0177777777777772*G0_1_0_12_1_1 + 0.365714285714283*G0_1_0_13_1_0 - 0.152380952380951*G0_1_0_13_1_1 - 1.37904761904761*G0_1_0_14_1_0 - 1.27238095238095*G0_1_0_14_1_1 + 2.48380952380952*G0_1_0_15_1_0 + 2.46095238095236*G0_1_0_15_1_1 + 1.37904761904761*G0_1_0_16_1_0 - 2.09523809523808*G0_1_0_16_1_1 + 0.0228571428571464*G0_1_0_17_1_1 + 0.777142857142858*G0_1_0_18_1_0 + 0.15238095238095*G0_1_0_18_1_1 - 2.8495238095238*G0_1_0_19_1_0 + 1.2495238095238*G0_1_0_19_1_1 - 1.94031746031745*G0_1_1_0_0_0 - 1.94031746031745*G0_1_1_0_0_1 + 0.172698412698411*G0_1_1_1_0_0 + 0.0507936507936506*G0_1_1_2_0_1 - 0.860952380952375*G0_1_1_3_0_0 - 0.33523809523809*G0_1_1_3_0_1 - 1.4095238095238*G0_1_1_4_0_0 - 1.81333333333333*G0_1_1_4_0_1 - 1.16571428571427*G0_1_1_5_0_0 + 3.04761904761903*G0_1_1_5_0_1 + 1.4095238095238*G0_1_1_6_0_0 - 1.15809523809523*G0_1_1_6_0_1 + 2.3390476190476*G0_1_1_7_0_0 - 1.8742857142857*G0_1_1_7_0_1 - 0.571428571428564*G0_1_1_8_0_0 + 0.33523809523809*G0_1_1_8_0_1 + 2.02666666666665*G0_1_1_9_0_0 + 3.68761904761903*G0_1_1_9_0_1 - 1.94031746031745*G0_1_1_10_1_0 - 1.94031746031745*G0_1_1_10_1_1 + 0.172698412698411*G0_1_1_11_1_0 + 0.0507936507936506*G0_1_1_12_1_1 - 0.860952380952375*G0_1_1_13_1_0 - 0.33523809523809*G0_1_1_13_1_1 - 1.4095238095238*G0_1_1_14_1_0 - 1.81333333333333*G0_1_1_14_1_1 - 1.16571428571427*G0_1_1_15_1_0 + 3.04761904761903*G0_1_1_15_1_1 + 1.4095238095238*G0_1_1_16_1_0 - 1.15809523809523*G0_1_1_16_1_1 + 2.3390476190476*G0_1_1_17_1_0 - 1.8742857142857*G0_1_1_17_1_1 - 0.571428571428564*G0_1_1_18_1_0 + 0.33523809523809*G0_1_1_18_1_1 + 2.02666666666665*G0_1_1_19_1_0 + 3.68761904761903*G0_1_1_19_1_1; + A[366] = A[192] - 1.42222222222221*G0_0_1_0_0_0 - 1.42222222222221*G0_0_1_0_0_1 - 0.386031746031744*G0_0_1_1_0_0 + 0.731428571428566*G0_0_1_2_0_1 + 0.975238095238093*G0_0_1_3_0_0 + 0.0203174603174642*G0_0_1_3_0_1 - 0.182857142857141*G0_0_1_4_0_0 - 0.34539682539682*G0_0_1_4_0_1 + 2.43809523809523*G0_0_1_5_0_0 + 4.36825396825394*G0_0_1_5_0_1 + 0.182857142857141*G0_0_1_6_0_0 - 3.6774603174603*G0_0_1_6_0_1 + 0.812698412698401*G0_0_1_7_0_0 - 1.11746031746031*G0_0_1_7_0_1 + 0.995555555555552*G0_0_1_8_0_0 - 0.0203174603174646*G0_0_1_8_0_1 - 3.41333333333333*G0_0_1_9_0_0 + 1.46285714285713*G0_0_1_9_0_1 - 1.42222222222221*G0_0_1_10_1_0 - 1.42222222222221*G0_0_1_10_1_1 - 0.386031746031744*G0_0_1_11_1_0 + 0.731428571428566*G0_0_1_12_1_1 + 0.975238095238093*G0_0_1_13_1_0 + 0.0203174603174642*G0_0_1_13_1_1 - 0.182857142857141*G0_0_1_14_1_0 - 0.34539682539682*G0_0_1_14_1_1 + 2.43809523809523*G0_0_1_15_1_0 + 4.36825396825394*G0_0_1_15_1_1 + 0.182857142857141*G0_0_1_16_1_0 - 3.6774603174603*G0_0_1_16_1_1 + 0.812698412698401*G0_0_1_17_1_0 - 1.11746031746031*G0_0_1_17_1_1 + 0.995555555555552*G0_0_1_18_1_0 - 0.0203174603174646*G0_0_1_18_1_1 - 3.41333333333333*G0_0_1_19_1_0 + 1.46285714285713*G0_0_1_19_1_1 + 1.42222222222221*G0_1_0_0_0_0 + 1.42222222222221*G0_1_0_0_0_1 + 0.386031746031744*G0_1_0_1_0_0 - 0.731428571428566*G0_1_0_2_0_1 - 0.975238095238093*G0_1_0_3_0_0 - 0.0203174603174642*G0_1_0_3_0_1 + 0.182857142857141*G0_1_0_4_0_0 + 0.34539682539682*G0_1_0_4_0_1 - 2.43809523809523*G0_1_0_5_0_0 - 4.36825396825394*G0_1_0_5_0_1 - 0.182857142857141*G0_1_0_6_0_0 + 3.6774603174603*G0_1_0_6_0_1 - 0.812698412698401*G0_1_0_7_0_0 + 1.1174603174603*G0_1_0_7_0_1 - 0.995555555555552*G0_1_0_8_0_0 + 0.0203174603174646*G0_1_0_8_0_1 + 3.41333333333332*G0_1_0_9_0_0 - 1.46285714285713*G0_1_0_9_0_1 + 1.42222222222221*G0_1_0_10_1_0 + 1.42222222222221*G0_1_0_10_1_1 + 0.386031746031744*G0_1_0_11_1_0 - 0.731428571428566*G0_1_0_12_1_1 - 0.975238095238093*G0_1_0_13_1_0 - 0.0203174603174642*G0_1_0_13_1_1 + 0.182857142857141*G0_1_0_14_1_0 + 0.34539682539682*G0_1_0_14_1_1 - 2.43809523809523*G0_1_0_15_1_0 - 4.36825396825394*G0_1_0_15_1_1 - 0.182857142857141*G0_1_0_16_1_0 + 3.6774603174603*G0_1_0_16_1_1 - 0.812698412698401*G0_1_0_17_1_0 + 1.1174603174603*G0_1_0_17_1_1 - 0.995555555555552*G0_1_0_18_1_0 + 0.0203174603174646*G0_1_0_18_1_1 + 3.41333333333332*G0_1_0_19_1_0 - 1.46285714285713*G0_1_0_19_1_1; + A[831] = A[366]; + A[657] = A[192]; + A[148] = 0.0; + A[598] = A[133]; + A[211] = A[676]; + A[167] = 0.0; + A[503] = A[38]; + A[572] = 0.0; + A[532] = A[67]; + A[689] = A[224]; + A[605] = 0.0; + A[561] = A[96]; + A[714] = A[249]; + A[243] = A[708]; + A[272] = A[737]; + A[445] = 0.0; + A[325] = 0.0; + A[478] = A[13]; + A[350] = 0.0; + A[732] = 0.0; + A[423] = A[888]; + A[383] = 0.0; + A[759] = 0.0; + A[412] = 0.0; + A[858] = A[393]; + A[89] = 0.0; + A[794] = 0.0; + A[889] = A[424]; + A[90] = A[555]; + A[825] = A[360]; + A[147] = 0.0; + A[848] = 0.0; + A[176] = 0.0; + A[883] = 0.0; + A[494] = 0.0; + A[197] = 0.0; + A[581] = 0.0; + A[525] = -A[61] - 0.12095238095238*G0_1_0_0_0_0 - 0.12095238095238*G0_1_0_0_0_1 - 0.120952380952381*G0_1_0_1_0_0 + 0.0561904761904756*G0_1_0_3_0_0 - 0.213809523809524*G0_1_0_3_0_1 + 0.149047619047619*G0_1_0_4_0_1 + 0.0561904761904757*G0_1_0_5_0_0 + 0.269999999999999*G0_1_0_5_0_1 - 0.149047619047618*G0_1_0_6_0_1 + 0.12095238095238*G0_1_0_7_0_0 - 0.092857142857143*G0_1_0_7_0_1 + 0.120952380952381*G0_1_0_8_0_0 + 0.213809523809524*G0_1_0_8_0_1 - 0.112380952380951*G0_1_0_9_0_0 - 0.0561904761904757*G0_1_0_9_0_1 - 0.12095238095238*G0_1_0_10_1_0 - 0.12095238095238*G0_1_0_10_1_1 - 0.120952380952381*G0_1_0_11_1_0 + 0.0561904761904756*G0_1_0_13_1_0 - 0.213809523809524*G0_1_0_13_1_1 + 0.149047619047619*G0_1_0_14_1_1 + 0.0561904761904757*G0_1_0_15_1_0 + 0.269999999999999*G0_1_0_15_1_1 - 0.149047619047618*G0_1_0_16_1_1 + 0.12095238095238*G0_1_0_17_1_0 - 0.092857142857143*G0_1_0_17_1_1 + 0.120952380952381*G0_1_0_18_1_0 + 0.213809523809524*G0_1_0_18_1_1 - 0.112380952380951*G0_1_0_19_1_0 - 0.0561904761904757*G0_1_0_19_1_1 - 0.137962962962963*G0_1_1_0_0_0 - 0.137962962962963*G0_1_1_0_0_1 + 0.017010582010582*G0_1_1_1_0_0 + 0.137962962962963*G0_1_1_2_0_1 - 0.0532539682539688*G0_1_1_3_0_0 - 0.0165873015873017*G0_1_1_3_0_1 + 0.197222222222223*G0_1_1_4_0_0 + 0.0396031746031749*G0_1_1_4_0_1 + 0.109444444444445*G0_1_1_5_0_0 + 0.306666666666666*G0_1_1_5_0_1 - 0.197222222222223*G0_1_1_6_0_0 - 0.306666666666667*G0_1_1_6_0_1 + 0.157619047619047*G0_1_1_7_0_0 - 0.0396031746031744*G0_1_1_7_0_1 - 0.0366666666666664*G0_1_1_8_0_0 + 0.0165873015873017*G0_1_1_8_0_1 - 0.0561904761904758*G0_1_1_9_0_0 - 0.137962962962963*G0_1_1_10_1_0 - 0.137962962962963*G0_1_1_10_1_1 + 0.017010582010582*G0_1_1_11_1_0 + 0.137962962962963*G0_1_1_12_1_1 - 0.0532539682539688*G0_1_1_13_1_0 - 0.0165873015873017*G0_1_1_13_1_1 + 0.197222222222223*G0_1_1_14_1_0 + 0.0396031746031749*G0_1_1_14_1_1 + 0.109444444444445*G0_1_1_15_1_0 + 0.306666666666666*G0_1_1_15_1_1 - 0.197222222222223*G0_1_1_16_1_0 - 0.306666666666667*G0_1_1_16_1_1 + 0.157619047619047*G0_1_1_17_1_0 - 0.0396031746031744*G0_1_1_17_1_1 - 0.0366666666666664*G0_1_1_18_1_0 + 0.0165873015873017*G0_1_1_18_1_1 - 0.0561904761904758*G0_1_1_19_1_0; + A[230] = 0.0; + A[680] = A[215]; + A[612] = 0.0; + A[552] = 0.0; + A[707] = A[242]; + A[631] = 0.0; + A[250] = A[715]; + A[674] = 0.0; + A[281] = A[804] + 0.135449735449735*G0_0_1_0_0_0 + 0.135449735449735*G0_0_1_0_0_1 - 0.135449735449732*G0_0_1_1_0_0 - 0.196402116402115*G0_0_1_2_0_1 - 0.345396825396822*G0_0_1_3_0_0 - 0.711111111111102*G0_0_1_3_0_1 + 0.142222222222222*G0_0_1_4_0_0 + 0.568888888888885*G0_0_1_4_0_1 + 0.345396825396825*G0_0_1_5_0_0 - 0.365714285714284*G0_0_1_5_0_1 - 0.142222222222222*G0_0_1_6_0_0 + 0.426666666666664*G0_0_1_6_0_1 + 0.670476190476188*G0_0_1_7_0_0 + 1.3815873015873*G0_0_1_7_0_1 - 0.670476190476191*G0_0_1_8_0_0 + 0.711111111111102*G0_0_1_8_0_1 - 1.95047619047618*G0_0_1_9_0_1 + 0.135449735449735*G0_0_1_10_1_0 + 0.135449735449735*G0_0_1_10_1_1 - 0.135449735449732*G0_0_1_11_1_0 - 0.196402116402115*G0_0_1_12_1_1 - 0.345396825396822*G0_0_1_13_1_0 - 0.711111111111102*G0_0_1_13_1_1 + 0.142222222222222*G0_0_1_14_1_0 + 0.568888888888885*G0_0_1_14_1_1 + 0.345396825396825*G0_0_1_15_1_0 - 0.365714285714284*G0_0_1_15_1_1 - 0.142222222222222*G0_0_1_16_1_0 + 0.426666666666664*G0_0_1_16_1_1 + 0.670476190476188*G0_0_1_17_1_0 + 1.3815873015873*G0_0_1_17_1_1 - 0.670476190476191*G0_0_1_18_1_0 + 0.711111111111102*G0_0_1_18_1_1 - 1.95047619047618*G0_0_1_19_1_1 - 0.135449735449735*G0_1_0_0_0_0 - 0.135449735449735*G0_1_0_0_0_1 + 0.135449735449732*G0_1_0_1_0_0 + 0.196402116402115*G0_1_0_2_0_1 + 0.345396825396822*G0_1_0_3_0_0 + 0.711111111111103*G0_1_0_3_0_1 - 0.142222222222222*G0_1_0_4_0_0 - 0.568888888888885*G0_1_0_4_0_1 - 0.345396825396825*G0_1_0_5_0_0 + 0.365714285714284*G0_1_0_5_0_1 + 0.142222222222222*G0_1_0_6_0_0 - 0.426666666666664*G0_1_0_6_0_1 - 0.670476190476188*G0_1_0_7_0_0 - 1.3815873015873*G0_1_0_7_0_1 + 0.670476190476191*G0_1_0_8_0_0 - 0.711111111111102*G0_1_0_8_0_1 + 1.95047619047618*G0_1_0_9_0_1 - 0.135449735449735*G0_1_0_10_1_0 - 0.135449735449735*G0_1_0_10_1_1 + 0.135449735449732*G0_1_0_11_1_0 + 0.196402116402115*G0_1_0_12_1_1 + 0.345396825396822*G0_1_0_13_1_0 + 0.711111111111103*G0_1_0_13_1_1 - 0.142222222222222*G0_1_0_14_1_0 - 0.568888888888885*G0_1_0_14_1_1 - 0.345396825396825*G0_1_0_15_1_0 + 0.365714285714284*G0_1_0_15_1_1 + 0.142222222222222*G0_1_0_16_1_0 - 0.426666666666664*G0_1_0_16_1_1 - 0.670476190476188*G0_1_0_17_1_0 - 1.3815873015873*G0_1_0_17_1_1 + 0.670476190476191*G0_1_0_18_1_0 - 0.711111111111102*G0_1_0_18_1_1 + 1.95047619047618*G0_1_0_19_1_1; + A[273] = -A[281] - 1.46962962962963*G0_0_0_0_0_0 - 1.46962962962963*G0_0_0_0_0_1 + 1.08359788359788*G0_0_0_1_0_0 + 0.331851851851851*G0_0_0_2_0_1 - 0.182857142857142*G0_0_0_3_0_0 + 1.47301587301587*G0_0_0_3_0_1 - 0.243809523809524*G0_0_0_4_0_0 - 1.14793650793651*G0_0_0_4_0_1 - 1.27999999999999*G0_0_0_5_0_0 + 1.69650793650794*G0_0_0_5_0_1 + 0.243809523809524*G0_0_0_6_0_0 - 0.55873015873016*G0_0_0_6_0_1 + 2.23492063492063*G0_0_0_7_0_0 - 0.741587301587299*G0_0_0_7_0_1 - 1.84888888888888*G0_0_0_8_0_0 - 1.47301587301587*G0_0_0_8_0_1 + 1.46285714285714*G0_0_0_9_0_0 + 1.8895238095238*G0_0_0_9_0_1 - 1.46962962962963*G0_0_0_10_1_0 - 1.46962962962963*G0_0_0_10_1_1 + 1.08359788359788*G0_0_0_11_1_0 + 0.331851851851851*G0_0_0_12_1_1 - 0.182857142857142*G0_0_0_13_1_0 + 1.47301587301587*G0_0_0_13_1_1 - 0.243809523809524*G0_0_0_14_1_0 - 1.14793650793651*G0_0_0_14_1_1 - 1.27999999999999*G0_0_0_15_1_0 + 1.69650793650794*G0_0_0_15_1_1 + 0.243809523809524*G0_0_0_16_1_0 - 0.55873015873016*G0_0_0_16_1_1 + 2.23492063492063*G0_0_0_17_1_0 - 0.741587301587299*G0_0_0_17_1_1 - 1.84888888888888*G0_0_0_18_1_0 - 1.47301587301587*G0_0_0_18_1_1 + 1.46285714285714*G0_0_0_19_1_0 + 1.8895238095238*G0_0_0_19_1_1 - 0.115132275132274*G0_1_0_0_0_0 - 0.115132275132274*G0_1_0_0_0_1 + 0.643386243386241*G0_1_0_1_0_0 + 0.318306878306877*G0_1_0_2_0_1 - 0.0507936507936524*G0_1_0_3_0_0 + 1.42222222222221*G0_1_0_3_0_1 - 0.172698412698412*G0_1_0_4_0_0 - 1.32063492063492*G0_1_0_4_0_1 - 0.497777777777777*G0_1_0_5_0_0 + 0.142222222222219*G0_1_0_5_0_1 + 0.172698412698412*G0_1_0_6_0_0 - 0.345396825396822*G0_1_0_6_0_1 - 0.477460317460316*G0_1_0_7_0_0 - 1.11746031746031*G0_1_0_7_0_1 - 0.0507936507936495*G0_1_0_8_0_0 - 1.42222222222221*G0_1_0_8_0_1 + 0.548571428571429*G0_1_0_9_0_0 + 2.43809523809523*G0_1_0_9_0_1 - 0.115132275132274*G0_1_0_10_1_0 - 0.115132275132274*G0_1_0_10_1_1 + 0.643386243386241*G0_1_0_11_1_0 + 0.318306878306877*G0_1_0_12_1_1 - 0.0507936507936524*G0_1_0_13_1_0 + 1.42222222222221*G0_1_0_13_1_1 - 0.172698412698412*G0_1_0_14_1_0 - 1.32063492063492*G0_1_0_14_1_1 - 0.497777777777777*G0_1_0_15_1_0 + 0.142222222222219*G0_1_0_15_1_1 + 0.172698412698412*G0_1_0_16_1_0 - 0.345396825396822*G0_1_0_16_1_1 - 0.477460317460316*G0_1_0_17_1_0 - 1.11746031746031*G0_1_0_17_1_1 - 0.0507936507936495*G0_1_0_18_1_0 - 1.42222222222221*G0_1_0_18_1_1 + 0.548571428571429*G0_1_0_19_1_0 + 2.43809523809523*G0_1_0_19_1_1; + A[621] = A[273] + 0.284444444444443*G0_0_0_0_0_0 + 0.284444444444444*G0_0_0_0_0_1 + 0.507936507936505*G0_0_0_1_0_0 - 1.44253968253967*G0_0_0_2_0_1 + 1.36126984126983*G0_0_0_3_0_0 + 1.26984126984126*G0_0_0_3_0_1 - 2.35682539682538*G0_0_0_4_0_0 - 0.314920634920632*G0_0_0_4_0_1 - 1.11746031746031*G0_0_0_5_0_0 - 1.55428571428571*G0_0_0_5_0_1 + 2.35682539682538*G0_0_0_6_0_0 + 2.71238095238093*G0_0_0_6_0_1 + 0.670476190476185*G0_0_0_7_0_0 + 1.10730158730158*G0_0_0_7_0_1 - 1.46285714285713*G0_0_0_8_0_0 - 1.26984126984126*G0_0_0_8_0_1 - 0.243809523809519*G0_0_0_9_0_0 - 0.792380952380948*G0_0_0_9_0_1 + 0.284444444444443*G0_0_0_10_1_0 + 0.284444444444444*G0_0_0_10_1_1 + 0.507936507936505*G0_0_0_11_1_0 - 1.44253968253967*G0_0_0_12_1_1 + 1.36126984126983*G0_0_0_13_1_0 + 1.26984126984126*G0_0_0_13_1_1 - 2.35682539682538*G0_0_0_14_1_0 - 0.314920634920632*G0_0_0_14_1_1 - 1.11746031746031*G0_0_0_15_1_0 - 1.55428571428571*G0_0_0_15_1_1 + 2.35682539682538*G0_0_0_16_1_0 + 2.71238095238093*G0_0_0_16_1_1 + 0.670476190476185*G0_0_0_17_1_0 + 1.10730158730158*G0_0_0_17_1_1 - 1.46285714285713*G0_0_0_18_1_0 - 1.26984126984126*G0_0_0_18_1_1 - 0.243809523809519*G0_0_0_19_1_0 - 0.792380952380948*G0_0_0_19_1_1 + 1.17841269841269*G0_0_1_1_0_0 - 1.17841269841269*G0_0_1_2_0_1 + 0.96507936507936*G0_0_1_3_0_0 + 2.14349206349205*G0_0_1_3_0_1 - 2.14349206349205*G0_0_1_4_0_0 - 0.965079365079361*G0_0_1_4_0_1 - 1.39174603174603*G0_0_1_5_0_0 - 1.39174603174603*G0_0_1_5_0_1 + 2.14349206349205*G0_0_1_6_0_0 + 2.57015873015872*G0_0_1_6_0_1 + 1.39174603174602*G0_0_1_7_0_0 + 1.39174603174603*G0_0_1_7_0_1 - 2.57015873015872*G0_0_1_8_0_0 - 2.14349206349206*G0_0_1_8_0_1 + 0.426666666666666*G0_0_1_9_0_0 - 0.426666666666664*G0_0_1_9_0_1 + 1.17841269841269*G0_0_1_11_1_0 - 1.17841269841269*G0_0_1_12_1_1 + 0.96507936507936*G0_0_1_13_1_0 + 2.14349206349205*G0_0_1_13_1_1 - 2.14349206349205*G0_0_1_14_1_0 - 0.965079365079361*G0_0_1_14_1_1 - 1.39174603174603*G0_0_1_15_1_0 - 1.39174603174603*G0_0_1_15_1_1 + 2.14349206349205*G0_0_1_16_1_0 + 2.57015873015872*G0_0_1_16_1_1 + 1.39174603174602*G0_0_1_17_1_0 + 1.39174603174603*G0_0_1_17_1_1 - 2.57015873015872*G0_0_1_18_1_0 - 2.14349206349206*G0_0_1_18_1_1 + 0.426666666666666*G0_0_1_19_1_0 - 0.426666666666664*G0_0_1_19_1_1 + 0.792380952380948*G0_1_0_1_0_0 - 0.792380952380947*G0_1_0_2_0_1 + 0.609523809523807*G0_1_0_3_0_0 + 1.40190476190475*G0_1_0_3_0_1 - 1.40190476190475*G0_1_0_4_0_0 - 0.609523809523804*G0_1_0_4_0_1 - 0.975238095238088*G0_1_0_5_0_0 - 0.975238095238088*G0_1_0_5_0_1 + 1.40190476190475*G0_1_0_6_0_0 + 1.76761904761904*G0_1_0_6_0_1 + 0.975238095238089*G0_1_0_7_0_0 + 0.97523809523809*G0_1_0_7_0_1 - 1.76761904761904*G0_1_0_8_0_0 - 1.40190476190476*G0_1_0_8_0_1 + 0.365714285714281*G0_1_0_9_0_0 - 0.365714285714284*G0_1_0_9_0_1 + 0.792380952380948*G0_1_0_11_1_0 - 0.792380952380947*G0_1_0_12_1_1 + 0.609523809523807*G0_1_0_13_1_0 + 1.40190476190475*G0_1_0_13_1_1 - 1.40190476190475*G0_1_0_14_1_0 - 0.609523809523804*G0_1_0_14_1_1 - 0.975238095238088*G0_1_0_15_1_0 - 0.975238095238088*G0_1_0_15_1_1 + 1.40190476190475*G0_1_0_16_1_0 + 1.76761904761904*G0_1_0_16_1_1 + 0.975238095238089*G0_1_0_17_1_0 + 0.97523809523809*G0_1_0_17_1_1 - 1.76761904761904*G0_1_0_18_1_0 - 1.40190476190476*G0_1_0_18_1_1 + 0.365714285714281*G0_1_0_19_1_0 - 0.365714285714284*G0_1_0_19_1_1 - 0.284444444444442*G0_1_1_0_0_0 - 0.284444444444442*G0_1_1_0_0_1 + 1.44253968253967*G0_1_1_1_0_0 - 0.507936507936505*G0_1_1_2_0_1 + 0.314920634920634*G0_1_1_3_0_0 + 2.35682539682538*G0_1_1_3_0_1 - 1.26984126984126*G0_1_1_4_0_0 - 1.36126984126983*G0_1_1_4_0_1 - 1.10730158730158*G0_1_1_5_0_0 - 0.670476190476188*G0_1_1_5_0_1 + 1.26984126984126*G0_1_1_6_0_0 + 1.46285714285713*G0_1_1_6_0_1 + 1.5542857142857*G0_1_1_7_0_0 + 1.11746031746031*G0_1_1_7_0_1 - 2.71238095238093*G0_1_1_8_0_0 - 2.35682539682538*G0_1_1_8_0_1 + 0.792380952380946*G0_1_1_9_0_0 + 0.243809523809521*G0_1_1_9_0_1 - 0.284444444444442*G0_1_1_10_1_0 - 0.284444444444442*G0_1_1_10_1_1 + 1.44253968253967*G0_1_1_11_1_0 - 0.507936507936505*G0_1_1_12_1_1 + 0.314920634920634*G0_1_1_13_1_0 + 2.35682539682538*G0_1_1_13_1_1 - 1.26984126984126*G0_1_1_14_1_0 - 1.36126984126983*G0_1_1_14_1_1 - 1.10730158730158*G0_1_1_15_1_0 - 0.670476190476188*G0_1_1_15_1_1 + 1.26984126984126*G0_1_1_16_1_0 + 1.46285714285713*G0_1_1_16_1_1 + 1.5542857142857*G0_1_1_17_1_0 + 1.11746031746031*G0_1_1_17_1_1 - 2.71238095238093*G0_1_1_18_1_0 - 2.35682539682538*G0_1_1_18_1_1 + 0.792380952380946*G0_1_1_19_1_0 + 0.243809523809521*G0_1_1_19_1_1; + A[156] = A[621]; + A[738] = A[273]; + A[650] = A[621] + 0.0203174603174588*G0_0_1_0_0_0 + 0.020317460317459*G0_0_1_0_0_1 + 0.121904761904763*G0_0_1_1_0_0 + 0.507936507936508*G0_0_1_2_0_1 - 0.751746031746027*G0_0_1_3_0_0 - 0.0304761904761874*G0_0_1_3_0_1 + 0.711111111111111*G0_0_1_4_0_0 - 0.396190476190474*G0_0_1_4_0_1 + 0.264126984126986*G0_0_1_5_0_0 + 0.193015873015876*G0_0_1_5_0_1 - 0.711111111111111*G0_0_1_6_0_0 - 0.721269841269844*G0_0_1_6_0_1 - 0.223492063492062*G0_0_1_7_0_0 - 0.152380952380951*G0_0_1_7_0_1 + 0.0812698412698399*G0_0_1_8_0_0 + 0.0304761904761875*G0_0_1_8_0_1 + 0.487619047619042*G0_0_1_9_0_0 + 0.548571428571426*G0_0_1_9_0_1 + 0.0203174603174588*G0_0_1_10_1_0 + 0.020317460317459*G0_0_1_10_1_1 + 0.121904761904763*G0_0_1_11_1_0 + 0.507936507936508*G0_0_1_12_1_1 - 0.751746031746027*G0_0_1_13_1_0 - 0.0304761904761874*G0_0_1_13_1_1 + 0.711111111111111*G0_0_1_14_1_0 - 0.396190476190474*G0_0_1_14_1_1 + 0.264126984126986*G0_0_1_15_1_0 + 0.193015873015876*G0_0_1_15_1_1 - 0.711111111111111*G0_0_1_16_1_0 - 0.721269841269844*G0_0_1_16_1_1 - 0.223492063492062*G0_0_1_17_1_0 - 0.152380952380951*G0_0_1_17_1_1 + 0.0812698412698399*G0_0_1_18_1_0 + 0.0304761904761875*G0_0_1_18_1_1 + 0.487619047619042*G0_0_1_19_1_0 + 0.548571428571426*G0_0_1_19_1_1 - 0.0203174603174588*G0_1_0_0_0_0 - 0.020317460317459*G0_1_0_0_0_1 - 0.121904761904763*G0_1_0_1_0_0 - 0.507936507936508*G0_1_0_2_0_1 + 0.751746031746028*G0_1_0_3_0_0 + 0.0304761904761875*G0_1_0_3_0_1 - 0.711111111111111*G0_1_0_4_0_0 + 0.396190476190474*G0_1_0_4_0_1 - 0.264126984126986*G0_1_0_5_0_0 - 0.193015873015876*G0_1_0_5_0_1 + 0.711111111111111*G0_1_0_6_0_0 + 0.721269841269844*G0_1_0_6_0_1 + 0.223492063492062*G0_1_0_7_0_0 + 0.152380952380951*G0_1_0_7_0_1 - 0.0812698412698399*G0_1_0_8_0_0 - 0.0304761904761875*G0_1_0_8_0_1 - 0.487619047619042*G0_1_0_9_0_0 - 0.548571428571426*G0_1_0_9_0_1 - 0.0203174603174588*G0_1_0_10_1_0 - 0.020317460317459*G0_1_0_10_1_1 - 0.121904761904763*G0_1_0_11_1_0 - 0.507936507936508*G0_1_0_12_1_1 + 0.751746031746028*G0_1_0_13_1_0 + 0.0304761904761875*G0_1_0_13_1_1 - 0.711111111111111*G0_1_0_14_1_0 + 0.396190476190474*G0_1_0_14_1_1 - 0.264126984126986*G0_1_0_15_1_0 - 0.193015873015876*G0_1_0_15_1_1 + 0.711111111111111*G0_1_0_16_1_0 + 0.721269841269844*G0_1_0_16_1_1 + 0.223492063492062*G0_1_0_17_1_0 + 0.152380952380951*G0_1_0_17_1_1 - 0.0812698412698399*G0_1_0_18_1_0 - 0.0304761904761875*G0_1_0_18_1_1 - 0.487619047619042*G0_1_0_19_1_0 - 0.548571428571426*G0_1_0_19_1_1; + A[185] = A[650]; + A[711] = -A[621] - 0.115132275132276*G0_1_0_0_0_0 - 0.115132275132276*G0_1_0_0_0_1 + 0.318306878306878*G0_1_0_1_0_0 + 0.64338624338624*G0_1_0_2_0_1 - 1.32063492063491*G0_1_0_3_0_0 - 0.172698412698408*G0_1_0_3_0_1 + 1.42222222222221*G0_1_0_4_0_0 - 0.0507936507936502*G0_1_0_4_0_1 - 1.11746031746031*G0_1_0_5_0_0 - 0.477460317460313*G0_1_0_5_0_1 - 1.42222222222221*G0_1_0_6_0_0 - 0.0507936507936511*G0_1_0_6_0_1 + 0.142222222222223*G0_1_0_7_0_0 - 0.497777777777777*G0_1_0_7_0_1 - 0.345396825396825*G0_1_0_8_0_0 + 0.172698412698409*G0_1_0_8_0_1 + 2.43809523809523*G0_1_0_9_0_0 + 0.548571428571427*G0_1_0_9_0_1 - 0.115132275132276*G0_1_0_10_1_0 - 0.115132275132276*G0_1_0_10_1_1 + 0.318306878306878*G0_1_0_11_1_0 + 0.64338624338624*G0_1_0_12_1_1 - 1.32063492063491*G0_1_0_13_1_0 - 0.172698412698408*G0_1_0_13_1_1 + 1.42222222222221*G0_1_0_14_1_0 - 0.0507936507936502*G0_1_0_14_1_1 - 1.11746031746031*G0_1_0_15_1_0 - 0.477460317460313*G0_1_0_15_1_1 - 1.42222222222221*G0_1_0_16_1_0 - 0.0507936507936511*G0_1_0_16_1_1 + 0.142222222222223*G0_1_0_17_1_0 - 0.497777777777777*G0_1_0_17_1_1 - 0.345396825396825*G0_1_0_18_1_0 + 0.172698412698409*G0_1_0_18_1_1 + 2.43809523809523*G0_1_0_19_1_0 + 0.548571428571427*G0_1_0_19_1_1 - 1.46962962962962*G0_1_1_0_0_0 - 1.46962962962962*G0_1_1_0_0_1 + 0.331851851851851*G0_1_1_1_0_0 + 1.08359788359788*G0_1_1_2_0_1 - 1.1479365079365*G0_1_1_3_0_0 - 0.243809523809519*G0_1_1_3_0_1 + 1.47301587301587*G0_1_1_4_0_0 - 0.18285714285714*G0_1_1_4_0_1 - 0.741587301587296*G0_1_1_5_0_0 + 2.23492063492062*G0_1_1_5_0_1 - 1.47301587301587*G0_1_1_6_0_0 - 1.84888888888888*G0_1_1_6_0_1 + 1.69650793650793*G0_1_1_7_0_0 - 1.27999999999999*G0_1_1_7_0_1 - 0.558730158730155*G0_1_1_8_0_0 + 0.243809523809519*G0_1_1_8_0_1 + 1.8895238095238*G0_1_1_9_0_0 + 1.46285714285713*G0_1_1_9_0_1 - 1.46962962962962*G0_1_1_10_1_0 - 1.46962962962962*G0_1_1_10_1_1 + 0.331851851851851*G0_1_1_11_1_0 + 1.08359788359788*G0_1_1_12_1_1 - 1.1479365079365*G0_1_1_13_1_0 - 0.243809523809519*G0_1_1_13_1_1 + 1.47301587301587*G0_1_1_14_1_0 - 0.18285714285714*G0_1_1_14_1_1 - 0.741587301587296*G0_1_1_15_1_0 + 2.23492063492062*G0_1_1_15_1_1 - 1.47301587301587*G0_1_1_16_1_0 - 1.84888888888888*G0_1_1_16_1_1 + 1.69650793650793*G0_1_1_17_1_0 - 1.27999999999999*G0_1_1_17_1_1 - 0.558730158730155*G0_1_1_18_1_0 + 0.243809523809519*G0_1_1_18_1_1 + 1.8895238095238*G0_1_1_19_1_0 + 1.46285714285713*G0_1_1_19_1_1; + A[246] = A[711]; + A[653] = A[711] - 0.135449735449735*G0_0_1_0_0_0 - 0.135449735449735*G0_0_1_0_0_1 + 0.196402116402115*G0_0_1_1_0_0 + 0.135449735449732*G0_0_1_2_0_1 - 0.568888888888884*G0_0_1_3_0_0 - 0.142222222222221*G0_0_1_3_0_1 + 0.711111111111105*G0_0_1_4_0_0 + 0.345396825396824*G0_0_1_4_0_1 - 1.3815873015873*G0_0_1_5_0_0 - 0.670476190476188*G0_0_1_5_0_1 - 0.711111111111105*G0_0_1_6_0_0 + 0.670476190476191*G0_0_1_6_0_1 + 0.365714285714285*G0_0_1_7_0_0 - 0.345396825396825*G0_0_1_7_0_1 - 0.426666666666665*G0_0_1_8_0_0 + 0.142222222222221*G0_0_1_8_0_1 + 1.95047619047618*G0_0_1_9_0_0 - 0.135449735449735*G0_0_1_10_1_0 - 0.135449735449735*G0_0_1_10_1_1 + 0.196402116402115*G0_0_1_11_1_0 + 0.135449735449732*G0_0_1_12_1_1 - 0.568888888888884*G0_0_1_13_1_0 - 0.142222222222221*G0_0_1_13_1_1 + 0.711111111111105*G0_0_1_14_1_0 + 0.345396825396824*G0_0_1_14_1_1 - 1.3815873015873*G0_0_1_15_1_0 - 0.670476190476188*G0_0_1_15_1_1 - 0.711111111111105*G0_0_1_16_1_0 + 0.670476190476191*G0_0_1_16_1_1 + 0.365714285714285*G0_0_1_17_1_0 - 0.345396825396825*G0_0_1_17_1_1 - 0.426666666666665*G0_0_1_18_1_0 + 0.142222222222221*G0_0_1_18_1_1 + 1.95047619047618*G0_0_1_19_1_0 + 0.135449735449735*G0_1_0_0_0_0 + 0.135449735449735*G0_1_0_0_0_1 - 0.196402116402115*G0_1_0_1_0_0 - 0.135449735449732*G0_1_0_2_0_1 + 0.568888888888884*G0_1_0_3_0_0 + 0.142222222222221*G0_1_0_3_0_1 - 0.711111111111105*G0_1_0_4_0_0 - 0.345396825396824*G0_1_0_4_0_1 + 1.3815873015873*G0_1_0_5_0_0 + 0.670476190476188*G0_1_0_5_0_1 + 0.711111111111105*G0_1_0_6_0_0 - 0.670476190476191*G0_1_0_6_0_1 - 0.365714285714285*G0_1_0_7_0_0 + 0.345396825396825*G0_1_0_7_0_1 + 0.426666666666665*G0_1_0_8_0_0 - 0.142222222222221*G0_1_0_8_0_1 - 1.95047619047618*G0_1_0_9_0_0 + 0.135449735449735*G0_1_0_10_1_0 + 0.135449735449735*G0_1_0_10_1_1 - 0.196402116402115*G0_1_0_11_1_0 - 0.135449735449732*G0_1_0_12_1_1 + 0.568888888888884*G0_1_0_13_1_0 + 0.142222222222221*G0_1_0_13_1_1 - 0.711111111111105*G0_1_0_14_1_0 - 0.345396825396824*G0_1_0_14_1_1 + 1.3815873015873*G0_1_0_15_1_0 + 0.670476190476188*G0_1_0_15_1_1 + 0.711111111111105*G0_1_0_16_1_0 - 0.670476190476191*G0_1_0_16_1_1 - 0.365714285714285*G0_1_0_17_1_0 + 0.345396825396825*G0_1_0_17_1_1 + 0.426666666666665*G0_1_0_18_1_0 - 0.142222222222221*G0_1_0_18_1_1 - 1.95047619047618*G0_1_0_19_1_0; + A[705] = A[240]; + A[300] = A[765]; + A[256] = 0.0; + A[343] = A[808]; + A[22] = 0.0; + A[739] = A[274]; + A[430] = A[895]; + A[374] = A[897] - 0.975238095238095*G0_0_1_0_0_0 - 0.975238095238095*G0_0_1_0_0_1 + 0.97523809523809*G0_0_1_1_0_0 + 0.975238095238094*G0_0_1_2_0_1 - 2.80380952380951*G0_0_1_3_0_0 - 0.243809523809523*G0_0_1_3_0_1 + 1.5847619047619*G0_0_1_4_0_0 - 0.975238095238089*G0_0_1_4_0_1 - 0.853333333333329*G0_0_1_5_0_0 + 0.731428571428577*G0_0_1_5_0_1 - 1.5847619047619*G0_0_1_6_0_0 - 0.731428571428576*G0_0_1_6_0_1 + 2.55999999999999*G0_0_1_7_0_0 + 0.975238095238087*G0_0_1_7_0_1 - 2.55999999999999*G0_0_1_8_0_0 + 0.243809523809524*G0_0_1_8_0_1 + 3.65714285714284*G0_0_1_9_0_0 - 0.975238095238095*G0_0_1_10_1_0 - 0.975238095238095*G0_0_1_10_1_1 + 0.97523809523809*G0_0_1_11_1_0 + 0.975238095238094*G0_0_1_12_1_1 - 2.80380952380951*G0_0_1_13_1_0 - 0.243809523809523*G0_0_1_13_1_1 + 1.5847619047619*G0_0_1_14_1_0 - 0.975238095238089*G0_0_1_14_1_1 - 0.853333333333329*G0_0_1_15_1_0 + 0.731428571428577*G0_0_1_15_1_1 - 1.5847619047619*G0_0_1_16_1_0 - 0.731428571428576*G0_0_1_16_1_1 + 2.55999999999999*G0_0_1_17_1_0 + 0.975238095238087*G0_0_1_17_1_1 - 2.55999999999999*G0_0_1_18_1_0 + 0.243809523809524*G0_0_1_18_1_1 + 3.65714285714284*G0_0_1_19_1_0 + 0.975238095238095*G0_1_0_0_0_0 + 0.975238095238095*G0_1_0_0_0_1 - 0.97523809523809*G0_1_0_1_0_0 - 0.975238095238094*G0_1_0_2_0_1 + 2.80380952380951*G0_1_0_3_0_0 + 0.243809523809523*G0_1_0_3_0_1 - 1.5847619047619*G0_1_0_4_0_0 + 0.975238095238088*G0_1_0_4_0_1 + 0.853333333333329*G0_1_0_5_0_0 - 0.731428571428577*G0_1_0_5_0_1 + 1.5847619047619*G0_1_0_6_0_0 + 0.731428571428576*G0_1_0_6_0_1 - 2.55999999999999*G0_1_0_7_0_0 - 0.975238095238087*G0_1_0_7_0_1 + 2.55999999999999*G0_1_0_8_0_0 - 0.243809523809524*G0_1_0_8_0_1 - 3.65714285714284*G0_1_0_9_0_0 + 0.975238095238095*G0_1_0_10_1_0 + 0.975238095238095*G0_1_0_10_1_1 - 0.97523809523809*G0_1_0_11_1_0 - 0.975238095238094*G0_1_0_12_1_1 + 2.80380952380951*G0_1_0_13_1_0 + 0.243809523809523*G0_1_0_13_1_1 - 1.5847619047619*G0_1_0_14_1_0 + 0.975238095238088*G0_1_0_14_1_1 + 0.853333333333329*G0_1_0_15_1_0 - 0.731428571428577*G0_1_0_15_1_1 + 1.5847619047619*G0_1_0_16_1_0 + 0.731428571428576*G0_1_0_16_1_1 - 2.55999999999999*G0_1_0_17_1_0 - 0.975238095238087*G0_1_0_17_1_1 + 2.55999999999999*G0_1_0_18_1_0 - 0.243809523809524*G0_1_0_18_1_1 - 3.65714285714284*G0_1_0_19_1_0; + A[53] = 0.0; + A[768] = A[303]; + A[453] = 0.0; + A[405] = 0.0; + A[80] = 0.0; + A[789] = 0.0; + A[12] = A[477]; + A[99] = -A[804] - 1.46962962962963*G0_0_0_0_0_0 - 1.46962962962963*G0_0_0_0_0_1 + 1.08359788359788*G0_0_0_1_0_0 + 0.331851851851851*G0_0_0_2_0_1 - 0.182857142857142*G0_0_0_3_0_0 + 1.47301587301587*G0_0_0_3_0_1 - 0.243809523809524*G0_0_0_4_0_0 - 1.14793650793651*G0_0_0_4_0_1 - 1.27999999999999*G0_0_0_5_0_0 + 1.69650793650794*G0_0_0_5_0_1 + 0.243809523809524*G0_0_0_6_0_0 - 0.55873015873016*G0_0_0_6_0_1 + 2.23492063492063*G0_0_0_7_0_0 - 0.741587301587299*G0_0_0_7_0_1 - 1.84888888888888*G0_0_0_8_0_0 - 1.47301587301587*G0_0_0_8_0_1 + 1.46285714285714*G0_0_0_9_0_0 + 1.8895238095238*G0_0_0_9_0_1 - 1.46962962962963*G0_0_0_10_1_0 - 1.46962962962963*G0_0_0_10_1_1 + 1.08359788359788*G0_0_0_11_1_0 + 0.331851851851851*G0_0_0_12_1_1 - 0.182857142857142*G0_0_0_13_1_0 + 1.47301587301587*G0_0_0_13_1_1 - 0.243809523809524*G0_0_0_14_1_0 - 1.14793650793651*G0_0_0_14_1_1 - 1.27999999999999*G0_0_0_15_1_0 + 1.69650793650794*G0_0_0_15_1_1 + 0.243809523809524*G0_0_0_16_1_0 - 0.55873015873016*G0_0_0_16_1_1 + 2.23492063492063*G0_0_0_17_1_0 - 0.741587301587299*G0_0_0_17_1_1 - 1.84888888888888*G0_0_0_18_1_0 - 1.47301587301587*G0_0_0_18_1_1 + 1.46285714285714*G0_0_0_19_1_0 + 1.8895238095238*G0_0_0_19_1_1 - 0.115132275132274*G0_0_1_0_0_0 - 0.115132275132274*G0_0_1_0_0_1 + 0.643386243386241*G0_0_1_1_0_0 + 0.318306878306877*G0_0_1_2_0_1 - 0.0507936507936524*G0_0_1_3_0_0 + 1.42222222222221*G0_0_1_3_0_1 - 0.172698412698412*G0_0_1_4_0_0 - 1.32063492063492*G0_0_1_4_0_1 - 0.497777777777777*G0_0_1_5_0_0 + 0.142222222222219*G0_0_1_5_0_1 + 0.172698412698412*G0_0_1_6_0_0 - 0.345396825396822*G0_0_1_6_0_1 - 0.477460317460316*G0_0_1_7_0_0 - 1.11746031746031*G0_0_1_7_0_1 - 0.0507936507936495*G0_0_1_8_0_0 - 1.42222222222221*G0_0_1_8_0_1 + 0.548571428571429*G0_0_1_9_0_0 + 2.43809523809523*G0_0_1_9_0_1 - 0.115132275132274*G0_0_1_10_1_0 - 0.115132275132274*G0_0_1_10_1_1 + 0.643386243386241*G0_0_1_11_1_0 + 0.318306878306877*G0_0_1_12_1_1 - 0.0507936507936524*G0_0_1_13_1_0 + 1.42222222222221*G0_0_1_13_1_1 - 0.172698412698412*G0_0_1_14_1_0 - 1.32063492063492*G0_0_1_14_1_1 - 0.497777777777777*G0_0_1_15_1_0 + 0.142222222222219*G0_0_1_15_1_1 + 0.172698412698412*G0_0_1_16_1_0 - 0.345396825396822*G0_0_1_16_1_1 - 0.477460317460316*G0_0_1_17_1_0 - 1.11746031746031*G0_0_1_17_1_1 - 0.0507936507936495*G0_0_1_18_1_0 - 1.42222222222221*G0_0_1_18_1_1 + 0.548571428571429*G0_0_1_19_1_0 + 2.43809523809523*G0_0_1_19_1_1; + A[814] = 0.0; + A[39] = A[504]; + A[122] = A[587]; + A[847] = 0.0; + A[74] = A[539]; + A[153] = -A[161] - 0.0135449735449744*G0_0_0_0_0_0 - 0.0135449735449742*G0_0_0_0_0_1 + 0.440211640211639*G0_0_0_1_0_0 + 1.35449735449735*G0_0_0_2_0_1 - 1.74730158730158*G0_0_0_3_0_0 + 0.0507936507936533*G0_0_0_3_0_1 + 2.33650793650792*G0_0_0_4_0_0 - 0.375873015873014*G0_0_0_4_0_1 + 0.284444444444444*G0_0_0_5_0_0 + 0.213333333333334*G0_0_0_5_0_1 - 2.33650793650792*G0_0_0_6_0_0 - 1.55428571428571*G0_0_0_6_0_1 - 0.243809523809521*G0_0_0_7_0_0 - 0.172698412698409*G0_0_0_7_0_1 - 0.182857142857145*G0_0_0_8_0_0 - 0.0507936507936531*G0_0_0_8_0_1 + 1.46285714285713*G0_0_0_9_0_0 + 0.548571428571423*G0_0_0_9_0_1 - 0.0135449735449744*G0_0_0_10_1_0 - 0.0135449735449742*G0_0_0_10_1_1 + 0.440211640211639*G0_0_0_11_1_0 + 1.35449735449735*G0_0_0_12_1_1 - 1.74730158730158*G0_0_0_13_1_0 + 0.0507936507936533*G0_0_0_13_1_1 + 2.33650793650792*G0_0_0_14_1_0 - 0.375873015873014*G0_0_0_14_1_1 + 0.284444444444444*G0_0_0_15_1_0 + 0.213333333333334*G0_0_0_15_1_1 - 2.33650793650792*G0_0_0_16_1_0 - 1.55428571428571*G0_0_0_16_1_1 - 0.243809523809521*G0_0_0_17_1_0 - 0.172698412698409*G0_0_0_17_1_1 - 0.182857142857145*G0_0_0_18_1_0 - 0.0507936507936531*G0_0_0_18_1_1 + 1.46285714285713*G0_0_0_19_1_0 + 0.548571428571423*G0_0_0_19_1_1 + 0.318306878306878*G0_1_0_0_0_0 + 0.318306878306877*G0_1_0_0_0_1 - 0.643386243386246*G0_1_0_1_0_0 - 0.115132275132276*G0_1_0_2_0_1 - 1.37142857142857*G0_1_0_3_0_0 - 1.42222222222223*G0_1_0_3_0_1 - 0.64*G0_1_0_4_0_0 - 1.11746031746031*G0_1_0_4_0_1 - 0.518095238095236*G0_1_0_5_0_0 - 0.345396825396824*G0_1_0_5_0_1 + 0.639999999999999*G0_1_0_6_0_0 + 0.142222222222223*G0_1_0_6_0_1 - 1.14793650793651*G0_1_0_7_0_0 - 1.32063492063492*G0_1_0_7_0_1 + 1.47301587301587*G0_1_0_8_0_0 + 1.42222222222223*G0_1_0_8_0_1 + 1.8895238095238*G0_1_0_9_0_0 + 2.43809523809523*G0_1_0_9_0_1 + 0.318306878306878*G0_1_0_10_1_0 + 0.318306878306877*G0_1_0_10_1_1 - 0.643386243386246*G0_1_0_11_1_0 - 0.115132275132276*G0_1_0_12_1_1 - 1.37142857142857*G0_1_0_13_1_0 - 1.42222222222223*G0_1_0_13_1_1 - 0.64*G0_1_0_14_1_0 - 1.11746031746031*G0_1_0_14_1_1 - 0.518095238095236*G0_1_0_15_1_0 - 0.345396825396824*G0_1_0_15_1_1 + 0.639999999999999*G0_1_0_16_1_0 + 0.142222222222223*G0_1_0_16_1_1 - 1.14793650793651*G0_1_0_17_1_0 - 1.32063492063492*G0_1_0_17_1_1 + 1.47301587301587*G0_1_0_18_1_0 + 1.42222222222223*G0_1_0_18_1_1 + 1.8895238095238*G0_1_0_19_1_0 + 2.43809523809523*G0_1_0_19_1_1; + A[876] = 0.0; + A[485] = 0.0; + A[188] = A[653]; + A[586] = A[121]; + A[510] = 0.0; + A[223] = A[688]; + A[611] = 0.0; + A[547] = 0.0; + A[507] = A[42]; + A[640] = 0.0; + A[536] = A[71]; + A[661] = 0.0; + A[282] = A[747]; + A[694] = 0.0; + A[311] = A[776]; + A[263] = 0.0; + A[332] = A[797]; + A[292] = 0.0; + A[746] = A[281]; + A[433] = A[898]; + A[365] = A[830]; + A[321] = 0.0; + A[777] = A[312]; + A[458] = 0.0; + A[398] = A[863]; + A[354] = 0.0; + A[796] = A[331]; + A[3] = A[468]; + A[720] = 0.0; + A[104] = A[569]; + A[839] = A[374]; + A[32] = A[497]; + A[129] = A[594]; + A[69] = A[534]; + A[162] = A[627]; + A[110] = 0.0; + A[183] = A[648]; + A[143] = 0.0; + A[595] = A[130]; + A[220] = A[685]; + A[172] = 0.0; + A[618] = A[153]; + A[498] = A[33]; + A[649] = A[184]; + A[529] = A[64]; + A[684] = A[219]; + A[564] = A[99]; + A[719] = A[254]; + A[440] = 0.0; + A[328] = 0.0; + A[778] = A[313]; + A[467] = A[2]; + A[391] = A[856]; + A[347] = 0.0; + A[807] = A[342]; + A[26] = 0.0; + A[727] = 0.0; + A[386] = 0.0; + A[828] = A[363]; + A[57] = 0.0; + A[756] = 0.0; + A[417] = 0.0; + A[861] = A[396]; + A[60] = A[525]; + A[785] = 0.0; + A[894] = A[429]; + A[119] = 0.0; + A[818] = 0.0; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f1_p3_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f1_p3_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f1_p3_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2}))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 1; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q4_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f1_p3_q4_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f1_p3_q4_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q1_excafe.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q1_excafe.h new file mode 100644 index 0000000..e073215 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q1_excafe.h @@ -0,0 +1,184 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 28.95 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][1]; + const double var_1 = x[1][1] + var_0; + const double var_2 = x[2][1] + var_0; + const double var_3 = -x[0][0]; + const double var_4 = x[1][0] + var_3; + const double var_5 = var_4*w[1][5] + var_2*w[1][1]; + const double var_6 = var_1*w[1][0] + var_5; + const double var_7 = x[2][0] + var_3; + const double var_8 = var_7*w[1][3]; + const double var_9 = var_6 + var_8; + const double var_10 = var_7*w[0][4] + var_1*w[0][2]; + const double var_11 = var_4*w[0][5] + var_2*w[0][1]; + const double var_12 = var_10 + -var_11; + const double var_13 = -var_7*w[0][3] + var_12; + const double var_14 = -var_1*w[0][0]; + const double var_15 = var_14 + var_13; + const double var_16 = var_15*var_9; + const double var_17 = var_7*w[1][4] + var_1*w[1][2]; + const double var_18 = var_4*w[1][3]; + const double var_19 = var_17 + var_18; + const double var_20 = var_4*var_6*w[0][3] + var_1*var_19*w[0][0]; + const double var_21 = -var_10 + var_11; + const double var_22 = -var_4*w[0][3]; + const double var_23 = var_22 + var_21; + const double var_24 = var_19*var_23; + const double var_25 = var_20 + var_16 + var_24; + const double var_26 = -var_4 + var_7; + const double var_27 = var_2*var_2; + const double var_28 = var_2*w[1][0]; + const double var_29 = var_17 + var_28; + const double var_30 = var_5 + var_8; + const double var_31 = var_16 + var_2*var_30*w[0][0] + var_29*var_7*w[0][3]; + const double var_32 = -var_19 + var_30; + const double var_33 = var_21*w[1][0] + var_32*w[0][0]; + const double var_34 = var_33 + var_26*w[0][3]*w[1][0]; + const double var_35 = var_7*var_7; + const double var_36 = var_27 + var_35; + const double var_37 = -var_1*var_7 + var_2*var_4; + const double var_38 = var_37; + const double var_39 = std::abs(var_38); + const double var_40 = var_37; + const double var_41 = var_4*w[0][3] + var_12; + const double var_42 = var_1*w[0][0] + var_21; + const double var_43 = var_19*var_41 + var_42*var_6 + -var_20; + const double var_44 = -var_17 + var_9; + const double var_45 = var_1*w[0][0]*w[1][3] + var_44*w[0][3]; + const double var_46 = 0.5000000000000000000000000*var_45 + var_22*w[1][3]; + const double var_47 = 0.5000000000000000000000000*var_43 + var_46*var_7; + const double var_48 = var_14 + 0.5000000000000000000000000*var_13; + const double var_49 = -var_2*w[0][0] + var_21; + const double var_50 = var_19 + var_28; + const double var_51 = -var_5 + var_50; + const double var_52 = var_4*w[0][3]*w[1][0]; + const double var_53 = var_52 + var_51*w[0][0]; + const double var_54 = var_2*var_53; + const double var_55 = var_54 + var_49*var_7*w[1][3]; + const double var_56 = var_2*var_48*w[1][0] + var_47 + 0.5000000000000000000000000*var_55; + const double var_57 = var_4*var_4; + const double var_58 = var_1*var_1; + const double var_59 = var_57 + var_58; + A[14] = var_39*var_56*var_59/(var_40*var_40*var_40*var_40); + A[35] = A[14]; + const double var_60 = var_13*var_29 + var_30*var_49; + const double var_61 = 0.5000000000000000000000000*var_60; + const double var_62 = var_2*var_29 + var_1*var_44; + const double var_63 = var_1*var_21*w[1][0] + var_7*var_9*w[0][3] + var_62*w[0][0]; + const double var_64 = var_61 + 0.5000000000000000000000000*var_63 + -var_1*var_2*w[0][0]*w[1][0]; + const double var_65 = var_14 + var_12; + const double var_66 = var_2*var_5*w[0][0] + 3.0000000000000000000000000*var_4*var_7*w[0][3]*w[1][3] + var_6*var_65; + const double var_67 = var_22 + var_49; + const double var_68 = var_50*var_67; + const double var_69 = 0.5000000000000000000000000*var_68; + const double var_70 = var_1*var_2*w[0][0]*w[1][0] + 0.5000000000000000000000000*var_20 + var_69; + const double var_71 = var_2*w[0][0] + var_65; + const double var_72 = -var_6 + var_29; + const double var_73 = var_71*w[1][3] + var_72*w[0][3]; + const double var_74 = var_7*var_73; + const double var_75 = -1.5000000000000000000000000*var_7*var_7*w[0][3]*w[1][3] + 0.5000000000000000000000000*var_66 + var_70 + var_74; + const double var_76 = var_4*var_75 + var_64*var_7; + const double var_77 = 0.5000000000000000000000000*var_17 + var_18; + const double var_78 = var_2*var_26*w[1][0] + var_7*var_77; + const double var_79 = -var_2 + var_1; + const double var_80 = 1.5000000000000000000000000*var_79*w[0][0]*w[1][0] + var_33; + const double var_81 = 0.5000000000000000000000000*var_25 + var_78*w[0][3] + var_2*var_80; + const double var_82 = var_30*var_7 + var_4*var_51; + const double var_83 = var_12*var_4*w[1][3] + var_2*var_50*w[0][0] + var_82*w[0][3]; + const double var_84 = var_61 + -var_4*var_7*w[0][3]*w[1][3] + 0.5000000000000000000000000*var_83; + const double var_85 = var_2*var_84; + const double var_86 = var_1*var_81 + var_85; + const double var_87 = var_4*var_76 + var_1*var_86; + A[2] = var_39*var_87/(var_40*var_40*var_40*var_40); + A[33] = A[2]; + const double var_88 = var_4*var_7*w[0][3]*w[1][3]; + A[12] = A[2]; + const double var_89 = 3.0000000000000000000000000*var_1*var_2*w[0][0]*w[1][0] + var_13*var_30 + var_4*var_5*w[0][3]; + const double var_90 = var_58 + var_27; + const double var_91 = var_57 + 2.0000000000000000000000000*var_90; + const double var_92 = 2.0000000000000000000000000*var_4*var_7 + -var_91; + const double var_93 = -var_30 + var_19; + const double var_94 = var_52 + var_13*w[1][0] + var_93*w[0][0]; + const double var_95 = var_1*var_94; + const double var_96 = var_2*var_34 + var_95; + const double var_97 = var_24 + var_17*var_7*w[0][3] + 2.0000000000000000000000000*var_88 + var_92*w[0][0]*w[1][0] + var_89 + 1.5000000000000000000000000*var_96; + const double var_98 = var_1*var_97 + var_85; + A[7] = var_36*var_39*var_56/(var_40*var_40*var_40*var_40); + const double var_99 = var_69 + -1.5000000000000000000000000*var_1*var_1*w[0][0]*w[1][0] + 0.5000000000000000000000000*var_89 + var_88 + var_95; + const double var_100 = 0.5000000000000000000000000*var_30*var_36*w[0][0] + var_2*var_99 + var_1*var_47; + const double var_101 = -var_29 + var_6; + const double var_102 = var_49*w[1][3] + var_101*w[0][3]; + const double var_103 = var_43 + var_12*var_2*w[1][0] + var_54; + const double var_104 = var_29*var_49; + const double var_105 = var_16 + 3.0000000000000000000000000*var_26*var_4*w[0][3]*w[1][3] + var_104; + const double var_106 = var_1*var_2*var_21*w[1][3] + var_29*var_36*w[0][3] + var_105*var_7 + var_103*var_4; + const double var_107 = 0.5000000000000000000000000*var_106 + var_102*var_4*var_7 + var_1*var_78*w[0][0]; + const double var_108 = var_100*var_2 + var_107*var_7; + A[1] = var_108*var_39/(var_40*var_40*var_40*var_40); + A[6] = A[1]; + const double var_109 = var_47 + 0.5000000000000000000000000*var_21*var_7*w[1][3]; + A[32] = 0.0000000000000000000000000; + const double var_110 = var_1*var_2 + var_4*var_7; + A[16] = 0.0000000000000000000000000; + A[3] = 0.0000000000000000000000000; + A[11] = 0.0000000000000000000000000; + A[5] = 0.0000000000000000000000000; + const double var_111 = var_88 + 0.5000000000000000000000000*var_31 + var_70; + A[8] = var_110*var_111*var_39/(var_40*var_40*var_40*var_40); + A[34] = A[8]; + A[13] = A[8]; + A[19] = 0.0000000000000000000000000; + const double var_112 = var_17 + 1.5000000000000000000000000*var_4*w[1][3]; + A[4] = 0.0000000000000000000000000; + A[30] = 0.0000000000000000000000000; + A[10] = 0.0000000000000000000000000; + A[20] = 0.0000000000000000000000000; + const double var_113 = var_57 + var_35; + const double var_114 = var_102*var_4 + var_74; + const double var_115 = -2.0000000000000000000000000*var_113*w[0][3]*w[1][3] + 1.5000000000000000000000000*var_114 + var_66 + var_104 + var_1*var_112*w[0][0]; + const double var_116 = 0.5000000000000000000000000*var_103*var_4 + var_115*var_7; + const double var_117 = var_64*var_7*var_7 + var_116*var_4 + var_2*var_98 + var_1*var_1*var_109; + A[0] = var_117*var_39/(var_40*var_40*var_40*var_40); + A[21] = A[0]; + A[29] = A[8]; + A[28] = A[7]; + A[24] = 0.0000000000000000000000000; + A[23] = A[2]; + A[18] = 0.0000000000000000000000000; + A[22] = A[1]; + A[17] = 0.0000000000000000000000000; + A[26] = 0.0000000000000000000000000; + A[27] = A[1]; + A[25] = 0.0000000000000000000000000; + A[15] = 0.0000000000000000000000000; + A[9] = 0.0000000000000000000000000; + A[31] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q1_quadrature.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q1_quadrature.h new file mode 100644 index 0000000..54dec5f --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q1_quadrature.h @@ -0,0 +1,3294 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F2_P1_Q1_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F2_P1_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q1_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q1_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q1_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q1_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f2_p1_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W1 = 0.5; + // Quadrature points on the UFC reference element: (0.333333333333333, 0.333333333333333) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[1][2] = \ + {{-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 210. + double G[30]; + G[0] = K_00*K_00*W1*det*(K_10*K_10 + K_11*K_11); + G[1] = K_00*K_10*W1*det*(K_10*K_10 + K_11*K_11); + G[2] = K_00*K_01*W1*det*(K_10*K_10 + K_11*K_11); + G[3] = K_00*K_11*W1*det*(K_10*K_10 + K_11*K_11); + G[4] = K_10*K_10*W1*det*(K_10*K_10 + K_11*K_11); + G[5] = K_01*K_10*W1*det*(K_10*K_10 + K_11*K_11); + G[6] = K_10*K_11*W1*det*(K_10*K_10 + K_11*K_11); + G[7] = K_01*K_01*W1*det*(K_10*K_10 + K_11*K_11); + G[8] = K_01*K_11*W1*det*(K_10*K_10 + K_11*K_11); + G[9] = K_11*K_11*W1*det*(K_10*K_10 + K_11*K_11); + G[10] = K_00*K_00*W1*det*(K_00*K_10 + K_01*K_11); + G[11] = K_00*K_10*W1*det*(K_00*K_10 + K_01*K_11); + G[12] = K_00*K_01*W1*det*(K_00*K_10 + K_01*K_11); + G[13] = K_00*K_11*W1*det*(K_00*K_10 + K_01*K_11); + G[14] = K_10*K_10*W1*det*(K_00*K_10 + K_01*K_11); + G[15] = K_01*K_10*W1*det*(K_00*K_10 + K_01*K_11); + G[16] = K_10*K_11*W1*det*(K_00*K_10 + K_01*K_11); + G[17] = K_01*K_01*W1*det*(K_00*K_10 + K_01*K_11); + G[18] = K_01*K_11*W1*det*(K_00*K_10 + K_01*K_11); + G[19] = K_11*K_11*W1*det*(K_00*K_10 + K_01*K_11); + G[20] = K_00*K_00*W1*det*(K_00*K_00 + K_01*K_01); + G[21] = K_00*K_10*W1*det*(K_00*K_00 + K_01*K_01); + G[22] = K_00*K_01*W1*det*(K_00*K_00 + K_01*K_01); + G[23] = K_00*K_11*W1*det*(K_00*K_00 + K_01*K_01); + G[24] = K_10*K_10*W1*det*(K_00*K_00 + K_01*K_01); + G[25] = K_01*K_10*W1*det*(K_00*K_00 + K_01*K_01); + G[26] = K_10*K_11*W1*det*(K_00*K_00 + K_01*K_01); + G[27] = K_01*K_01*W1*det*(K_00*K_00 + K_01*K_01); + G[28] = K_01*K_11*W1*det*(K_00*K_00 + K_01*K_01); + G[29] = K_11*K_11*W1*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 233 + // Only 1 integration point, omitting IP loop. + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + double F4 = 0.0; + double F5 = 0.0; + double F6 = 0.0; + double F7 = 0.0; + + // Total number of operations to compute function values = 32 + for (unsigned int r = 0; r < 2; r++) + { + F0 += FE0_C0_D01[0][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[0][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D01[0][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[0][r]*w[0][nzc4[r]]; + F4 += FE0_C0_D01[0][r]*w[1][nzc2[r]]; + F5 += FE0_C0_D01[0][r]*w[1][nzc1[r]]; + F6 += FE0_C0_D01[0][r]*w[1][nzc5[r]]; + F7 += FE0_C0_D01[0][r]*w[1][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 105 + double I[3]; + // Number of operations: 35 + I[0] = (F4*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]) + F5*(F0*G[1] + F1*G[4] + F2*G[5] + F3*G[6]) + F6*(F0*G[2] + F1*G[5] + F2*G[7] + F3*G[8]) + F7*(F0*G[3] + F1*G[6] + F2*G[8] + F3*G[9])); + + // Number of operations: 35 + I[1] = (F4*(F0*G[10] + F1*G[11] + F2*G[12] + F3*G[13]) + F5*(F0*G[11] + F1*G[14] + F2*G[15] + F3*G[16]) + F6*(F0*G[12] + F1*G[15] + F2*G[17] + F3*G[18]) + F7*(F0*G[13] + F1*G[16] + F2*G[18] + F3*G[19])); + + // Number of operations: 35 + I[2] = (F4*(F0*G[20] + F1*G[21] + F2*G[22] + F3*G[23]) + F5*(F0*G[21] + F1*G[24] + F2*G[25] + F3*G[26]) + F6*(F0*G[22] + F1*G[25] + F2*G[27] + F3*G[28]) + F7*(F0*G[23] + F1*G[26] + F2*G[28] + F3*G[29])); + + + // Number of operations for primary indices: 96 + for (unsigned int j = 0; j < 2; j++) + { + for (unsigned int k = 0; k < 2; k++) + { + // Number of operations to compute entry: 3 + A[nzc1[j]*6 + nzc1[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc1[j]*6 + nzc2[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*6 + nzc1[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*6 + nzc2[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc4[j]*6 + nzc4[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc4[j]*6 + nzc5[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*6 + nzc4[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*6 + nzc5[k]] += FE0_C0_D01[0][j]*FE0_C0_D01[0][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f2_p1_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), Product(IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 2; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q1_quadrature_finite_element_1(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q1_quadrature_finite_element_1(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q1_quadrature_finite_element_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q1_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q1_quadrature_dofmap_1(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q1_quadrature_dofmap_1(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q1_quadrature_dofmap_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q1_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q1_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q1_tensor.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q1_tensor.h new file mode 100644 index 0000000..216586c --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q1_tensor.h @@ -0,0 +1,3464 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F2_P1_Q1_TENSOR_H +#define __VECTOR_LAPLACIAN_F2_P1_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q1_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q1_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q1_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q1_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f2_p1_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 1024 + // Number of operations (multiply-add pairs) for tensor contraction: 638 + // Total number of operations (multiply-add pairs): 1673 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[9] = 0.0; + A[18] = 0.0; + A[20] = 0.0; + A[31] = 0.0; + A[3] = 0.0; + A[17] = 0.0; + A[24] = 0.0; + A[8] = 0.5*G0_0_1_0_0_0_0_0_0 + 0.5*G0_0_1_0_0_0_0_0_1 - 0.5*G0_0_1_0_0_0_1_0_0 - 0.5*G0_0_1_0_0_0_2_0_1 + 0.5*G0_0_1_0_0_0_3_1_0 + 0.5*G0_0_1_0_0_0_3_1_1 - 0.5*G0_0_1_0_0_0_4_1_0 - 0.5*G0_0_1_0_0_0_5_1_1 + 0.5*G0_0_1_0_0_1_0_0_0 + 0.5*G0_0_1_0_0_1_0_0_1 - 0.5*G0_0_1_0_0_1_1_0_0 - 0.5*G0_0_1_0_0_1_2_0_1 + 0.5*G0_0_1_0_0_1_3_1_0 + 0.5*G0_0_1_0_0_1_3_1_1 - 0.5*G0_0_1_0_0_1_4_1_0 - 0.5*G0_0_1_0_0_1_5_1_1 - 0.5*G0_0_1_1_0_0_0_0_0 - 0.5*G0_0_1_1_0_0_0_0_1 + 0.5*G0_0_1_1_0_0_1_0_0 + 0.5*G0_0_1_1_0_0_2_0_1 - 0.5*G0_0_1_1_0_0_3_1_0 - 0.5*G0_0_1_1_0_0_3_1_1 + 0.5*G0_0_1_1_0_0_4_1_0 + 0.5*G0_0_1_1_0_0_5_1_1 - 0.5*G0_0_1_2_0_1_0_0_0 - 0.5*G0_0_1_2_0_1_0_0_1 + 0.5*G0_0_1_2_0_1_1_0_0 + 0.5*G0_0_1_2_0_1_2_0_1 - 0.5*G0_0_1_2_0_1_3_1_0 - 0.5*G0_0_1_2_0_1_3_1_1 + 0.5*G0_0_1_2_0_1_4_1_0 + 0.5*G0_0_1_2_0_1_5_1_1 + 0.5*G0_0_1_3_1_0_0_0_0 + 0.5*G0_0_1_3_1_0_0_0_1 - 0.5*G0_0_1_3_1_0_1_0_0 - 0.5*G0_0_1_3_1_0_2_0_1 + 0.5*G0_0_1_3_1_0_3_1_0 + 0.5*G0_0_1_3_1_0_3_1_1 - 0.5*G0_0_1_3_1_0_4_1_0 - 0.5*G0_0_1_3_1_0_5_1_1 + 0.5*G0_0_1_3_1_1_0_0_0 + 0.5*G0_0_1_3_1_1_0_0_1 - 0.5*G0_0_1_3_1_1_1_0_0 - 0.5*G0_0_1_3_1_1_2_0_1 + 0.5*G0_0_1_3_1_1_3_1_0 + 0.5*G0_0_1_3_1_1_3_1_1 - 0.5*G0_0_1_3_1_1_4_1_0 - 0.5*G0_0_1_3_1_1_5_1_1 - 0.5*G0_0_1_4_1_0_0_0_0 - 0.5*G0_0_1_4_1_0_0_0_1 + 0.5*G0_0_1_4_1_0_1_0_0 + 0.5*G0_0_1_4_1_0_2_0_1 - 0.5*G0_0_1_4_1_0_3_1_0 - 0.5*G0_0_1_4_1_0_3_1_1 + 0.5*G0_0_1_4_1_0_4_1_0 + 0.5*G0_0_1_4_1_0_5_1_1 - 0.5*G0_0_1_5_1_1_0_0_0 - 0.5*G0_0_1_5_1_1_0_0_1 + 0.5*G0_0_1_5_1_1_1_0_0 + 0.5*G0_0_1_5_1_1_2_0_1 - 0.5*G0_0_1_5_1_1_3_1_0 - 0.5*G0_0_1_5_1_1_3_1_1 + 0.5*G0_0_1_5_1_1_4_1_0 + 0.5*G0_0_1_5_1_1_5_1_1; + A[28] = 0.5*G0_0_0_0_0_0_0_0_0 + 0.5*G0_0_0_0_0_0_0_0_1 - 0.5*G0_0_0_0_0_0_1_0_0 - 0.5*G0_0_0_0_0_0_2_0_1 + 0.5*G0_0_0_0_0_0_3_1_0 + 0.5*G0_0_0_0_0_0_3_1_1 - 0.5*G0_0_0_0_0_0_4_1_0 - 0.5*G0_0_0_0_0_0_5_1_1 + 0.5*G0_0_0_0_0_1_0_0_0 + 0.5*G0_0_0_0_0_1_0_0_1 - 0.5*G0_0_0_0_0_1_1_0_0 - 0.5*G0_0_0_0_0_1_2_0_1 + 0.5*G0_0_0_0_0_1_3_1_0 + 0.5*G0_0_0_0_0_1_3_1_1 - 0.5*G0_0_0_0_0_1_4_1_0 - 0.5*G0_0_0_0_0_1_5_1_1 - 0.5*G0_0_0_1_0_0_0_0_0 - 0.5*G0_0_0_1_0_0_0_0_1 + 0.5*G0_0_0_1_0_0_1_0_0 + 0.5*G0_0_0_1_0_0_2_0_1 - 0.5*G0_0_0_1_0_0_3_1_0 - 0.5*G0_0_0_1_0_0_3_1_1 + 0.5*G0_0_0_1_0_0_4_1_0 + 0.5*G0_0_0_1_0_0_5_1_1 - 0.5*G0_0_0_2_0_1_0_0_0 - 0.5*G0_0_0_2_0_1_0_0_1 + 0.5*G0_0_0_2_0_1_1_0_0 + 0.5*G0_0_0_2_0_1_2_0_1 - 0.5*G0_0_0_2_0_1_3_1_0 - 0.5*G0_0_0_2_0_1_3_1_1 + 0.5*G0_0_0_2_0_1_4_1_0 + 0.5*G0_0_0_2_0_1_5_1_1 + 0.5*G0_0_0_3_1_0_0_0_0 + 0.5*G0_0_0_3_1_0_0_0_1 - 0.5*G0_0_0_3_1_0_1_0_0 - 0.5*G0_0_0_3_1_0_2_0_1 + 0.5*G0_0_0_3_1_0_3_1_0 + 0.5*G0_0_0_3_1_0_3_1_1 - 0.5*G0_0_0_3_1_0_4_1_0 - 0.5*G0_0_0_3_1_0_5_1_1 + 0.5*G0_0_0_3_1_1_0_0_0 + 0.5*G0_0_0_3_1_1_0_0_1 - 0.5*G0_0_0_3_1_1_1_0_0 - 0.5*G0_0_0_3_1_1_2_0_1 + 0.5*G0_0_0_3_1_1_3_1_0 + 0.5*G0_0_0_3_1_1_3_1_1 - 0.5*G0_0_0_3_1_1_4_1_0 - 0.5*G0_0_0_3_1_1_5_1_1 - 0.5*G0_0_0_4_1_0_0_0_0 - 0.5*G0_0_0_4_1_0_0_0_1 + 0.5*G0_0_0_4_1_0_1_0_0 + 0.5*G0_0_0_4_1_0_2_0_1 - 0.5*G0_0_0_4_1_0_3_1_0 - 0.5*G0_0_0_4_1_0_3_1_1 + 0.5*G0_0_0_4_1_0_4_1_0 + 0.5*G0_0_0_4_1_0_5_1_1 - 0.5*G0_0_0_5_1_1_0_0_0 - 0.5*G0_0_0_5_1_1_0_0_1 + 0.5*G0_0_0_5_1_1_1_0_0 + 0.5*G0_0_0_5_1_1_2_0_1 - 0.5*G0_0_0_5_1_1_3_1_0 - 0.5*G0_0_0_5_1_1_3_1_1 + 0.5*G0_0_0_5_1_1_4_1_0 + 0.5*G0_0_0_5_1_1_5_1_1; + A[11] = 0.0; + A[30] = 0.0; + A[4] = 0.0; + A[25] = 0.0; + A[7] = A[28]; + A[34] = 0.5*G0_1_0_0_0_0_0_0_0 + 0.5*G0_1_0_0_0_0_0_0_1 - 0.5*G0_1_0_0_0_0_1_0_0 - 0.5*G0_1_0_0_0_0_2_0_1 + 0.5*G0_1_0_0_0_0_3_1_0 + 0.5*G0_1_0_0_0_0_3_1_1 - 0.5*G0_1_0_0_0_0_4_1_0 - 0.5*G0_1_0_0_0_0_5_1_1 + 0.5*G0_1_0_0_0_1_0_0_0 + 0.5*G0_1_0_0_0_1_0_0_1 - 0.5*G0_1_0_0_0_1_1_0_0 - 0.5*G0_1_0_0_0_1_2_0_1 + 0.5*G0_1_0_0_0_1_3_1_0 + 0.5*G0_1_0_0_0_1_3_1_1 - 0.5*G0_1_0_0_0_1_4_1_0 - 0.5*G0_1_0_0_0_1_5_1_1 - 0.5*G0_1_0_1_0_0_0_0_0 - 0.5*G0_1_0_1_0_0_0_0_1 + 0.5*G0_1_0_1_0_0_1_0_0 + 0.5*G0_1_0_1_0_0_2_0_1 - 0.5*G0_1_0_1_0_0_3_1_0 - 0.5*G0_1_0_1_0_0_3_1_1 + 0.5*G0_1_0_1_0_0_4_1_0 + 0.5*G0_1_0_1_0_0_5_1_1 - 0.5*G0_1_0_2_0_1_0_0_0 - 0.5*G0_1_0_2_0_1_0_0_1 + 0.5*G0_1_0_2_0_1_1_0_0 + 0.5*G0_1_0_2_0_1_2_0_1 - 0.5*G0_1_0_2_0_1_3_1_0 - 0.5*G0_1_0_2_0_1_3_1_1 + 0.5*G0_1_0_2_0_1_4_1_0 + 0.5*G0_1_0_2_0_1_5_1_1 + 0.5*G0_1_0_3_1_0_0_0_0 + 0.5*G0_1_0_3_1_0_0_0_1 - 0.5*G0_1_0_3_1_0_1_0_0 - 0.5*G0_1_0_3_1_0_2_0_1 + 0.5*G0_1_0_3_1_0_3_1_0 + 0.5*G0_1_0_3_1_0_3_1_1 - 0.5*G0_1_0_3_1_0_4_1_0 - 0.5*G0_1_0_3_1_0_5_1_1 + 0.5*G0_1_0_3_1_1_0_0_0 + 0.5*G0_1_0_3_1_1_0_0_1 - 0.5*G0_1_0_3_1_1_1_0_0 - 0.5*G0_1_0_3_1_1_2_0_1 + 0.5*G0_1_0_3_1_1_3_1_0 + 0.5*G0_1_0_3_1_1_3_1_1 - 0.5*G0_1_0_3_1_1_4_1_0 - 0.5*G0_1_0_3_1_1_5_1_1 - 0.5*G0_1_0_4_1_0_0_0_0 - 0.5*G0_1_0_4_1_0_0_0_1 + 0.5*G0_1_0_4_1_0_1_0_0 + 0.5*G0_1_0_4_1_0_2_0_1 - 0.5*G0_1_0_4_1_0_3_1_0 - 0.5*G0_1_0_4_1_0_3_1_1 + 0.5*G0_1_0_4_1_0_4_1_0 + 0.5*G0_1_0_4_1_0_5_1_1 - 0.5*G0_1_0_5_1_1_0_0_0 - 0.5*G0_1_0_5_1_1_0_0_1 + 0.5*G0_1_0_5_1_1_1_0_0 + 0.5*G0_1_0_5_1_1_2_0_1 - 0.5*G0_1_0_5_1_1_3_1_0 - 0.5*G0_1_0_5_1_1_3_1_1 + 0.5*G0_1_0_5_1_1_4_1_0 + 0.5*G0_1_0_5_1_1_5_1_1; + A[13] = A[34]; + A[33] = -A[34] - 0.5*G0_1_1_0_0_0_0_0_0 - 0.5*G0_1_1_0_0_0_0_0_1 + 0.5*G0_1_1_0_0_0_1_0_0 + 0.5*G0_1_1_0_0_0_2_0_1 - 0.5*G0_1_1_0_0_0_3_1_0 - 0.5*G0_1_1_0_0_0_3_1_1 + 0.5*G0_1_1_0_0_0_4_1_0 + 0.5*G0_1_1_0_0_0_5_1_1 - 0.5*G0_1_1_0_0_1_0_0_0 - 0.5*G0_1_1_0_0_1_0_0_1 + 0.5*G0_1_1_0_0_1_1_0_0 + 0.5*G0_1_1_0_0_1_2_0_1 - 0.5*G0_1_1_0_0_1_3_1_0 - 0.5*G0_1_1_0_0_1_3_1_1 + 0.5*G0_1_1_0_0_1_4_1_0 + 0.5*G0_1_1_0_0_1_5_1_1 + 0.5*G0_1_1_1_0_0_0_0_0 + 0.5*G0_1_1_1_0_0_0_0_1 - 0.5*G0_1_1_1_0_0_1_0_0 - 0.5*G0_1_1_1_0_0_2_0_1 + 0.5*G0_1_1_1_0_0_3_1_0 + 0.5*G0_1_1_1_0_0_3_1_1 - 0.5*G0_1_1_1_0_0_4_1_0 - 0.5*G0_1_1_1_0_0_5_1_1 + 0.5*G0_1_1_2_0_1_0_0_0 + 0.5*G0_1_1_2_0_1_0_0_1 - 0.5*G0_1_1_2_0_1_1_0_0 - 0.5*G0_1_1_2_0_1_2_0_1 + 0.5*G0_1_1_2_0_1_3_1_0 + 0.5*G0_1_1_2_0_1_3_1_1 - 0.5*G0_1_1_2_0_1_4_1_0 - 0.5*G0_1_1_2_0_1_5_1_1 - 0.5*G0_1_1_3_1_0_0_0_0 - 0.5*G0_1_1_3_1_0_0_0_1 + 0.5*G0_1_1_3_1_0_1_0_0 + 0.5*G0_1_1_3_1_0_2_0_1 - 0.5*G0_1_1_3_1_0_3_1_0 - 0.5*G0_1_1_3_1_0_3_1_1 + 0.5*G0_1_1_3_1_0_4_1_0 + 0.5*G0_1_1_3_1_0_5_1_1 - 0.5*G0_1_1_3_1_1_0_0_0 - 0.5*G0_1_1_3_1_1_0_0_1 + 0.5*G0_1_1_3_1_1_1_0_0 + 0.5*G0_1_1_3_1_1_2_0_1 - 0.5*G0_1_1_3_1_1_3_1_0 - 0.5*G0_1_1_3_1_1_3_1_1 + 0.5*G0_1_1_3_1_1_4_1_0 + 0.5*G0_1_1_3_1_1_5_1_1 + 0.5*G0_1_1_4_1_0_0_0_0 + 0.5*G0_1_1_4_1_0_0_0_1 - 0.5*G0_1_1_4_1_0_1_0_0 - 0.5*G0_1_1_4_1_0_2_0_1 + 0.5*G0_1_1_4_1_0_3_1_0 + 0.5*G0_1_1_4_1_0_3_1_1 - 0.5*G0_1_1_4_1_0_4_1_0 - 0.5*G0_1_1_4_1_0_5_1_1 + 0.5*G0_1_1_5_1_1_0_0_0 + 0.5*G0_1_1_5_1_1_0_0_1 - 0.5*G0_1_1_5_1_1_1_0_0 - 0.5*G0_1_1_5_1_1_2_0_1 + 0.5*G0_1_1_5_1_1_3_1_0 + 0.5*G0_1_1_5_1_1_3_1_1 - 0.5*G0_1_1_5_1_1_4_1_0 - 0.5*G0_1_1_5_1_1_5_1_1; + A[1] = -A[34] - 0.5*G0_0_0_0_0_0_0_0_0 - 0.5*G0_0_0_0_0_0_0_0_1 + 0.5*G0_0_0_0_0_0_1_0_0 + 0.5*G0_0_0_0_0_0_2_0_1 - 0.5*G0_0_0_0_0_0_3_1_0 - 0.5*G0_0_0_0_0_0_3_1_1 + 0.5*G0_0_0_0_0_0_4_1_0 + 0.5*G0_0_0_0_0_0_5_1_1 - 0.5*G0_0_0_0_0_1_0_0_0 - 0.5*G0_0_0_0_0_1_0_0_1 + 0.5*G0_0_0_0_0_1_1_0_0 + 0.5*G0_0_0_0_0_1_2_0_1 - 0.5*G0_0_0_0_0_1_3_1_0 - 0.5*G0_0_0_0_0_1_3_1_1 + 0.5*G0_0_0_0_0_1_4_1_0 + 0.5*G0_0_0_0_0_1_5_1_1 + 0.5*G0_0_0_1_0_0_0_0_0 + 0.5*G0_0_0_1_0_0_0_0_1 - 0.5*G0_0_0_1_0_0_1_0_0 - 0.5*G0_0_0_1_0_0_2_0_1 + 0.5*G0_0_0_1_0_0_3_1_0 + 0.5*G0_0_0_1_0_0_3_1_1 - 0.5*G0_0_0_1_0_0_4_1_0 - 0.5*G0_0_0_1_0_0_5_1_1 + 0.5*G0_0_0_2_0_1_0_0_0 + 0.5*G0_0_0_2_0_1_0_0_1 - 0.5*G0_0_0_2_0_1_1_0_0 - 0.5*G0_0_0_2_0_1_2_0_1 + 0.5*G0_0_0_2_0_1_3_1_0 + 0.5*G0_0_0_2_0_1_3_1_1 - 0.5*G0_0_0_2_0_1_4_1_0 - 0.5*G0_0_0_2_0_1_5_1_1 - 0.5*G0_0_0_3_1_0_0_0_0 - 0.5*G0_0_0_3_1_0_0_0_1 + 0.5*G0_0_0_3_1_0_1_0_0 + 0.5*G0_0_0_3_1_0_2_0_1 - 0.5*G0_0_0_3_1_0_3_1_0 - 0.5*G0_0_0_3_1_0_3_1_1 + 0.5*G0_0_0_3_1_0_4_1_0 + 0.5*G0_0_0_3_1_0_5_1_1 - 0.5*G0_0_0_3_1_1_0_0_0 - 0.5*G0_0_0_3_1_1_0_0_1 + 0.5*G0_0_0_3_1_1_1_0_0 + 0.5*G0_0_0_3_1_1_2_0_1 - 0.5*G0_0_0_3_1_1_3_1_0 - 0.5*G0_0_0_3_1_1_3_1_1 + 0.5*G0_0_0_3_1_1_4_1_0 + 0.5*G0_0_0_3_1_1_5_1_1 + 0.5*G0_0_0_4_1_0_0_0_0 + 0.5*G0_0_0_4_1_0_0_0_1 - 0.5*G0_0_0_4_1_0_1_0_0 - 0.5*G0_0_0_4_1_0_2_0_1 + 0.5*G0_0_0_4_1_0_3_1_0 + 0.5*G0_0_0_4_1_0_3_1_1 - 0.5*G0_0_0_4_1_0_4_1_0 - 0.5*G0_0_0_4_1_0_5_1_1 + 0.5*G0_0_0_5_1_1_0_0_0 + 0.5*G0_0_0_5_1_1_0_0_1 - 0.5*G0_0_0_5_1_1_1_0_0 - 0.5*G0_0_0_5_1_1_2_0_1 + 0.5*G0_0_0_5_1_1_3_1_0 + 0.5*G0_0_0_5_1_1_3_1_1 - 0.5*G0_0_0_5_1_1_4_1_0 - 0.5*G0_0_0_5_1_1_5_1_1; + A[29] = A[8]; + A[14] = 0.5*G0_1_1_0_0_0_0_0_0 + 0.5*G0_1_1_0_0_0_0_0_1 - 0.5*G0_1_1_0_0_0_1_0_0 - 0.5*G0_1_1_0_0_0_2_0_1 + 0.5*G0_1_1_0_0_0_3_1_0 + 0.5*G0_1_1_0_0_0_3_1_1 - 0.5*G0_1_1_0_0_0_4_1_0 - 0.5*G0_1_1_0_0_0_5_1_1 + 0.5*G0_1_1_0_0_1_0_0_0 + 0.5*G0_1_1_0_0_1_0_0_1 - 0.5*G0_1_1_0_0_1_1_0_0 - 0.5*G0_1_1_0_0_1_2_0_1 + 0.5*G0_1_1_0_0_1_3_1_0 + 0.5*G0_1_1_0_0_1_3_1_1 - 0.5*G0_1_1_0_0_1_4_1_0 - 0.5*G0_1_1_0_0_1_5_1_1 - 0.5*G0_1_1_1_0_0_0_0_0 - 0.5*G0_1_1_1_0_0_0_0_1 + 0.5*G0_1_1_1_0_0_1_0_0 + 0.5*G0_1_1_1_0_0_2_0_1 - 0.5*G0_1_1_1_0_0_3_1_0 - 0.5*G0_1_1_1_0_0_3_1_1 + 0.5*G0_1_1_1_0_0_4_1_0 + 0.5*G0_1_1_1_0_0_5_1_1 - 0.5*G0_1_1_2_0_1_0_0_0 - 0.5*G0_1_1_2_0_1_0_0_1 + 0.5*G0_1_1_2_0_1_1_0_0 + 0.5*G0_1_1_2_0_1_2_0_1 - 0.5*G0_1_1_2_0_1_3_1_0 - 0.5*G0_1_1_2_0_1_3_1_1 + 0.5*G0_1_1_2_0_1_4_1_0 + 0.5*G0_1_1_2_0_1_5_1_1 + 0.5*G0_1_1_3_1_0_0_0_0 + 0.5*G0_1_1_3_1_0_0_0_1 - 0.5*G0_1_1_3_1_0_1_0_0 - 0.5*G0_1_1_3_1_0_2_0_1 + 0.5*G0_1_1_3_1_0_3_1_0 + 0.5*G0_1_1_3_1_0_3_1_1 - 0.5*G0_1_1_3_1_0_4_1_0 - 0.5*G0_1_1_3_1_0_5_1_1 + 0.5*G0_1_1_3_1_1_0_0_0 + 0.5*G0_1_1_3_1_1_0_0_1 - 0.5*G0_1_1_3_1_1_1_0_0 - 0.5*G0_1_1_3_1_1_2_0_1 + 0.5*G0_1_1_3_1_1_3_1_0 + 0.5*G0_1_1_3_1_1_3_1_1 - 0.5*G0_1_1_3_1_1_4_1_0 - 0.5*G0_1_1_3_1_1_5_1_1 - 0.5*G0_1_1_4_1_0_0_0_0 - 0.5*G0_1_1_4_1_0_0_0_1 + 0.5*G0_1_1_4_1_0_1_0_0 + 0.5*G0_1_1_4_1_0_2_0_1 - 0.5*G0_1_1_4_1_0_3_1_0 - 0.5*G0_1_1_4_1_0_3_1_1 + 0.5*G0_1_1_4_1_0_4_1_0 + 0.5*G0_1_1_4_1_0_5_1_1 - 0.5*G0_1_1_5_1_1_0_0_0 - 0.5*G0_1_1_5_1_1_0_0_1 + 0.5*G0_1_1_5_1_1_1_0_0 + 0.5*G0_1_1_5_1_1_2_0_1 - 0.5*G0_1_1_5_1_1_3_1_0 - 0.5*G0_1_1_5_1_1_3_1_1 + 0.5*G0_1_1_5_1_1_4_1_0 + 0.5*G0_1_1_5_1_1_5_1_1; + A[10] = 0.0; + A[5] = 0.0; + A[26] = 0.0; + A[6] = -A[8] - 0.5*G0_0_0_0_0_0_0_0_0 - 0.5*G0_0_0_0_0_0_0_0_1 + 0.5*G0_0_0_0_0_0_1_0_0 + 0.5*G0_0_0_0_0_0_2_0_1 - 0.5*G0_0_0_0_0_0_3_1_0 - 0.5*G0_0_0_0_0_0_3_1_1 + 0.5*G0_0_0_0_0_0_4_1_0 + 0.5*G0_0_0_0_0_0_5_1_1 - 0.5*G0_0_0_0_0_1_0_0_0 - 0.5*G0_0_0_0_0_1_0_0_1 + 0.5*G0_0_0_0_0_1_1_0_0 + 0.5*G0_0_0_0_0_1_2_0_1 - 0.5*G0_0_0_0_0_1_3_1_0 - 0.5*G0_0_0_0_0_1_3_1_1 + 0.5*G0_0_0_0_0_1_4_1_0 + 0.5*G0_0_0_0_0_1_5_1_1 + 0.5*G0_0_0_1_0_0_0_0_0 + 0.5*G0_0_0_1_0_0_0_0_1 - 0.5*G0_0_0_1_0_0_1_0_0 - 0.5*G0_0_0_1_0_0_2_0_1 + 0.5*G0_0_0_1_0_0_3_1_0 + 0.5*G0_0_0_1_0_0_3_1_1 - 0.5*G0_0_0_1_0_0_4_1_0 - 0.5*G0_0_0_1_0_0_5_1_1 + 0.5*G0_0_0_2_0_1_0_0_0 + 0.5*G0_0_0_2_0_1_0_0_1 - 0.5*G0_0_0_2_0_1_1_0_0 - 0.5*G0_0_0_2_0_1_2_0_1 + 0.5*G0_0_0_2_0_1_3_1_0 + 0.5*G0_0_0_2_0_1_3_1_1 - 0.5*G0_0_0_2_0_1_4_1_0 - 0.5*G0_0_0_2_0_1_5_1_1 - 0.5*G0_0_0_3_1_0_0_0_0 - 0.5*G0_0_0_3_1_0_0_0_1 + 0.5*G0_0_0_3_1_0_1_0_0 + 0.5*G0_0_0_3_1_0_2_0_1 - 0.5*G0_0_0_3_1_0_3_1_0 - 0.5*G0_0_0_3_1_0_3_1_1 + 0.5*G0_0_0_3_1_0_4_1_0 + 0.5*G0_0_0_3_1_0_5_1_1 - 0.5*G0_0_0_3_1_1_0_0_0 - 0.5*G0_0_0_3_1_1_0_0_1 + 0.5*G0_0_0_3_1_1_1_0_0 + 0.5*G0_0_0_3_1_1_2_0_1 - 0.5*G0_0_0_3_1_1_3_1_0 - 0.5*G0_0_0_3_1_1_3_1_1 + 0.5*G0_0_0_3_1_1_4_1_0 + 0.5*G0_0_0_3_1_1_5_1_1 + 0.5*G0_0_0_4_1_0_0_0_0 + 0.5*G0_0_0_4_1_0_0_0_1 - 0.5*G0_0_0_4_1_0_1_0_0 - 0.5*G0_0_0_4_1_0_2_0_1 + 0.5*G0_0_0_4_1_0_3_1_0 + 0.5*G0_0_0_4_1_0_3_1_1 - 0.5*G0_0_0_4_1_0_4_1_0 - 0.5*G0_0_0_4_1_0_5_1_1 + 0.5*G0_0_0_5_1_1_0_0_0 + 0.5*G0_0_0_5_1_1_0_0_1 - 0.5*G0_0_0_5_1_1_1_0_0 - 0.5*G0_0_0_5_1_1_2_0_1 + 0.5*G0_0_0_5_1_1_3_1_0 + 0.5*G0_0_0_5_1_1_3_1_1 - 0.5*G0_0_0_5_1_1_4_1_0 - 0.5*G0_0_0_5_1_1_5_1_1; + A[35] = A[14]; + A[23] = -A[8] - 0.5*G0_1_1_0_0_0_0_0_0 - 0.5*G0_1_1_0_0_0_0_0_1 + 0.5*G0_1_1_0_0_0_1_0_0 + 0.5*G0_1_1_0_0_0_2_0_1 - 0.5*G0_1_1_0_0_0_3_1_0 - 0.5*G0_1_1_0_0_0_3_1_1 + 0.5*G0_1_1_0_0_0_4_1_0 + 0.5*G0_1_1_0_0_0_5_1_1 - 0.5*G0_1_1_0_0_1_0_0_0 - 0.5*G0_1_1_0_0_1_0_0_1 + 0.5*G0_1_1_0_0_1_1_0_0 + 0.5*G0_1_1_0_0_1_2_0_1 - 0.5*G0_1_1_0_0_1_3_1_0 - 0.5*G0_1_1_0_0_1_3_1_1 + 0.5*G0_1_1_0_0_1_4_1_0 + 0.5*G0_1_1_0_0_1_5_1_1 + 0.5*G0_1_1_1_0_0_0_0_0 + 0.5*G0_1_1_1_0_0_0_0_1 - 0.5*G0_1_1_1_0_0_1_0_0 - 0.5*G0_1_1_1_0_0_2_0_1 + 0.5*G0_1_1_1_0_0_3_1_0 + 0.5*G0_1_1_1_0_0_3_1_1 - 0.5*G0_1_1_1_0_0_4_1_0 - 0.5*G0_1_1_1_0_0_5_1_1 + 0.5*G0_1_1_2_0_1_0_0_0 + 0.5*G0_1_1_2_0_1_0_0_1 - 0.5*G0_1_1_2_0_1_1_0_0 - 0.5*G0_1_1_2_0_1_2_0_1 + 0.5*G0_1_1_2_0_1_3_1_0 + 0.5*G0_1_1_2_0_1_3_1_1 - 0.5*G0_1_1_2_0_1_4_1_0 - 0.5*G0_1_1_2_0_1_5_1_1 - 0.5*G0_1_1_3_1_0_0_0_0 - 0.5*G0_1_1_3_1_0_0_0_1 + 0.5*G0_1_1_3_1_0_1_0_0 + 0.5*G0_1_1_3_1_0_2_0_1 - 0.5*G0_1_1_3_1_0_3_1_0 - 0.5*G0_1_1_3_1_0_3_1_1 + 0.5*G0_1_1_3_1_0_4_1_0 + 0.5*G0_1_1_3_1_0_5_1_1 - 0.5*G0_1_1_3_1_1_0_0_0 - 0.5*G0_1_1_3_1_1_0_0_1 + 0.5*G0_1_1_3_1_1_1_0_0 + 0.5*G0_1_1_3_1_1_2_0_1 - 0.5*G0_1_1_3_1_1_3_1_0 - 0.5*G0_1_1_3_1_1_3_1_1 + 0.5*G0_1_1_3_1_1_4_1_0 + 0.5*G0_1_1_3_1_1_5_1_1 + 0.5*G0_1_1_4_1_0_0_0_0 + 0.5*G0_1_1_4_1_0_0_0_1 - 0.5*G0_1_1_4_1_0_1_0_0 - 0.5*G0_1_1_4_1_0_2_0_1 + 0.5*G0_1_1_4_1_0_3_1_0 + 0.5*G0_1_1_4_1_0_3_1_1 - 0.5*G0_1_1_4_1_0_4_1_0 - 0.5*G0_1_1_4_1_0_5_1_1 + 0.5*G0_1_1_5_1_1_0_0_0 + 0.5*G0_1_1_5_1_1_0_0_1 - 0.5*G0_1_1_5_1_1_1_0_0 - 0.5*G0_1_1_5_1_1_2_0_1 + 0.5*G0_1_1_5_1_1_3_1_0 + 0.5*G0_1_1_5_1_1_3_1_1 - 0.5*G0_1_1_5_1_1_4_1_0 - 0.5*G0_1_1_5_1_1_5_1_1; + A[21] = -A[23] + 0.5*G0_0_0_0_0_0_0_0_0 + 0.5*G0_0_0_0_0_0_0_0_1 - 0.5*G0_0_0_0_0_0_1_0_0 - 0.5*G0_0_0_0_0_0_2_0_1 + 0.5*G0_0_0_0_0_0_3_1_0 + 0.5*G0_0_0_0_0_0_3_1_1 - 0.5*G0_0_0_0_0_0_4_1_0 - 0.5*G0_0_0_0_0_0_5_1_1 + 0.5*G0_0_0_0_0_1_0_0_0 + 0.5*G0_0_0_0_0_1_0_0_1 - 0.5*G0_0_0_0_0_1_1_0_0 - 0.5*G0_0_0_0_0_1_2_0_1 + 0.5*G0_0_0_0_0_1_3_1_0 + 0.5*G0_0_0_0_0_1_3_1_1 - 0.5*G0_0_0_0_0_1_4_1_0 - 0.5*G0_0_0_0_0_1_5_1_1 - 0.5*G0_0_0_1_0_0_0_0_0 - 0.5*G0_0_0_1_0_0_0_0_1 + 0.5*G0_0_0_1_0_0_1_0_0 + 0.5*G0_0_0_1_0_0_2_0_1 - 0.5*G0_0_0_1_0_0_3_1_0 - 0.5*G0_0_0_1_0_0_3_1_1 + 0.5*G0_0_0_1_0_0_4_1_0 + 0.5*G0_0_0_1_0_0_5_1_1 - 0.5*G0_0_0_2_0_1_0_0_0 - 0.5*G0_0_0_2_0_1_0_0_1 + 0.5*G0_0_0_2_0_1_1_0_0 + 0.5*G0_0_0_2_0_1_2_0_1 - 0.5*G0_0_0_2_0_1_3_1_0 - 0.5*G0_0_0_2_0_1_3_1_1 + 0.5*G0_0_0_2_0_1_4_1_0 + 0.5*G0_0_0_2_0_1_5_1_1 + 0.5*G0_0_0_3_1_0_0_0_0 + 0.5*G0_0_0_3_1_0_0_0_1 - 0.5*G0_0_0_3_1_0_1_0_0 - 0.5*G0_0_0_3_1_0_2_0_1 + 0.5*G0_0_0_3_1_0_3_1_0 + 0.5*G0_0_0_3_1_0_3_1_1 - 0.5*G0_0_0_3_1_0_4_1_0 - 0.5*G0_0_0_3_1_0_5_1_1 + 0.5*G0_0_0_3_1_1_0_0_0 + 0.5*G0_0_0_3_1_1_0_0_1 - 0.5*G0_0_0_3_1_1_1_0_0 - 0.5*G0_0_0_3_1_1_2_0_1 + 0.5*G0_0_0_3_1_1_3_1_0 + 0.5*G0_0_0_3_1_1_3_1_1 - 0.5*G0_0_0_3_1_1_4_1_0 - 0.5*G0_0_0_3_1_1_5_1_1 - 0.5*G0_0_0_4_1_0_0_0_0 - 0.5*G0_0_0_4_1_0_0_0_1 + 0.5*G0_0_0_4_1_0_1_0_0 + 0.5*G0_0_0_4_1_0_2_0_1 - 0.5*G0_0_0_4_1_0_3_1_0 - 0.5*G0_0_0_4_1_0_3_1_1 + 0.5*G0_0_0_4_1_0_4_1_0 + 0.5*G0_0_0_4_1_0_5_1_1 - 0.5*G0_0_0_5_1_1_0_0_0 - 0.5*G0_0_0_5_1_1_0_0_1 + 0.5*G0_0_0_5_1_1_1_0_0 + 0.5*G0_0_0_5_1_1_2_0_1 - 0.5*G0_0_0_5_1_1_3_1_0 - 0.5*G0_0_0_5_1_1_3_1_1 + 0.5*G0_0_0_5_1_1_4_1_0 + 0.5*G0_0_0_5_1_1_5_1_1 + 0.5*G0_1_0_0_0_0_0_0_0 + 0.5*G0_1_0_0_0_0_0_0_1 - 0.5*G0_1_0_0_0_0_1_0_0 - 0.5*G0_1_0_0_0_0_2_0_1 + 0.5*G0_1_0_0_0_0_3_1_0 + 0.5*G0_1_0_0_0_0_3_1_1 - 0.5*G0_1_0_0_0_0_4_1_0 - 0.5*G0_1_0_0_0_0_5_1_1 + 0.5*G0_1_0_0_0_1_0_0_0 + 0.5*G0_1_0_0_0_1_0_0_1 - 0.5*G0_1_0_0_0_1_1_0_0 - 0.5*G0_1_0_0_0_1_2_0_1 + 0.5*G0_1_0_0_0_1_3_1_0 + 0.5*G0_1_0_0_0_1_3_1_1 - 0.5*G0_1_0_0_0_1_4_1_0 - 0.5*G0_1_0_0_0_1_5_1_1 - 0.5*G0_1_0_1_0_0_0_0_0 - 0.5*G0_1_0_1_0_0_0_0_1 + 0.5*G0_1_0_1_0_0_1_0_0 + 0.5*G0_1_0_1_0_0_2_0_1 - 0.5*G0_1_0_1_0_0_3_1_0 - 0.5*G0_1_0_1_0_0_3_1_1 + 0.5*G0_1_0_1_0_0_4_1_0 + 0.5*G0_1_0_1_0_0_5_1_1 - 0.5*G0_1_0_2_0_1_0_0_0 - 0.5*G0_1_0_2_0_1_0_0_1 + 0.5*G0_1_0_2_0_1_1_0_0 + 0.5*G0_1_0_2_0_1_2_0_1 - 0.5*G0_1_0_2_0_1_3_1_0 - 0.5*G0_1_0_2_0_1_3_1_1 + 0.5*G0_1_0_2_0_1_4_1_0 + 0.5*G0_1_0_2_0_1_5_1_1 + 0.5*G0_1_0_3_1_0_0_0_0 + 0.5*G0_1_0_3_1_0_0_0_1 - 0.5*G0_1_0_3_1_0_1_0_0 - 0.5*G0_1_0_3_1_0_2_0_1 + 0.5*G0_1_0_3_1_0_3_1_0 + 0.5*G0_1_0_3_1_0_3_1_1 - 0.5*G0_1_0_3_1_0_4_1_0 - 0.5*G0_1_0_3_1_0_5_1_1 + 0.5*G0_1_0_3_1_1_0_0_0 + 0.5*G0_1_0_3_1_1_0_0_1 - 0.5*G0_1_0_3_1_1_1_0_0 - 0.5*G0_1_0_3_1_1_2_0_1 + 0.5*G0_1_0_3_1_1_3_1_0 + 0.5*G0_1_0_3_1_1_3_1_1 - 0.5*G0_1_0_3_1_1_4_1_0 - 0.5*G0_1_0_3_1_1_5_1_1 - 0.5*G0_1_0_4_1_0_0_0_0 - 0.5*G0_1_0_4_1_0_0_0_1 + 0.5*G0_1_0_4_1_0_1_0_0 + 0.5*G0_1_0_4_1_0_2_0_1 - 0.5*G0_1_0_4_1_0_3_1_0 - 0.5*G0_1_0_4_1_0_3_1_1 + 0.5*G0_1_0_4_1_0_4_1_0 + 0.5*G0_1_0_4_1_0_5_1_1 - 0.5*G0_1_0_5_1_1_0_0_0 - 0.5*G0_1_0_5_1_1_0_0_1 + 0.5*G0_1_0_5_1_1_1_0_0 + 0.5*G0_1_0_5_1_1_2_0_1 - 0.5*G0_1_0_5_1_1_3_1_0 - 0.5*G0_1_0_5_1_1_3_1_1 + 0.5*G0_1_0_5_1_1_4_1_0 + 0.5*G0_1_0_5_1_1_5_1_1; + A[0] = A[21]; + A[22] = A[1]; + A[19] = 0.0; + A[16] = 0.0; + A[12] = A[33]; + A[27] = A[6]; + A[15] = 0.0; + A[32] = 0.0; + A[2] = A[23]; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f2_p1_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), Product(IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 2; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q1_tensor_finite_element_1(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q1_tensor_finite_element_1(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q1_tensor_finite_element_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q1_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q1_tensor_dofmap_1(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q1_tensor_dofmap_1(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q1_tensor_dofmap_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q1_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q1_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q2_excafe.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q2_excafe.h new file mode 100644 index 0000000..871ba2f --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q2_excafe.h @@ -0,0 +1,315 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 1 minute and 9.64 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = -x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -x[0][0]; + const double var_3 = x[1][0] + var_2; + const double var_4 = -var_1*var_3*w[0][0]*w[1][3]; + const double var_5 = x[1][1] + var_0; + const double var_6 = x[2][0] + var_2; + const double var_7 = -var_5*var_6*w[0][3]*w[1][0]; + const double var_8 = w[0][0]*w[1][3] + w[0][3]*w[1][0]; + const double var_9 = var_3*var_5*var_8; + const double var_10 = var_4 + var_9 + var_7; + const double var_11 = var_1*var_1*var_5*var_5*w[0][0]*w[1][0] + var_3*var_3*var_6*var_6*w[0][3]*w[1][3]; + const double var_12 = var_3*w[0][5] + var_1*w[0][1]; + const double var_13 = var_5*w[0][2] + var_6*w[0][4]; + const double var_14 = var_12 + -var_13; + const double var_15 = -var_3*w[0][3] + var_14; + const double var_16 = -var_12 + var_13; + const double var_17 = -var_5*w[0][0] + var_16; + const double var_18 = var_1*w[1][1] + var_3*w[1][5]; + const double var_19 = var_6*w[1][4] + var_5*w[1][2]; + const double var_20 = var_3*w[0][3]; + const double var_21 = var_17 + var_20; + const double var_22 = var_5*w[0][0]; + const double var_23 = var_15 + var_22; + const double var_24 = var_21*var_3*w[1][3] + var_23*var_5*w[1][0]; + const double var_25 = var_15*var_18 + var_17*var_19 + var_24; + const double var_26 = var_1*w[1][0] + var_19; + const double var_27 = -var_18 + var_26; + const double var_28 = var_3*w[1][3] + var_27; + const double var_29 = var_16*w[1][0]; + const double var_30 = var_28*w[0][0] + var_29; + const double var_31 = var_26*var_3*w[0][3] + var_1*var_30 + var_18*var_5*w[0][0]; + const double var_32 = var_6*w[1][3] + var_18; + const double var_33 = -var_19 + var_32; + const double var_34 = var_14*w[1][3]; + const double var_35 = var_33*w[0][3] + var_34; + const double var_36 = var_6*w[0][3]*w[1][0]; + const double var_37 = var_36 + var_32*w[0][0]; + const double var_38 = var_35*var_6 + var_19*var_3*w[0][3] + var_37*var_5; + const double var_39 = var_3*var_3; + const double var_40 = var_5*var_5; + const double var_41 = var_39 + var_40; + const double var_42 = var_38*var_5*var_5 + var_3*var_3*var_31 + var_25*var_41; + const double var_43 = var_1*var_5*var_5*var_5*w[0][0]*w[1][0] + var_3*var_3*var_3*var_6*w[0][3]*w[1][3]; + const double var_44 = -var_43 + 0.3333333333333333148296163*var_42; + const double var_45 = var_44 + var_11; + const double var_46 = var_33*w[0][0] + var_36; + const double var_47 = var_22 + var_14; + const double var_48 = var_46 + var_47*w[1][0]; + const double var_49 = var_1*w[0][0]*w[1][3] + var_27*w[0][3]; + const double var_50 = var_20 + var_16; + const double var_51 = var_49 + var_50*w[1][3]; + const double var_52 = var_1*var_51 + var_48*var_6; + const double var_53 = var_1*var_3 + -var_5*var_6; + const double var_54 = var_53; + const double var_55 = std::abs(var_54); + const double var_56 = var_53; + const double var_57 = -var_26; + const double var_58 = var_32 + var_57; + const double var_59 = -var_32; + const double var_60 = var_26 + var_59; + const double var_61 = var_58*var_6*w[0][3] + var_1*var_60*w[0][0] + var_16*var_26 + var_14*var_32; + const double var_62 = var_1*var_5 + var_3*var_6; + const double var_63 = var_18*w[0][3] + var_15*w[1][3]; + const double var_64 = var_3*var_63; + const double var_65 = var_19*w[0][0] + var_17*w[1][0]; + const double var_66 = var_5*var_65; + const double var_67 = var_66 + var_64 + var_9; + const double var_68 = var_18 + var_57; + const double var_69 = var_1*var_68*w[0][0] + var_17*var_18; + const double var_70 = var_4 + var_15*var_26; + const double var_71 = var_69 + var_70; + const double var_72 = var_1*var_5*w[0][0]*w[1][0]; + const double var_73 = var_17*w[1][3] + var_49; + const double var_74 = var_6*var_73; + const double var_75 = var_7 + var_74 + var_72; + const double var_76 = -var_1*var_5*var_6*w[0][0]*w[1][0] + var_3*var_75; + const double var_77 = 2.0000000000000000000000000*var_76 + var_3*var_71 + var_5*var_52; + const double var_78 = var_3*var_6*w[0][3]*w[1][3]; + const double var_79 = var_15*w[1][0] + var_46; + const double var_80 = var_1*var_79; + const double var_81 = var_4 + var_80 + var_78; + const double var_82 = -var_1*var_3*var_6*w[0][3]*w[1][3] + var_5*var_81; + const double var_83 = var_19 + var_59; + const double var_84 = var_15*var_19 + var_6*var_83*w[0][3]; + const double var_85 = var_17*var_32 + var_7; + const double var_86 = var_84 + var_85; + const double var_87 = 2.0000000000000000000000000*var_82 + var_5*var_86; + const double var_88 = var_3*var_77 + var_61*var_62 + var_5*var_87 + var_41*var_67; + const double var_89 = -var_11; + const double var_90 = 0.3333333333333333148296163*var_88 + var_89 + var_43; + A[41] = 4.0000000000000000000000000*var_55*var_90/(var_56*var_56*var_56*var_56); + A[63] = A[41]; + const double var_91 = var_83*w[0][0] + var_29; + const double var_92 = var_5*var_91; + A[31] = 0.0000000000000000000000000; + const double var_93 = var_1*var_58*w[0][0] + var_6*var_60*w[0][3]; + const double var_94 = var_1*var_1; + const double var_95 = var_6*var_6; + const double var_96 = var_94 + var_95; + const double var_97 = var_68*w[0][3] + var_34; + const double var_98 = var_3*var_97; + const double var_99 = var_72 + var_4 + var_98; + const double var_100 = -var_1*var_3*var_5*w[0][0]*w[1][0] + var_6*var_99; + const double var_101 = var_7 + var_92 + var_78; + const double var_102 = -var_3*var_5*var_6*w[0][3]*w[1][3] + var_1*var_101; + const double var_103 = var_3*var_5*var_8*var_96 + var_100*var_6 + var_1*var_102; + const double var_104 = var_16*var_32 + var_64; + const double var_105 = var_70 + var_104; + const double var_106 = var_1*var_105 + var_38*var_5; + const double var_107 = var_66 + var_14*var_26; + const double var_108 = var_85 + var_107; + const double var_109 = var_108*var_6 + var_3*var_31; + const double var_110 = var_1*var_106 + var_109*var_6 + var_93*var_96 + var_25*var_62 + 2.0000000000000000000000000*var_103; + const double var_111 = var_3*var_6*var_6*var_6*w[0][3]*w[1][3] + var_1*var_1*var_1*var_5*w[0][0]*w[1][0]; + const double var_112 = var_111 + 0.3333333333333333148296163*var_110 + var_89; + A[40] = 4.0000000000000000000000000*var_112*var_55/(var_56*var_56*var_56*var_56); + A[67] = 0.0000000000000000000000000; + A[98] = 0.0000000000000000000000000; + A[19] = 0.0000000000000000000000000; + A[72] = 0.0000000000000000000000000; + const double var_113 = var_46*var_5 + var_3*var_49 + var_24 + var_61; + const double var_114 = var_72 + var_78; + const double var_115 = 0.5000000000000000000000000*var_113 + -var_114; + A[14] = 0.3333333333333333148296163*var_115*var_55*var_62/(var_56*var_56*var_56*var_56); + A[94] = 0.0000000000000000000000000; + A[4] = 2.0000000000000000000000000*var_55*var_90/(var_56*var_56*var_56*var_56); + A[126] = A[4]; + A[75] = 0.0000000000000000000000000; + const double var_116 = var_100*var_3 + var_102*var_5 + var_62*var_9; + A[121] = 0.0000000000000000000000000; + A[77] = 0.0000000000000000000000000; + A[133] = 0.0000000000000000000000000; + A[49] = 0.0000000000000000000000000; + A[34] = 0.0000000000000000000000000; + const double var_117 = w[0][0]*w[1][0] + w[0][3]*w[1][3]; + const double var_118 = 2.0000000000000000000000000*var_1*var_117*var_5 + var_107 + var_69; + const double var_119 = var_84 + var_104; + const double var_120 = var_118*var_3*var_6 + var_1*var_119*var_5; + const double var_121 = var_48*var_5*var_6*var_6 + var_61*var_96 + var_1*var_1*var_3*var_51; + const double var_122 = 0.3333333333333333148296163*var_121 + -var_111; + const double var_123 = var_74 + var_98; + const double var_124 = var_80 + var_92; + const double var_125 = var_1*var_124*var_5 + var_123*var_3*var_6 + var_10*var_62; + const double var_126 = var_94 + var_40; + const double var_127 = var_39 + var_95; + const double var_128 = -var_126*var_3*var_6*w[0][3]*w[1][3] + -var_1*var_127*var_5*w[0][0]*w[1][0]; + const double var_129 = var_125 + 2.0000000000000000000000000*var_11 + var_128; + const double var_130 = var_44 + 0.3333333333333333148296163*var_120 + var_122 + 0.6666666666666666296592325*var_129; + A[39] = 4.0000000000000000000000000*var_130*var_55/(var_56*var_56*var_56*var_56); + A[55] = 0.0000000000000000000000000; + A[106] = A[4]; + A[130] = A[39]; + const double var_131 = var_43 + var_111; + A[140] = 0.0000000000000000000000000; + A[136] = 0.0000000000000000000000000; + A[118] = A[40]; + A[119] = A[41]; + A[7] = 0.0000000000000000000000000; + A[51] = A[40]; + A[123] = 0.0000000000000000000000000; + A[135] = 0.0000000000000000000000000; + const double var_132 = var_42 + var_121; + const double var_133 = -2.0000000000000000000000000*var_131 + 0.5000000000000000000000000*var_132 + 3.0000000000000000000000000*var_11 + var_120 + var_128 + 1.5000000000000000000000000*var_125; + A[43] = 0.0000000000000000000000000; + const double var_134 = var_93 + var_67 + var_70 + var_85 + 2.0000000000000000000000000*var_114; + A[15] = 0.6666666666666666296592325*var_134*var_55*var_62/(var_56*var_56*var_56*var_56); + A[93] = A[15]; + A[132] = 0.0000000000000000000000000; + A[65] = A[39]; + A[46] = 0.0000000000000000000000000; + A[28] = A[4]; + const double var_135 = var_62*var_67 + var_3*var_6*var_71 + var_1*var_5*var_86; + const double var_136 = var_6*var_76 + var_1*var_82; + const double var_137 = var_11 + var_122; + const double var_138 = 0.3333333333333333148296163*var_136 + 0.5000000000000000000000000*var_137 + 0.1666666666666666574148081*var_135; + A[1] = var_138*var_55/(var_56*var_56*var_56*var_56); + A[90] = A[1]; + A[53] = 1.3333333333333332593184650*var_134*var_55*var_62/(var_56*var_56*var_56*var_56); + A[142] = A[53]; + A[73] = 0.0000000000000000000000000; + A[97] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[107] = 0.0000000000000000000000000; + A[108] = 0.0000000000000000000000000; + A[69] = 0.0000000000000000000000000; + A[27] = A[15]; + A[12] = A[1]; + A[38] = A[15]; + A[42] = 0.0000000000000000000000000; + A[117] = A[39]; + A[5] = 2.0000000000000000000000000*var_112*var_55/(var_56*var_56*var_56*var_56); + A[139] = A[5]; + A[37] = A[15]; + A[127] = 0.0000000000000000000000000; + A[17] = A[5]; + A[86] = 0.0000000000000000000000000; + A[13] = var_115*var_55*var_96/(var_56*var_56*var_56*var_56); + A[22] = 0.0000000000000000000000000; + A[110] = 0.0000000000000000000000000; + A[109] = 0.0000000000000000000000000; + A[33] = 0.0000000000000000000000000; + A[95] = A[5]; + A[111] = 0.0000000000000000000000000; + const double var_139 = var_1*var_105*var_5 + var_62*var_93 + var_108*var_3*var_6; + const double var_140 = 0.3333333333333333148296163*var_116 + 0.5000000000000000000000000*var_45 + 0.1666666666666666574148081*var_139; + A[2] = var_140*var_55/(var_56*var_56*var_56*var_56); + A[70] = 0.0000000000000000000000000; + A[24] = A[2]; + A[3] = 0.0000000000000000000000000; + A[60] = A[5]; + A[116] = A[15]; + A[62] = 0.0000000000000000000000000; + A[25] = A[14]; + A[141] = A[41]; + A[74] = 0.0000000000000000000000000; + A[52] = A[39]; + A[54] = 0.0000000000000000000000000; + A[71] = 0.0000000000000000000000000; + A[21] = 0.0000000000000000000000000; + A[114] = 0.0000000000000000000000000; + A[102] = A[2]; + A[44] = 0.0000000000000000000000000; + A[81] = 0.0000000000000000000000000; + A[99] = 0.0000000000000000000000000; + A[143] = A[39]; + A[61] = A[5]; + A[6] = 0.0000000000000000000000000; + A[26] = var_115*var_41*var_55/(var_56*var_56*var_56*var_56); + A[82] = A[4]; + A[120] = 0.0000000000000000000000000; + A[100] = 0.0000000000000000000000000; + A[47] = 0.0000000000000000000000000; + A[134] = 0.0000000000000000000000000; + A[96] = 0.0000000000000000000000000; + A[124] = 0.0000000000000000000000000; + A[9] = 0.0000000000000000000000000; + A[84] = 0.0000000000000000000000000; + A[113] = 0.0000000000000000000000000; + A[57] = 0.0000000000000000000000000; + A[129] = A[40]; + A[87] = 0.0000000000000000000000000; + A[85] = 0.0000000000000000000000000; + A[64] = A[53]; + A[16] = 0.0000000000000000000000000; + A[59] = 0.0000000000000000000000000; + A[137] = 0.0000000000000000000000000; + A[92] = A[14]; + A[101] = 0.0000000000000000000000000; + A[23] = 0.0000000000000000000000000; + A[83] = A[5]; + A[56] = 0.0000000000000000000000000; + A[36] = 0.0000000000000000000000000; + A[11] = 0.0000000000000000000000000; + A[79] = A[1]; + A[89] = 0.0000000000000000000000000; + A[8] = 0.0000000000000000000000000; + A[103] = A[14]; + A[0] = var_133*var_55/(var_56*var_56*var_56*var_56); + A[48] = A[4]; + A[112] = 0.0000000000000000000000000; + A[20] = 0.0000000000000000000000000; + A[104] = A[26]; + A[10] = 0.0000000000000000000000000; + A[80] = A[2]; + A[32] = 0.0000000000000000000000000; + A[105] = A[15]; + A[138] = A[5]; + A[29] = 0.0000000000000000000000000; + A[122] = 0.0000000000000000000000000; + A[35] = 0.0000000000000000000000000; + A[76] = 0.0000000000000000000000000; + A[78] = A[0]; + A[131] = A[53]; + A[30] = 0.0000000000000000000000000; + A[50] = A[4]; + A[58] = 0.0000000000000000000000000; + A[91] = A[13]; + A[66] = 0.0000000000000000000000000; + A[128] = A[4]; + A[125] = 0.0000000000000000000000000; + A[115] = A[15]; + A[68] = 0.0000000000000000000000000; + A[88] = 0.0000000000000000000000000; + A[45] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q2_quadrature.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q2_quadrature.h new file mode 100644 index 0000000..79dc6f2 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q2_quadrature.h @@ -0,0 +1,8500 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F2_P1_Q2_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F2_P1_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q2_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q2_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q2_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q2_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q2_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q2_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q2_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q2_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q2_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f2_p1_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W3[3] = {0.166666666666667, 0.166666666666667, 0.166666666666667}; + // Quadrature points on the UFC reference element: (0.166666666666667, 0.166666666666667), (0.166666666666667, 0.666666666666667), (0.666666666666667, 0.166666666666667) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[3][2] = \ + {{-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + static const double FE1_C0_D01[3][5] = \ + {{-1.66666666666667, -0.333333333333333, 0.666666666666666, 2.0, -0.666666666666666}, + {0.333333333333333, 1.66666666666667, 0.666666666666666, -2, -0.666666666666666}, + {0.333333333333333, -0.333333333333333, 2.66666666666666, 0.0, -2.66666666666667}}; + + // Array of non-zero columns + static const unsigned int nzc10[5] = {6, 8, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc7[5] = {0, 2, 3, 4, 5}; + + static const double FE1_C0_D10[3][5] = \ + {{-1.66666666666667, -0.333333333333334, 0.666666666666666, -0.666666666666666, 2.0}, + {0.333333333333334, -0.333333333333334, 2.66666666666667, -2.66666666666667, 0.0}, + {0.333333333333333, 1.66666666666667, 0.666666666666666, -0.666666666666666, -2.0}}; + + // Array of non-zero columns + static const unsigned int nzc11[5] = {6, 7, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc8[5] = {0, 1, 3, 4, 5}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 144; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 180. + double G[30]; + G[0] = K_00*K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_00*K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_00*K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_00*K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_10*K_10*det*(K_10*K_10 + K_11*K_11); + G[5] = K_01*K_10*det*(K_10*K_10 + K_11*K_11); + G[6] = K_10*K_11*det*(K_10*K_10 + K_11*K_11); + G[7] = K_01*K_01*det*(K_10*K_10 + K_11*K_11); + G[8] = K_01*K_11*det*(K_10*K_10 + K_11*K_11); + G[9] = K_11*K_11*det*(K_10*K_10 + K_11*K_11); + G[10] = K_00*K_00*det*(K_00*K_10 + K_01*K_11); + G[11] = K_00*K_10*det*(K_00*K_10 + K_01*K_11); + G[12] = K_00*K_01*det*(K_00*K_10 + K_01*K_11); + G[13] = K_00*K_11*det*(K_00*K_10 + K_01*K_11); + G[14] = K_10*K_10*det*(K_00*K_10 + K_01*K_11); + G[15] = K_01*K_10*det*(K_00*K_10 + K_01*K_11); + G[16] = K_10*K_11*det*(K_00*K_10 + K_01*K_11); + G[17] = K_01*K_01*det*(K_00*K_10 + K_01*K_11); + G[18] = K_01*K_11*det*(K_00*K_10 + K_01*K_11); + G[19] = K_11*K_11*det*(K_00*K_10 + K_01*K_11); + G[20] = K_00*K_00*det*(K_00*K_00 + K_01*K_01); + G[21] = K_00*K_10*det*(K_00*K_00 + K_01*K_01); + G[22] = K_00*K_01*det*(K_00*K_00 + K_01*K_01); + G[23] = K_00*K_11*det*(K_00*K_00 + K_01*K_01); + G[24] = K_10*K_10*det*(K_00*K_00 + K_01*K_01); + G[25] = K_01*K_10*det*(K_00*K_00 + K_01*K_01); + G[26] = K_10*K_11*det*(K_00*K_00 + K_01*K_01); + G[27] = K_01*K_01*det*(K_00*K_00 + K_01*K_01); + G[28] = K_01*K_11*det*(K_00*K_00 + K_01*K_01); + G[29] = K_11*K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 2220 + for (unsigned int ip = 0; ip < 3; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + double F4 = 0.0; + double F5 = 0.0; + double F6 = 0.0; + double F7 = 0.0; + + // Total number of operations to compute function values = 32 + for (unsigned int r = 0; r < 2; r++) + { + F0 += FE0_C0_D01[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D01[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + F4 += FE0_C0_D01[ip][r]*w[1][nzc2[r]]; + F5 += FE0_C0_D01[ip][r]*w[1][nzc1[r]]; + F6 += FE0_C0_D01[ip][r]*w[1][nzc5[r]]; + F7 += FE0_C0_D01[ip][r]*w[1][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 108 + double I[3]; + // Number of operations: 36 + I[0] = W3[ip]*(F4*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]) + F5*(F0*G[1] + F1*G[4] + F2*G[5] + F3*G[6]) + F6*(F0*G[2] + F1*G[5] + F2*G[7] + F3*G[8]) + F7*(F0*G[3] + F1*G[6] + F2*G[8] + F3*G[9])); + + // Number of operations: 36 + I[1] = W3[ip]*(F4*(F0*G[10] + F1*G[11] + F2*G[12] + F3*G[13]) + F5*(F0*G[11] + F1*G[14] + F2*G[15] + F3*G[16]) + F6*(F0*G[12] + F1*G[15] + F2*G[17] + F3*G[18]) + F7*(F0*G[13] + F1*G[16] + F2*G[18] + F3*G[19])); + + // Number of operations: 36 + I[2] = W3[ip]*(F4*(F0*G[20] + F1*G[21] + F2*G[22] + F3*G[23]) + F5*(F0*G[21] + F1*G[24] + F2*G[25] + F3*G[26]) + F6*(F0*G[22] + F1*G[25] + F2*G[27] + F3*G[28]) + F7*(F0*G[23] + F1*G[26] + F2*G[28] + F3*G[29])); + + + // Number of operations for primary indices: 600 + for (unsigned int j = 0; j < 5; j++) + { + for (unsigned int k = 0; k < 5; k++) + { + // Number of operations to compute entry: 3 + A[nzc10[j]*12 + nzc10[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc10[j]*12 + nzc11[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*12 + nzc10[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*12 + nzc11[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc7[j]*12 + nzc7[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc7[j]*12 + nzc8[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*12 + nzc7[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*12 + nzc8[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f2_p1_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), Product(IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 2; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q2_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q2_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q2_tensor.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q2_tensor.h new file mode 100644 index 0000000..f3abbf4 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q2_tensor.h @@ -0,0 +1,8752 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F2_P1_Q2_TENSOR_H +#define __VECTOR_LAPLACIAN_F2_P1_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q2_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q2_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q2_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q2_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q2_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q2_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q2_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q2_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q2_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f2_p1_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 1024 + // Number of operations (multiply-add pairs) for tensor contraction: 961 + // Total number of operations (multiply-add pairs): 1996 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[87] = 0.0; + A[81] = 0.0; + A[7] = 0.0; + A[18] = 0.0; + A[10] = 0.0; + A[43] = 0.0; + A[29] = 0.0; + A[23] = 0.0; + A[101] = 0.0; + A[68] = 0.0; + A[108] = 0.0; + A[137] = 0.0; + A[127] = 0.0; + A[13] = 0.5*G0_0_0_0_0_0_0_0_0 + 0.5*G0_0_0_0_0_0_0_0_1 - 0.5*G0_0_0_0_0_0_1_0_0 - 0.5*G0_0_0_0_0_0_2_0_1 + 0.5*G0_0_0_0_0_0_3_1_0 + 0.5*G0_0_0_0_0_0_3_1_1 - 0.5*G0_0_0_0_0_0_4_1_0 - 0.5*G0_0_0_0_0_0_5_1_1 + 0.5*G0_0_0_0_0_1_0_0_0 + 0.5*G0_0_0_0_0_1_0_0_1 - 0.5*G0_0_0_0_0_1_1_0_0 - 0.5*G0_0_0_0_0_1_2_0_1 + 0.5*G0_0_0_0_0_1_3_1_0 + 0.5*G0_0_0_0_0_1_3_1_1 - 0.5*G0_0_0_0_0_1_4_1_0 - 0.5*G0_0_0_0_0_1_5_1_1 - 0.5*G0_0_0_1_0_0_0_0_0 - 0.5*G0_0_0_1_0_0_0_0_1 + 0.5*G0_0_0_1_0_0_1_0_0 + 0.5*G0_0_0_1_0_0_2_0_1 - 0.5*G0_0_0_1_0_0_3_1_0 - 0.5*G0_0_0_1_0_0_3_1_1 + 0.5*G0_0_0_1_0_0_4_1_0 + 0.5*G0_0_0_1_0_0_5_1_1 - 0.5*G0_0_0_2_0_1_0_0_0 - 0.5*G0_0_0_2_0_1_0_0_1 + 0.5*G0_0_0_2_0_1_1_0_0 + 0.5*G0_0_0_2_0_1_2_0_1 - 0.5*G0_0_0_2_0_1_3_1_0 - 0.5*G0_0_0_2_0_1_3_1_1 + 0.5*G0_0_0_2_0_1_4_1_0 + 0.5*G0_0_0_2_0_1_5_1_1 + 0.5*G0_0_0_3_1_0_0_0_0 + 0.5*G0_0_0_3_1_0_0_0_1 - 0.5*G0_0_0_3_1_0_1_0_0 - 0.5*G0_0_0_3_1_0_2_0_1 + 0.5*G0_0_0_3_1_0_3_1_0 + 0.5*G0_0_0_3_1_0_3_1_1 - 0.5*G0_0_0_3_1_0_4_1_0 - 0.5*G0_0_0_3_1_0_5_1_1 + 0.5*G0_0_0_3_1_1_0_0_0 + 0.5*G0_0_0_3_1_1_0_0_1 - 0.5*G0_0_0_3_1_1_1_0_0 - 0.5*G0_0_0_3_1_1_2_0_1 + 0.5*G0_0_0_3_1_1_3_1_0 + 0.5*G0_0_0_3_1_1_3_1_1 - 0.5*G0_0_0_3_1_1_4_1_0 - 0.5*G0_0_0_3_1_1_5_1_1 - 0.5*G0_0_0_4_1_0_0_0_0 - 0.5*G0_0_0_4_1_0_0_0_1 + 0.5*G0_0_0_4_1_0_1_0_0 + 0.5*G0_0_0_4_1_0_2_0_1 - 0.5*G0_0_0_4_1_0_3_1_0 - 0.5*G0_0_0_4_1_0_3_1_1 + 0.5*G0_0_0_4_1_0_4_1_0 + 0.5*G0_0_0_4_1_0_5_1_1 - 0.5*G0_0_0_5_1_1_0_0_0 - 0.5*G0_0_0_5_1_1_0_0_1 + 0.5*G0_0_0_5_1_1_1_0_0 + 0.5*G0_0_0_5_1_1_2_0_1 - 0.5*G0_0_0_5_1_1_3_1_0 - 0.5*G0_0_0_5_1_1_3_1_1 + 0.5*G0_0_0_5_1_1_4_1_0 + 0.5*G0_0_0_5_1_1_5_1_1; + A[58] = 0.0; + A[38] = 0.666666666666666*G0_0_1_0_0_0_0_0_0 + 0.666666666666666*G0_0_1_0_0_0_0_0_1 - 0.666666666666666*G0_0_1_0_0_0_1_0_0 - 0.666666666666666*G0_0_1_0_0_0_2_0_1 + 0.666666666666666*G0_0_1_0_0_0_3_1_0 + 0.666666666666666*G0_0_1_0_0_0_3_1_1 - 0.666666666666666*G0_0_1_0_0_0_4_1_0 - 0.666666666666666*G0_0_1_0_0_0_5_1_1 + 0.666666666666666*G0_0_1_0_0_1_0_0_0 + 0.666666666666666*G0_0_1_0_0_1_0_0_1 - 0.666666666666666*G0_0_1_0_0_1_1_0_0 - 0.666666666666666*G0_0_1_0_0_1_2_0_1 + 0.666666666666666*G0_0_1_0_0_1_3_1_0 + 0.666666666666666*G0_0_1_0_0_1_3_1_1 - 0.666666666666666*G0_0_1_0_0_1_4_1_0 - 0.666666666666666*G0_0_1_0_0_1_5_1_1 - 0.666666666666666*G0_0_1_1_0_0_0_0_0 - 0.666666666666666*G0_0_1_1_0_0_0_0_1 + 0.666666666666666*G0_0_1_1_0_0_1_0_0 + 0.666666666666666*G0_0_1_1_0_0_2_0_1 - 0.666666666666666*G0_0_1_1_0_0_3_1_0 - 0.666666666666666*G0_0_1_1_0_0_3_1_1 + 0.666666666666666*G0_0_1_1_0_0_4_1_0 + 0.666666666666666*G0_0_1_1_0_0_5_1_1 - 0.666666666666666*G0_0_1_2_0_1_0_0_0 - 0.666666666666666*G0_0_1_2_0_1_0_0_1 + 0.666666666666666*G0_0_1_2_0_1_1_0_0 + 0.666666666666666*G0_0_1_2_0_1_2_0_1 - 0.666666666666666*G0_0_1_2_0_1_3_1_0 - 0.666666666666666*G0_0_1_2_0_1_3_1_1 + 0.666666666666666*G0_0_1_2_0_1_4_1_0 + 0.666666666666666*G0_0_1_2_0_1_5_1_1 + 0.666666666666666*G0_0_1_3_1_0_0_0_0 + 0.666666666666666*G0_0_1_3_1_0_0_0_1 - 0.666666666666666*G0_0_1_3_1_0_1_0_0 - 0.666666666666666*G0_0_1_3_1_0_2_0_1 + 0.666666666666666*G0_0_1_3_1_0_3_1_0 + 0.666666666666666*G0_0_1_3_1_0_3_1_1 - 0.666666666666666*G0_0_1_3_1_0_4_1_0 - 0.666666666666666*G0_0_1_3_1_0_5_1_1 + 0.666666666666666*G0_0_1_3_1_1_0_0_0 + 0.666666666666666*G0_0_1_3_1_1_0_0_1 - 0.666666666666666*G0_0_1_3_1_1_1_0_0 - 0.666666666666666*G0_0_1_3_1_1_2_0_1 + 0.666666666666666*G0_0_1_3_1_1_3_1_0 + 0.666666666666666*G0_0_1_3_1_1_3_1_1 - 0.666666666666666*G0_0_1_3_1_1_4_1_0 - 0.666666666666666*G0_0_1_3_1_1_5_1_1 - 0.666666666666666*G0_0_1_4_1_0_0_0_0 - 0.666666666666666*G0_0_1_4_1_0_0_0_1 + 0.666666666666666*G0_0_1_4_1_0_1_0_0 + 0.666666666666666*G0_0_1_4_1_0_2_0_1 - 0.666666666666666*G0_0_1_4_1_0_3_1_0 - 0.666666666666666*G0_0_1_4_1_0_3_1_1 + 0.666666666666666*G0_0_1_4_1_0_4_1_0 + 0.666666666666666*G0_0_1_4_1_0_5_1_1 - 0.666666666666666*G0_0_1_5_1_1_0_0_0 - 0.666666666666666*G0_0_1_5_1_1_0_0_1 + 0.666666666666666*G0_0_1_5_1_1_1_0_0 + 0.666666666666666*G0_0_1_5_1_1_2_0_1 - 0.666666666666666*G0_0_1_5_1_1_3_1_0 - 0.666666666666666*G0_0_1_5_1_1_3_1_1 + 0.666666666666666*G0_0_1_5_1_1_4_1_0 + 0.666666666666666*G0_0_1_5_1_1_5_1_1; + A[128] = -A[38] - 0.666666666666666*G0_1_1_0_0_0_0_0_0 - 0.666666666666666*G0_1_1_0_0_0_0_0_1 + 0.666666666666666*G0_1_1_0_0_0_1_0_0 + 0.666666666666666*G0_1_1_0_0_0_2_0_1 - 0.666666666666666*G0_1_1_0_0_0_3_1_0 - 0.666666666666666*G0_1_1_0_0_0_3_1_1 + 0.666666666666666*G0_1_1_0_0_0_4_1_0 + 0.666666666666666*G0_1_1_0_0_0_5_1_1 - 0.666666666666666*G0_1_1_0_0_1_0_0_0 - 0.666666666666666*G0_1_1_0_0_1_0_0_1 + 0.666666666666666*G0_1_1_0_0_1_1_0_0 + 0.666666666666666*G0_1_1_0_0_1_2_0_1 - 0.666666666666666*G0_1_1_0_0_1_3_1_0 - 0.666666666666666*G0_1_1_0_0_1_3_1_1 + 0.666666666666666*G0_1_1_0_0_1_4_1_0 + 0.666666666666666*G0_1_1_0_0_1_5_1_1 + 0.666666666666666*G0_1_1_1_0_0_0_0_0 + 0.666666666666666*G0_1_1_1_0_0_0_0_1 - 0.666666666666666*G0_1_1_1_0_0_1_0_0 - 0.666666666666666*G0_1_1_1_0_0_2_0_1 + 0.666666666666666*G0_1_1_1_0_0_3_1_0 + 0.666666666666666*G0_1_1_1_0_0_3_1_1 - 0.666666666666666*G0_1_1_1_0_0_4_1_0 - 0.666666666666666*G0_1_1_1_0_0_5_1_1 + 0.666666666666666*G0_1_1_2_0_1_0_0_0 + 0.666666666666666*G0_1_1_2_0_1_0_0_1 - 0.666666666666666*G0_1_1_2_0_1_1_0_0 - 0.666666666666666*G0_1_1_2_0_1_2_0_1 + 0.666666666666666*G0_1_1_2_0_1_3_1_0 + 0.666666666666666*G0_1_1_2_0_1_3_1_1 - 0.666666666666666*G0_1_1_2_0_1_4_1_0 - 0.666666666666666*G0_1_1_2_0_1_5_1_1 - 0.666666666666666*G0_1_1_3_1_0_0_0_0 - 0.666666666666666*G0_1_1_3_1_0_0_0_1 + 0.666666666666666*G0_1_1_3_1_0_1_0_0 + 0.666666666666666*G0_1_1_3_1_0_2_0_1 - 0.666666666666666*G0_1_1_3_1_0_3_1_0 - 0.666666666666666*G0_1_1_3_1_0_3_1_1 + 0.666666666666666*G0_1_1_3_1_0_4_1_0 + 0.666666666666666*G0_1_1_3_1_0_5_1_1 - 0.666666666666666*G0_1_1_3_1_1_0_0_0 - 0.666666666666666*G0_1_1_3_1_1_0_0_1 + 0.666666666666666*G0_1_1_3_1_1_1_0_0 + 0.666666666666666*G0_1_1_3_1_1_2_0_1 - 0.666666666666666*G0_1_1_3_1_1_3_1_0 - 0.666666666666666*G0_1_1_3_1_1_3_1_1 + 0.666666666666666*G0_1_1_3_1_1_4_1_0 + 0.666666666666666*G0_1_1_3_1_1_5_1_1 + 0.666666666666666*G0_1_1_4_1_0_0_0_0 + 0.666666666666666*G0_1_1_4_1_0_0_0_1 - 0.666666666666666*G0_1_1_4_1_0_1_0_0 - 0.666666666666666*G0_1_1_4_1_0_2_0_1 + 0.666666666666666*G0_1_1_4_1_0_3_1_0 + 0.666666666666666*G0_1_1_4_1_0_3_1_1 - 0.666666666666666*G0_1_1_4_1_0_4_1_0 - 0.666666666666666*G0_1_1_4_1_0_5_1_1 + 0.666666666666666*G0_1_1_5_1_1_0_0_0 + 0.666666666666666*G0_1_1_5_1_1_0_0_1 - 0.666666666666666*G0_1_1_5_1_1_1_0_0 - 0.666666666666666*G0_1_1_5_1_1_2_0_1 + 0.666666666666666*G0_1_1_5_1_1_3_1_0 + 0.666666666666666*G0_1_1_5_1_1_3_1_1 - 0.666666666666666*G0_1_1_5_1_1_4_1_0 - 0.666666666666666*G0_1_1_5_1_1_5_1_1; + A[82] = A[128]; + A[4] = A[128]; + A[30] = 0.0; + A[98] = 0.0; + A[71] = 0.0; + A[53] = A[38] + 0.666666666666667*G0_1_0_0_0_0_0_0_0 + 0.666666666666667*G0_1_0_0_0_0_0_0_1 - 0.666666666666667*G0_1_0_0_0_0_1_0_0 - 0.666666666666667*G0_1_0_0_0_0_2_0_1 + 0.666666666666667*G0_1_0_0_0_0_3_1_0 + 0.666666666666667*G0_1_0_0_0_0_3_1_1 - 0.666666666666667*G0_1_0_0_0_0_4_1_0 - 0.666666666666667*G0_1_0_0_0_0_5_1_1 + 0.666666666666667*G0_1_0_0_0_1_0_0_0 + 0.666666666666667*G0_1_0_0_0_1_0_0_1 - 0.666666666666667*G0_1_0_0_0_1_1_0_0 - 0.666666666666667*G0_1_0_0_0_1_2_0_1 + 0.666666666666667*G0_1_0_0_0_1_3_1_0 + 0.666666666666667*G0_1_0_0_0_1_3_1_1 - 0.666666666666667*G0_1_0_0_0_1_4_1_0 - 0.666666666666667*G0_1_0_0_0_1_5_1_1 - 0.666666666666667*G0_1_0_1_0_0_0_0_0 - 0.666666666666667*G0_1_0_1_0_0_0_0_1 + 0.666666666666667*G0_1_0_1_0_0_1_0_0 + 0.666666666666667*G0_1_0_1_0_0_2_0_1 - 0.666666666666667*G0_1_0_1_0_0_3_1_0 - 0.666666666666667*G0_1_0_1_0_0_3_1_1 + 0.666666666666667*G0_1_0_1_0_0_4_1_0 + 0.666666666666667*G0_1_0_1_0_0_5_1_1 - 0.666666666666667*G0_1_0_2_0_1_0_0_0 - 0.666666666666667*G0_1_0_2_0_1_0_0_1 + 0.666666666666667*G0_1_0_2_0_1_1_0_0 + 0.666666666666667*G0_1_0_2_0_1_2_0_1 - 0.666666666666667*G0_1_0_2_0_1_3_1_0 - 0.666666666666667*G0_1_0_2_0_1_3_1_1 + 0.666666666666667*G0_1_0_2_0_1_4_1_0 + 0.666666666666667*G0_1_0_2_0_1_5_1_1 + 0.666666666666667*G0_1_0_3_1_0_0_0_0 + 0.666666666666667*G0_1_0_3_1_0_0_0_1 - 0.666666666666667*G0_1_0_3_1_0_1_0_0 - 0.666666666666667*G0_1_0_3_1_0_2_0_1 + 0.666666666666667*G0_1_0_3_1_0_3_1_0 + 0.666666666666667*G0_1_0_3_1_0_3_1_1 - 0.666666666666667*G0_1_0_3_1_0_4_1_0 - 0.666666666666667*G0_1_0_3_1_0_5_1_1 + 0.666666666666667*G0_1_0_3_1_1_0_0_0 + 0.666666666666667*G0_1_0_3_1_1_0_0_1 - 0.666666666666667*G0_1_0_3_1_1_1_0_0 - 0.666666666666667*G0_1_0_3_1_1_2_0_1 + 0.666666666666667*G0_1_0_3_1_1_3_1_0 + 0.666666666666667*G0_1_0_3_1_1_3_1_1 - 0.666666666666667*G0_1_0_3_1_1_4_1_0 - 0.666666666666667*G0_1_0_3_1_1_5_1_1 - 0.666666666666667*G0_1_0_4_1_0_0_0_0 - 0.666666666666667*G0_1_0_4_1_0_0_0_1 + 0.666666666666667*G0_1_0_4_1_0_1_0_0 + 0.666666666666667*G0_1_0_4_1_0_2_0_1 - 0.666666666666667*G0_1_0_4_1_0_3_1_0 - 0.666666666666667*G0_1_0_4_1_0_3_1_1 + 0.666666666666667*G0_1_0_4_1_0_4_1_0 + 0.666666666666667*G0_1_0_4_1_0_5_1_1 - 0.666666666666667*G0_1_0_5_1_1_0_0_0 - 0.666666666666667*G0_1_0_5_1_1_0_0_1 + 0.666666666666667*G0_1_0_5_1_1_1_0_0 + 0.666666666666667*G0_1_0_5_1_1_2_0_1 - 0.666666666666667*G0_1_0_5_1_1_3_1_0 - 0.666666666666667*G0_1_0_5_1_1_3_1_1 + 0.666666666666667*G0_1_0_5_1_1_4_1_0 + 0.666666666666667*G0_1_0_5_1_1_5_1_1; + A[111] = 0.0; + A[72] = 0.0; + A[132] = 0.0; + A[89] = 0.0; + A[37] = 0.666666666666666*G0_1_0_0_0_0_0_0_0 + 0.666666666666666*G0_1_0_0_0_0_0_0_1 - 0.666666666666666*G0_1_0_0_0_0_1_0_0 - 0.666666666666666*G0_1_0_0_0_0_2_0_1 + 0.666666666666666*G0_1_0_0_0_0_3_1_0 + 0.666666666666666*G0_1_0_0_0_0_3_1_1 - 0.666666666666666*G0_1_0_0_0_0_4_1_0 - 0.666666666666666*G0_1_0_0_0_0_5_1_1 + 0.666666666666666*G0_1_0_0_0_1_0_0_0 + 0.666666666666666*G0_1_0_0_0_1_0_0_1 - 0.666666666666666*G0_1_0_0_0_1_1_0_0 - 0.666666666666666*G0_1_0_0_0_1_2_0_1 + 0.666666666666666*G0_1_0_0_0_1_3_1_0 + 0.666666666666666*G0_1_0_0_0_1_3_1_1 - 0.666666666666666*G0_1_0_0_0_1_4_1_0 - 0.666666666666666*G0_1_0_0_0_1_5_1_1 - 0.666666666666666*G0_1_0_1_0_0_0_0_0 - 0.666666666666666*G0_1_0_1_0_0_0_0_1 + 0.666666666666666*G0_1_0_1_0_0_1_0_0 + 0.666666666666666*G0_1_0_1_0_0_2_0_1 - 0.666666666666666*G0_1_0_1_0_0_3_1_0 - 0.666666666666666*G0_1_0_1_0_0_3_1_1 + 0.666666666666666*G0_1_0_1_0_0_4_1_0 + 0.666666666666666*G0_1_0_1_0_0_5_1_1 - 0.666666666666666*G0_1_0_2_0_1_0_0_0 - 0.666666666666666*G0_1_0_2_0_1_0_0_1 + 0.666666666666666*G0_1_0_2_0_1_1_0_0 + 0.666666666666666*G0_1_0_2_0_1_2_0_1 - 0.666666666666666*G0_1_0_2_0_1_3_1_0 - 0.666666666666666*G0_1_0_2_0_1_3_1_1 + 0.666666666666666*G0_1_0_2_0_1_4_1_0 + 0.666666666666666*G0_1_0_2_0_1_5_1_1 + 0.666666666666666*G0_1_0_3_1_0_0_0_0 + 0.666666666666666*G0_1_0_3_1_0_0_0_1 - 0.666666666666666*G0_1_0_3_1_0_1_0_0 - 0.666666666666666*G0_1_0_3_1_0_2_0_1 + 0.666666666666666*G0_1_0_3_1_0_3_1_0 + 0.666666666666666*G0_1_0_3_1_0_3_1_1 - 0.666666666666666*G0_1_0_3_1_0_4_1_0 - 0.666666666666666*G0_1_0_3_1_0_5_1_1 + 0.666666666666666*G0_1_0_3_1_1_0_0_0 + 0.666666666666666*G0_1_0_3_1_1_0_0_1 - 0.666666666666666*G0_1_0_3_1_1_1_0_0 - 0.666666666666666*G0_1_0_3_1_1_2_0_1 + 0.666666666666666*G0_1_0_3_1_1_3_1_0 + 0.666666666666666*G0_1_0_3_1_1_3_1_1 - 0.666666666666666*G0_1_0_3_1_1_4_1_0 - 0.666666666666666*G0_1_0_3_1_1_5_1_1 - 0.666666666666666*G0_1_0_4_1_0_0_0_0 - 0.666666666666666*G0_1_0_4_1_0_0_0_1 + 0.666666666666666*G0_1_0_4_1_0_1_0_0 + 0.666666666666666*G0_1_0_4_1_0_2_0_1 - 0.666666666666666*G0_1_0_4_1_0_3_1_0 - 0.666666666666666*G0_1_0_4_1_0_3_1_1 + 0.666666666666666*G0_1_0_4_1_0_4_1_0 + 0.666666666666666*G0_1_0_4_1_0_5_1_1 - 0.666666666666666*G0_1_0_5_1_1_0_0_0 - 0.666666666666666*G0_1_0_5_1_1_0_0_1 + 0.666666666666666*G0_1_0_5_1_1_1_0_0 + 0.666666666666666*G0_1_0_5_1_1_2_0_1 - 0.666666666666666*G0_1_0_5_1_1_3_1_0 - 0.666666666666666*G0_1_0_5_1_1_3_1_1 + 0.666666666666666*G0_1_0_5_1_1_4_1_0 + 0.666666666666666*G0_1_0_5_1_1_5_1_1; + A[48] = -A[37] - 0.666666666666667*G0_1_1_0_0_0_0_0_0 - 0.666666666666667*G0_1_1_0_0_0_0_0_1 + 0.666666666666667*G0_1_1_0_0_0_1_0_0 + 0.666666666666667*G0_1_1_0_0_0_2_0_1 - 0.666666666666667*G0_1_1_0_0_0_3_1_0 - 0.666666666666667*G0_1_1_0_0_0_3_1_1 + 0.666666666666667*G0_1_1_0_0_0_4_1_0 + 0.666666666666667*G0_1_1_0_0_0_5_1_1 - 0.666666666666667*G0_1_1_0_0_1_0_0_0 - 0.666666666666667*G0_1_1_0_0_1_0_0_1 + 0.666666666666667*G0_1_1_0_0_1_1_0_0 + 0.666666666666667*G0_1_1_0_0_1_2_0_1 - 0.666666666666667*G0_1_1_0_0_1_3_1_0 - 0.666666666666667*G0_1_1_0_0_1_3_1_1 + 0.666666666666667*G0_1_1_0_0_1_4_1_0 + 0.666666666666667*G0_1_1_0_0_1_5_1_1 + 0.666666666666667*G0_1_1_1_0_0_0_0_0 + 0.666666666666667*G0_1_1_1_0_0_0_0_1 - 0.666666666666667*G0_1_1_1_0_0_1_0_0 - 0.666666666666667*G0_1_1_1_0_0_2_0_1 + 0.666666666666667*G0_1_1_1_0_0_3_1_0 + 0.666666666666667*G0_1_1_1_0_0_3_1_1 - 0.666666666666667*G0_1_1_1_0_0_4_1_0 - 0.666666666666667*G0_1_1_1_0_0_5_1_1 + 0.666666666666667*G0_1_1_2_0_1_0_0_0 + 0.666666666666667*G0_1_1_2_0_1_0_0_1 - 0.666666666666667*G0_1_1_2_0_1_1_0_0 - 0.666666666666667*G0_1_1_2_0_1_2_0_1 + 0.666666666666667*G0_1_1_2_0_1_3_1_0 + 0.666666666666667*G0_1_1_2_0_1_3_1_1 - 0.666666666666667*G0_1_1_2_0_1_4_1_0 - 0.666666666666667*G0_1_1_2_0_1_5_1_1 - 0.666666666666667*G0_1_1_3_1_0_0_0_0 - 0.666666666666667*G0_1_1_3_1_0_0_0_1 + 0.666666666666667*G0_1_1_3_1_0_1_0_0 + 0.666666666666667*G0_1_1_3_1_0_2_0_1 - 0.666666666666667*G0_1_1_3_1_0_3_1_0 - 0.666666666666667*G0_1_1_3_1_0_3_1_1 + 0.666666666666667*G0_1_1_3_1_0_4_1_0 + 0.666666666666667*G0_1_1_3_1_0_5_1_1 - 0.666666666666667*G0_1_1_3_1_1_0_0_0 - 0.666666666666667*G0_1_1_3_1_1_0_0_1 + 0.666666666666667*G0_1_1_3_1_1_1_0_0 + 0.666666666666667*G0_1_1_3_1_1_2_0_1 - 0.666666666666667*G0_1_1_3_1_1_3_1_0 - 0.666666666666667*G0_1_1_3_1_1_3_1_1 + 0.666666666666667*G0_1_1_3_1_1_4_1_0 + 0.666666666666667*G0_1_1_3_1_1_5_1_1 + 0.666666666666667*G0_1_1_4_1_0_0_0_0 + 0.666666666666667*G0_1_1_4_1_0_0_0_1 - 0.666666666666667*G0_1_1_4_1_0_1_0_0 - 0.666666666666667*G0_1_1_4_1_0_2_0_1 + 0.666666666666667*G0_1_1_4_1_0_3_1_0 + 0.666666666666667*G0_1_1_4_1_0_3_1_1 - 0.666666666666667*G0_1_1_4_1_0_4_1_0 - 0.666666666666667*G0_1_1_4_1_0_5_1_1 + 0.666666666666667*G0_1_1_5_1_1_0_0_0 + 0.666666666666667*G0_1_1_5_1_1_0_0_1 - 0.666666666666667*G0_1_1_5_1_1_1_0_0 - 0.666666666666667*G0_1_1_5_1_1_2_0_1 + 0.666666666666667*G0_1_1_5_1_1_3_1_0 + 0.666666666666667*G0_1_1_5_1_1_3_1_1 - 0.666666666666667*G0_1_1_5_1_1_4_1_0 - 0.666666666666667*G0_1_1_5_1_1_5_1_1; + A[35] = 0.0; + A[92] = -0.25*A[38]; + A[90] = -A[92] + 0.166666666666667*G0_0_0_0_0_0_0_0_0 + 0.166666666666667*G0_0_0_0_0_0_0_0_1 - 0.166666666666667*G0_0_0_0_0_0_1_0_0 - 0.166666666666667*G0_0_0_0_0_0_2_0_1 + 0.166666666666667*G0_0_0_0_0_0_3_1_0 + 0.166666666666667*G0_0_0_0_0_0_3_1_1 - 0.166666666666667*G0_0_0_0_0_0_4_1_0 - 0.166666666666667*G0_0_0_0_0_0_5_1_1 + 0.166666666666667*G0_0_0_0_0_1_0_0_0 + 0.166666666666667*G0_0_0_0_0_1_0_0_1 - 0.166666666666667*G0_0_0_0_0_1_1_0_0 - 0.166666666666667*G0_0_0_0_0_1_2_0_1 + 0.166666666666667*G0_0_0_0_0_1_3_1_0 + 0.166666666666667*G0_0_0_0_0_1_3_1_1 - 0.166666666666667*G0_0_0_0_0_1_4_1_0 - 0.166666666666667*G0_0_0_0_0_1_5_1_1 - 0.166666666666667*G0_0_0_1_0_0_0_0_0 - 0.166666666666667*G0_0_0_1_0_0_0_0_1 + 0.166666666666667*G0_0_0_1_0_0_1_0_0 + 0.166666666666667*G0_0_0_1_0_0_2_0_1 - 0.166666666666667*G0_0_0_1_0_0_3_1_0 - 0.166666666666667*G0_0_0_1_0_0_3_1_1 + 0.166666666666667*G0_0_0_1_0_0_4_1_0 + 0.166666666666667*G0_0_0_1_0_0_5_1_1 - 0.166666666666667*G0_0_0_2_0_1_0_0_0 - 0.166666666666667*G0_0_0_2_0_1_0_0_1 + 0.166666666666667*G0_0_0_2_0_1_1_0_0 + 0.166666666666667*G0_0_0_2_0_1_2_0_1 - 0.166666666666667*G0_0_0_2_0_1_3_1_0 - 0.166666666666667*G0_0_0_2_0_1_3_1_1 + 0.166666666666667*G0_0_0_2_0_1_4_1_0 + 0.166666666666667*G0_0_0_2_0_1_5_1_1 + 0.166666666666667*G0_0_0_3_1_0_0_0_0 + 0.166666666666667*G0_0_0_3_1_0_0_0_1 - 0.166666666666667*G0_0_0_3_1_0_1_0_0 - 0.166666666666667*G0_0_0_3_1_0_2_0_1 + 0.166666666666667*G0_0_0_3_1_0_3_1_0 + 0.166666666666667*G0_0_0_3_1_0_3_1_1 - 0.166666666666667*G0_0_0_3_1_0_4_1_0 - 0.166666666666667*G0_0_0_3_1_0_5_1_1 + 0.166666666666667*G0_0_0_3_1_1_0_0_0 + 0.166666666666667*G0_0_0_3_1_1_0_0_1 - 0.166666666666667*G0_0_0_3_1_1_1_0_0 - 0.166666666666667*G0_0_0_3_1_1_2_0_1 + 0.166666666666667*G0_0_0_3_1_1_3_1_0 + 0.166666666666667*G0_0_0_3_1_1_3_1_1 - 0.166666666666667*G0_0_0_3_1_1_4_1_0 - 0.166666666666667*G0_0_0_3_1_1_5_1_1 - 0.166666666666667*G0_0_0_4_1_0_0_0_0 - 0.166666666666667*G0_0_0_4_1_0_0_0_1 + 0.166666666666667*G0_0_0_4_1_0_1_0_0 + 0.166666666666667*G0_0_0_4_1_0_2_0_1 - 0.166666666666667*G0_0_0_4_1_0_3_1_0 - 0.166666666666667*G0_0_0_4_1_0_3_1_1 + 0.166666666666667*G0_0_0_4_1_0_4_1_0 + 0.166666666666667*G0_0_0_4_1_0_5_1_1 - 0.166666666666667*G0_0_0_5_1_1_0_0_0 - 0.166666666666667*G0_0_0_5_1_1_0_0_1 + 0.166666666666667*G0_0_0_5_1_1_1_0_0 + 0.166666666666667*G0_0_0_5_1_1_2_0_1 - 0.166666666666667*G0_0_0_5_1_1_3_1_0 - 0.166666666666667*G0_0_0_5_1_1_3_1_1 + 0.166666666666667*G0_0_0_5_1_1_4_1_0 + 0.166666666666667*G0_0_0_5_1_1_5_1_1; + A[47] = 0.0; + A[25] = -0.25*A[37]; + A[79] = -A[25] + 0.166666666666667*G0_0_0_0_0_0_0_0_0 + 0.166666666666667*G0_0_0_0_0_0_0_0_1 - 0.166666666666667*G0_0_0_0_0_0_1_0_0 - 0.166666666666667*G0_0_0_0_0_0_2_0_1 + 0.166666666666667*G0_0_0_0_0_0_3_1_0 + 0.166666666666667*G0_0_0_0_0_0_3_1_1 - 0.166666666666667*G0_0_0_0_0_0_4_1_0 - 0.166666666666667*G0_0_0_0_0_0_5_1_1 + 0.166666666666667*G0_0_0_0_0_1_0_0_0 + 0.166666666666667*G0_0_0_0_0_1_0_0_1 - 0.166666666666667*G0_0_0_0_0_1_1_0_0 - 0.166666666666667*G0_0_0_0_0_1_2_0_1 + 0.166666666666667*G0_0_0_0_0_1_3_1_0 + 0.166666666666667*G0_0_0_0_0_1_3_1_1 - 0.166666666666667*G0_0_0_0_0_1_4_1_0 - 0.166666666666667*G0_0_0_0_0_1_5_1_1 - 0.166666666666667*G0_0_0_1_0_0_0_0_0 - 0.166666666666667*G0_0_0_1_0_0_0_0_1 + 0.166666666666667*G0_0_0_1_0_0_1_0_0 + 0.166666666666667*G0_0_0_1_0_0_2_0_1 - 0.166666666666667*G0_0_0_1_0_0_3_1_0 - 0.166666666666667*G0_0_0_1_0_0_3_1_1 + 0.166666666666667*G0_0_0_1_0_0_4_1_0 + 0.166666666666667*G0_0_0_1_0_0_5_1_1 - 0.166666666666667*G0_0_0_2_0_1_0_0_0 - 0.166666666666667*G0_0_0_2_0_1_0_0_1 + 0.166666666666667*G0_0_0_2_0_1_1_0_0 + 0.166666666666667*G0_0_0_2_0_1_2_0_1 - 0.166666666666667*G0_0_0_2_0_1_3_1_0 - 0.166666666666667*G0_0_0_2_0_1_3_1_1 + 0.166666666666667*G0_0_0_2_0_1_4_1_0 + 0.166666666666667*G0_0_0_2_0_1_5_1_1 + 0.166666666666667*G0_0_0_3_1_0_0_0_0 + 0.166666666666667*G0_0_0_3_1_0_0_0_1 - 0.166666666666667*G0_0_0_3_1_0_1_0_0 - 0.166666666666667*G0_0_0_3_1_0_2_0_1 + 0.166666666666667*G0_0_0_3_1_0_3_1_0 + 0.166666666666667*G0_0_0_3_1_0_3_1_1 - 0.166666666666667*G0_0_0_3_1_0_4_1_0 - 0.166666666666667*G0_0_0_3_1_0_5_1_1 + 0.166666666666667*G0_0_0_3_1_1_0_0_0 + 0.166666666666667*G0_0_0_3_1_1_0_0_1 - 0.166666666666667*G0_0_0_3_1_1_1_0_0 - 0.166666666666667*G0_0_0_3_1_1_2_0_1 + 0.166666666666667*G0_0_0_3_1_1_3_1_0 + 0.166666666666667*G0_0_0_3_1_1_3_1_1 - 0.166666666666667*G0_0_0_3_1_1_4_1_0 - 0.166666666666667*G0_0_0_3_1_1_5_1_1 - 0.166666666666667*G0_0_0_4_1_0_0_0_0 - 0.166666666666667*G0_0_0_4_1_0_0_0_1 + 0.166666666666667*G0_0_0_4_1_0_1_0_0 + 0.166666666666667*G0_0_0_4_1_0_2_0_1 - 0.166666666666667*G0_0_0_4_1_0_3_1_0 - 0.166666666666667*G0_0_0_4_1_0_3_1_1 + 0.166666666666667*G0_0_0_4_1_0_4_1_0 + 0.166666666666667*G0_0_0_4_1_0_5_1_1 - 0.166666666666667*G0_0_0_5_1_1_0_0_0 - 0.166666666666667*G0_0_0_5_1_1_0_0_1 + 0.166666666666667*G0_0_0_5_1_1_1_0_0 + 0.166666666666667*G0_0_0_5_1_1_2_0_1 - 0.166666666666667*G0_0_0_5_1_1_3_1_0 - 0.166666666666667*G0_0_0_5_1_1_3_1_1 + 0.166666666666667*G0_0_0_5_1_1_4_1_0 + 0.166666666666667*G0_0_0_5_1_1_5_1_1; + A[1] = A[79]; + A[105] = A[37]; + A[112] = 0.0; + A[61] = -4*A[79]; + A[123] = 0.0; + A[86] = 0.0; + A[142] = A[53]; + A[17] = -4.0*A[90]; + A[11] = 0.0; + A[42] = 0.0; + A[26] = 0.5*G0_1_1_0_0_0_0_0_0 + 0.5*G0_1_1_0_0_0_0_0_1 - 0.5*G0_1_1_0_0_0_1_0_0 - 0.5*G0_1_1_0_0_0_2_0_1 + 0.5*G0_1_1_0_0_0_3_1_0 + 0.5*G0_1_1_0_0_0_3_1_1 - 0.5*G0_1_1_0_0_0_4_1_0 - 0.5*G0_1_1_0_0_0_5_1_1 + 0.5*G0_1_1_0_0_1_0_0_0 + 0.5*G0_1_1_0_0_1_0_0_1 - 0.5*G0_1_1_0_0_1_1_0_0 - 0.5*G0_1_1_0_0_1_2_0_1 + 0.5*G0_1_1_0_0_1_3_1_0 + 0.5*G0_1_1_0_0_1_3_1_1 - 0.5*G0_1_1_0_0_1_4_1_0 - 0.5*G0_1_1_0_0_1_5_1_1 - 0.5*G0_1_1_1_0_0_0_0_0 - 0.5*G0_1_1_1_0_0_0_0_1 + 0.5*G0_1_1_1_0_0_1_0_0 + 0.5*G0_1_1_1_0_0_2_0_1 - 0.5*G0_1_1_1_0_0_3_1_0 - 0.5*G0_1_1_1_0_0_3_1_1 + 0.5*G0_1_1_1_0_0_4_1_0 + 0.5*G0_1_1_1_0_0_5_1_1 - 0.5*G0_1_1_2_0_1_0_0_0 - 0.5*G0_1_1_2_0_1_0_0_1 + 0.5*G0_1_1_2_0_1_1_0_0 + 0.5*G0_1_1_2_0_1_2_0_1 - 0.5*G0_1_1_2_0_1_3_1_0 - 0.5*G0_1_1_2_0_1_3_1_1 + 0.5*G0_1_1_2_0_1_4_1_0 + 0.5*G0_1_1_2_0_1_5_1_1 + 0.5*G0_1_1_3_1_0_0_0_0 + 0.5*G0_1_1_3_1_0_0_0_1 - 0.5*G0_1_1_3_1_0_1_0_0 - 0.5*G0_1_1_3_1_0_2_0_1 + 0.5*G0_1_1_3_1_0_3_1_0 + 0.5*G0_1_1_3_1_0_3_1_1 - 0.5*G0_1_1_3_1_0_4_1_0 - 0.5*G0_1_1_3_1_0_5_1_1 + 0.5*G0_1_1_3_1_1_0_0_0 + 0.5*G0_1_1_3_1_1_0_0_1 - 0.5*G0_1_1_3_1_1_1_0_0 - 0.5*G0_1_1_3_1_1_2_0_1 + 0.5*G0_1_1_3_1_1_3_1_0 + 0.5*G0_1_1_3_1_1_3_1_1 - 0.5*G0_1_1_3_1_1_4_1_0 - 0.5*G0_1_1_3_1_1_5_1_1 - 0.5*G0_1_1_4_1_0_0_0_0 - 0.5*G0_1_1_4_1_0_0_0_1 + 0.5*G0_1_1_4_1_0_1_0_0 + 0.5*G0_1_1_4_1_0_2_0_1 - 0.5*G0_1_1_4_1_0_3_1_0 - 0.5*G0_1_1_4_1_0_3_1_1 + 0.5*G0_1_1_4_1_0_4_1_0 + 0.5*G0_1_1_4_1_0_5_1_1 - 0.5*G0_1_1_5_1_1_0_0_0 - 0.5*G0_1_1_5_1_1_0_0_1 + 0.5*G0_1_1_5_1_1_1_0_0 + 0.5*G0_1_1_5_1_1_2_0_1 - 0.5*G0_1_1_5_1_1_3_1_0 - 0.5*G0_1_1_5_1_1_3_1_1 + 0.5*G0_1_1_5_1_1_4_1_0 + 0.5*G0_1_1_5_1_1_5_1_1; + A[22] = 0.0; + A[102] = -0.25*A[48]; + A[49] = 0.0; + A[129] = -A[53] - 1.33333333333333*G0_0_0_0_0_0_0_0_0 - 1.33333333333333*G0_0_0_0_0_0_0_0_1 + 1.33333333333333*G0_0_0_0_0_0_1_0_0 + 1.33333333333333*G0_0_0_0_0_0_2_0_1 - 1.33333333333333*G0_0_0_0_0_0_3_1_0 - 1.33333333333333*G0_0_0_0_0_0_3_1_1 + 1.33333333333333*G0_0_0_0_0_0_4_1_0 + 1.33333333333333*G0_0_0_0_0_0_5_1_1 - 1.33333333333333*G0_0_0_0_0_1_0_0_0 - 1.33333333333333*G0_0_0_0_0_1_0_0_1 + 1.33333333333333*G0_0_0_0_0_1_1_0_0 + 1.33333333333333*G0_0_0_0_0_1_2_0_1 - 1.33333333333333*G0_0_0_0_0_1_3_1_0 - 1.33333333333333*G0_0_0_0_0_1_3_1_1 + 1.33333333333333*G0_0_0_0_0_1_4_1_0 + 1.33333333333333*G0_0_0_0_0_1_5_1_1 + 1.33333333333333*G0_0_0_1_0_0_0_0_0 + 1.33333333333333*G0_0_0_1_0_0_0_0_1 - 1.33333333333333*G0_0_0_1_0_0_1_0_0 - 1.33333333333333*G0_0_0_1_0_0_2_0_1 + 1.33333333333333*G0_0_0_1_0_0_3_1_0 + 1.33333333333333*G0_0_0_1_0_0_3_1_1 - 1.33333333333333*G0_0_0_1_0_0_4_1_0 - 1.33333333333333*G0_0_0_1_0_0_5_1_1 + 1.33333333333333*G0_0_0_2_0_1_0_0_0 + 1.33333333333333*G0_0_0_2_0_1_0_0_1 - 1.33333333333333*G0_0_0_2_0_1_1_0_0 - 1.33333333333333*G0_0_0_2_0_1_2_0_1 + 1.33333333333333*G0_0_0_2_0_1_3_1_0 + 1.33333333333333*G0_0_0_2_0_1_3_1_1 - 1.33333333333333*G0_0_0_2_0_1_4_1_0 - 1.33333333333333*G0_0_0_2_0_1_5_1_1 - 1.33333333333333*G0_0_0_3_1_0_0_0_0 - 1.33333333333333*G0_0_0_3_1_0_0_0_1 + 1.33333333333333*G0_0_0_3_1_0_1_0_0 + 1.33333333333333*G0_0_0_3_1_0_2_0_1 - 1.33333333333333*G0_0_0_3_1_0_3_1_0 - 1.33333333333333*G0_0_0_3_1_0_3_1_1 + 1.33333333333333*G0_0_0_3_1_0_4_1_0 + 1.33333333333333*G0_0_0_3_1_0_5_1_1 - 1.33333333333333*G0_0_0_3_1_1_0_0_0 - 1.33333333333333*G0_0_0_3_1_1_0_0_1 + 1.33333333333333*G0_0_0_3_1_1_1_0_0 + 1.33333333333333*G0_0_0_3_1_1_2_0_1 - 1.33333333333333*G0_0_0_3_1_1_3_1_0 - 1.33333333333333*G0_0_0_3_1_1_3_1_1 + 1.33333333333333*G0_0_0_3_1_1_4_1_0 + 1.33333333333333*G0_0_0_3_1_1_5_1_1 + 1.33333333333333*G0_0_0_4_1_0_0_0_0 + 1.33333333333333*G0_0_0_4_1_0_0_0_1 - 1.33333333333333*G0_0_0_4_1_0_1_0_0 - 1.33333333333333*G0_0_0_4_1_0_2_0_1 + 1.33333333333333*G0_0_0_4_1_0_3_1_0 + 1.33333333333333*G0_0_0_4_1_0_3_1_1 - 1.33333333333333*G0_0_0_4_1_0_4_1_0 - 1.33333333333333*G0_0_0_4_1_0_5_1_1 + 1.33333333333333*G0_0_0_5_1_1_0_0_0 + 1.33333333333333*G0_0_0_5_1_1_0_0_1 - 1.33333333333333*G0_0_0_5_1_1_1_0_0 - 1.33333333333333*G0_0_0_5_1_1_2_0_1 + 1.33333333333333*G0_0_0_5_1_1_3_1_0 + 1.33333333333333*G0_0_0_5_1_1_3_1_1 - 1.33333333333333*G0_0_0_5_1_1_4_1_0 - 1.33333333333333*G0_0_0_5_1_1_5_1_1; + A[143] = -A[129] + 1.33333333333333*G0_1_1_0_0_0_0_0_0 + 1.33333333333333*G0_1_1_0_0_0_0_0_1 - 1.33333333333333*G0_1_1_0_0_0_1_0_0 - 1.33333333333333*G0_1_1_0_0_0_2_0_1 + 1.33333333333333*G0_1_1_0_0_0_3_1_0 + 1.33333333333333*G0_1_1_0_0_0_3_1_1 - 1.33333333333333*G0_1_1_0_0_0_4_1_0 - 1.33333333333333*G0_1_1_0_0_0_5_1_1 + 1.33333333333333*G0_1_1_0_0_1_0_0_0 + 1.33333333333333*G0_1_1_0_0_1_0_0_1 - 1.33333333333333*G0_1_1_0_0_1_1_0_0 - 1.33333333333333*G0_1_1_0_0_1_2_0_1 + 1.33333333333333*G0_1_1_0_0_1_3_1_0 + 1.33333333333333*G0_1_1_0_0_1_3_1_1 - 1.33333333333333*G0_1_1_0_0_1_4_1_0 - 1.33333333333333*G0_1_1_0_0_1_5_1_1 - 1.33333333333333*G0_1_1_1_0_0_0_0_0 - 1.33333333333333*G0_1_1_1_0_0_0_0_1 + 1.33333333333333*G0_1_1_1_0_0_1_0_0 + 1.33333333333333*G0_1_1_1_0_0_2_0_1 - 1.33333333333333*G0_1_1_1_0_0_3_1_0 - 1.33333333333333*G0_1_1_1_0_0_3_1_1 + 1.33333333333333*G0_1_1_1_0_0_4_1_0 + 1.33333333333333*G0_1_1_1_0_0_5_1_1 - 1.33333333333333*G0_1_1_2_0_1_0_0_0 - 1.33333333333333*G0_1_1_2_0_1_0_0_1 + 1.33333333333333*G0_1_1_2_0_1_1_0_0 + 1.33333333333333*G0_1_1_2_0_1_2_0_1 - 1.33333333333333*G0_1_1_2_0_1_3_1_0 - 1.33333333333333*G0_1_1_2_0_1_3_1_1 + 1.33333333333333*G0_1_1_2_0_1_4_1_0 + 1.33333333333333*G0_1_1_2_0_1_5_1_1 + 1.33333333333333*G0_1_1_3_1_0_0_0_0 + 1.33333333333333*G0_1_1_3_1_0_0_0_1 - 1.33333333333333*G0_1_1_3_1_0_1_0_0 - 1.33333333333333*G0_1_1_3_1_0_2_0_1 + 1.33333333333333*G0_1_1_3_1_0_3_1_0 + 1.33333333333333*G0_1_1_3_1_0_3_1_1 - 1.33333333333333*G0_1_1_3_1_0_4_1_0 - 1.33333333333333*G0_1_1_3_1_0_5_1_1 + 1.33333333333333*G0_1_1_3_1_1_0_0_0 + 1.33333333333333*G0_1_1_3_1_1_0_0_1 - 1.33333333333333*G0_1_1_3_1_1_1_0_0 - 1.33333333333333*G0_1_1_3_1_1_2_0_1 + 1.33333333333333*G0_1_1_3_1_1_3_1_0 + 1.33333333333333*G0_1_1_3_1_1_3_1_1 - 1.33333333333333*G0_1_1_3_1_1_4_1_0 - 1.33333333333333*G0_1_1_3_1_1_5_1_1 - 1.33333333333333*G0_1_1_4_1_0_0_0_0 - 1.33333333333333*G0_1_1_4_1_0_0_0_1 + 1.33333333333333*G0_1_1_4_1_0_1_0_0 + 1.33333333333333*G0_1_1_4_1_0_2_0_1 - 1.33333333333333*G0_1_1_4_1_0_3_1_0 - 1.33333333333333*G0_1_1_4_1_0_3_1_1 + 1.33333333333333*G0_1_1_4_1_0_4_1_0 + 1.33333333333333*G0_1_1_4_1_0_5_1_1 - 1.33333333333333*G0_1_1_5_1_1_0_0_0 - 1.33333333333333*G0_1_1_5_1_1_0_0_1 + 1.33333333333333*G0_1_1_5_1_1_1_0_0 + 1.33333333333333*G0_1_1_5_1_1_2_0_1 - 1.33333333333333*G0_1_1_5_1_1_3_1_0 - 1.33333333333333*G0_1_1_5_1_1_3_1_1 + 1.33333333333333*G0_1_1_5_1_1_4_1_0 + 1.33333333333333*G0_1_1_5_1_1_5_1_1; + A[65] = A[143]; + A[117] = A[143]; + A[115] = A[37]; + A[76] = 0.0; + A[64] = A[53]; + A[136] = 0.0; + A[124] = 0.0; + A[85] = 0.0; + A[83] = A[61]; + A[141] = -A[53] - 1.33333333333333*G0_1_1_0_0_0_0_0_0 - 1.33333333333333*G0_1_1_0_0_0_0_0_1 + 1.33333333333333*G0_1_1_0_0_0_1_0_0 + 1.33333333333333*G0_1_1_0_0_0_2_0_1 - 1.33333333333333*G0_1_1_0_0_0_3_1_0 - 1.33333333333333*G0_1_1_0_0_0_3_1_1 + 1.33333333333333*G0_1_1_0_0_0_4_1_0 + 1.33333333333333*G0_1_1_0_0_0_5_1_1 - 1.33333333333333*G0_1_1_0_0_1_0_0_0 - 1.33333333333333*G0_1_1_0_0_1_0_0_1 + 1.33333333333333*G0_1_1_0_0_1_1_0_0 + 1.33333333333333*G0_1_1_0_0_1_2_0_1 - 1.33333333333333*G0_1_1_0_0_1_3_1_0 - 1.33333333333333*G0_1_1_0_0_1_3_1_1 + 1.33333333333333*G0_1_1_0_0_1_4_1_0 + 1.33333333333333*G0_1_1_0_0_1_5_1_1 + 1.33333333333333*G0_1_1_1_0_0_0_0_0 + 1.33333333333333*G0_1_1_1_0_0_0_0_1 - 1.33333333333333*G0_1_1_1_0_0_1_0_0 - 1.33333333333333*G0_1_1_1_0_0_2_0_1 + 1.33333333333333*G0_1_1_1_0_0_3_1_0 + 1.33333333333333*G0_1_1_1_0_0_3_1_1 - 1.33333333333333*G0_1_1_1_0_0_4_1_0 - 1.33333333333333*G0_1_1_1_0_0_5_1_1 + 1.33333333333333*G0_1_1_2_0_1_0_0_0 + 1.33333333333333*G0_1_1_2_0_1_0_0_1 - 1.33333333333333*G0_1_1_2_0_1_1_0_0 - 1.33333333333333*G0_1_1_2_0_1_2_0_1 + 1.33333333333333*G0_1_1_2_0_1_3_1_0 + 1.33333333333333*G0_1_1_2_0_1_3_1_1 - 1.33333333333333*G0_1_1_2_0_1_4_1_0 - 1.33333333333333*G0_1_1_2_0_1_5_1_1 - 1.33333333333333*G0_1_1_3_1_0_0_0_0 - 1.33333333333333*G0_1_1_3_1_0_0_0_1 + 1.33333333333333*G0_1_1_3_1_0_1_0_0 + 1.33333333333333*G0_1_1_3_1_0_2_0_1 - 1.33333333333333*G0_1_1_3_1_0_3_1_0 - 1.33333333333333*G0_1_1_3_1_0_3_1_1 + 1.33333333333333*G0_1_1_3_1_0_4_1_0 + 1.33333333333333*G0_1_1_3_1_0_5_1_1 - 1.33333333333333*G0_1_1_3_1_1_0_0_0 - 1.33333333333333*G0_1_1_3_1_1_0_0_1 + 1.33333333333333*G0_1_1_3_1_1_1_0_0 + 1.33333333333333*G0_1_1_3_1_1_2_0_1 - 1.33333333333333*G0_1_1_3_1_1_3_1_0 - 1.33333333333333*G0_1_1_3_1_1_3_1_1 + 1.33333333333333*G0_1_1_3_1_1_4_1_0 + 1.33333333333333*G0_1_1_3_1_1_5_1_1 + 1.33333333333333*G0_1_1_4_1_0_0_0_0 + 1.33333333333333*G0_1_1_4_1_0_0_0_1 - 1.33333333333333*G0_1_1_4_1_0_1_0_0 - 1.33333333333333*G0_1_1_4_1_0_2_0_1 + 1.33333333333333*G0_1_1_4_1_0_3_1_0 + 1.33333333333333*G0_1_1_4_1_0_3_1_1 - 1.33333333333333*G0_1_1_4_1_0_4_1_0 - 1.33333333333333*G0_1_1_4_1_0_5_1_1 + 1.33333333333333*G0_1_1_5_1_1_0_0_0 + 1.33333333333333*G0_1_1_5_1_1_0_0_1 - 1.33333333333333*G0_1_1_5_1_1_1_0_0 - 1.33333333333333*G0_1_1_5_1_1_2_0_1 + 1.33333333333333*G0_1_1_5_1_1_3_1_0 + 1.33333333333333*G0_1_1_5_1_1_3_1_1 - 1.33333333333333*G0_1_1_5_1_1_4_1_0 - 1.33333333333333*G0_1_1_5_1_1_5_1_1; + A[5] = A[61]; + A[12] = A[90]; + A[8] = 0.0; + A[59] = 0.0; + A[41] = A[141]; + A[31] = 0.0; + A[99] = 0.0; + A[70] = 0.0; + A[54] = 0.0; + A[130] = A[143]; + A[110] = 0.0; + A[73] = 0.0; + A[67] = 0.0; + A[135] = 0.0; + A[88] = 0.0; + A[2] = -0.25*A[128]; + A[15] = A[38]; + A[56] = 0.0; + A[36] = 0.0; + A[32] = 0.0; + A[116] = A[38]; + A[96] = 0.0; + A[74] = 0.0; + A[95] = A[17]; + A[46] = 0.0; + A[106] = A[48]; + A[119] = A[141]; + A[60] = A[17]; + A[120] = 0.0; + A[16] = 0.0; + A[45] = 0.0; + A[27] = A[37]; + A[21] = 0.0; + A[103] = A[25]; + A[50] = A[128]; + A[114] = 0.0; + A[77] = 0.0; + A[63] = A[141]; + A[139] = A[61]; + A[125] = 0.0; + A[84] = 0.0; + A[80] = A[2]; + A[140] = 0.0; + A[6] = 0.0; + A[19] = 0.0; + A[9] = 0.0; + A[40] = A[129]; + A[28] = A[48]; + A[100] = 0.0; + A[69] = 0.0; + A[55] = 0.0; + A[131] = A[53]; + A[109] = 0.0; + A[78] = A[13] + 0.5*G0_0_1_0_0_0_0_0_0 + 0.5*G0_0_1_0_0_0_0_0_1 - 0.5*G0_0_1_0_0_0_1_0_0 - 0.5*G0_0_1_0_0_0_2_0_1 + 0.5*G0_0_1_0_0_0_3_1_0 + 0.5*G0_0_1_0_0_0_3_1_1 - 0.5*G0_0_1_0_0_0_4_1_0 - 0.5*G0_0_1_0_0_0_5_1_1 + 0.5*G0_0_1_0_0_1_0_0_0 + 0.5*G0_0_1_0_0_1_0_0_1 - 0.5*G0_0_1_0_0_1_1_0_0 - 0.5*G0_0_1_0_0_1_2_0_1 + 0.5*G0_0_1_0_0_1_3_1_0 + 0.5*G0_0_1_0_0_1_3_1_1 - 0.5*G0_0_1_0_0_1_4_1_0 - 0.5*G0_0_1_0_0_1_5_1_1 - 0.5*G0_0_1_1_0_0_0_0_0 - 0.5*G0_0_1_1_0_0_0_0_1 + 0.5*G0_0_1_1_0_0_1_0_0 + 0.5*G0_0_1_1_0_0_2_0_1 - 0.5*G0_0_1_1_0_0_3_1_0 - 0.5*G0_0_1_1_0_0_3_1_1 + 0.5*G0_0_1_1_0_0_4_1_0 + 0.5*G0_0_1_1_0_0_5_1_1 - 0.5*G0_0_1_2_0_1_0_0_0 - 0.5*G0_0_1_2_0_1_0_0_1 + 0.5*G0_0_1_2_0_1_1_0_0 + 0.5*G0_0_1_2_0_1_2_0_1 - 0.5*G0_0_1_2_0_1_3_1_0 - 0.5*G0_0_1_2_0_1_3_1_1 + 0.5*G0_0_1_2_0_1_4_1_0 + 0.5*G0_0_1_2_0_1_5_1_1 + 0.5*G0_0_1_3_1_0_0_0_0 + 0.5*G0_0_1_3_1_0_0_0_1 - 0.5*G0_0_1_3_1_0_1_0_0 - 0.5*G0_0_1_3_1_0_2_0_1 + 0.5*G0_0_1_3_1_0_3_1_0 + 0.5*G0_0_1_3_1_0_3_1_1 - 0.5*G0_0_1_3_1_0_4_1_0 - 0.5*G0_0_1_3_1_0_5_1_1 + 0.5*G0_0_1_3_1_1_0_0_0 + 0.5*G0_0_1_3_1_1_0_0_1 - 0.5*G0_0_1_3_1_1_1_0_0 - 0.5*G0_0_1_3_1_1_2_0_1 + 0.5*G0_0_1_3_1_1_3_1_0 + 0.5*G0_0_1_3_1_1_3_1_1 - 0.5*G0_0_1_3_1_1_4_1_0 - 0.5*G0_0_1_3_1_1_5_1_1 - 0.5*G0_0_1_4_1_0_0_0_0 - 0.5*G0_0_1_4_1_0_0_0_1 + 0.5*G0_0_1_4_1_0_1_0_0 + 0.5*G0_0_1_4_1_0_2_0_1 - 0.5*G0_0_1_4_1_0_3_1_0 - 0.5*G0_0_1_4_1_0_3_1_1 + 0.5*G0_0_1_4_1_0_4_1_0 + 0.5*G0_0_1_4_1_0_5_1_1 - 0.5*G0_0_1_5_1_1_0_0_0 - 0.5*G0_0_1_5_1_1_0_0_1 + 0.5*G0_0_1_5_1_1_1_0_0 + 0.5*G0_0_1_5_1_1_2_0_1 - 0.5*G0_0_1_5_1_1_3_1_0 - 0.5*G0_0_1_5_1_1_3_1_1 + 0.5*G0_0_1_5_1_1_4_1_0 + 0.5*G0_0_1_5_1_1_5_1_1 + 0.5*G0_1_0_0_0_0_0_0_0 + 0.5*G0_1_0_0_0_0_0_0_1 - 0.5*G0_1_0_0_0_0_1_0_0 - 0.5*G0_1_0_0_0_0_2_0_1 + 0.5*G0_1_0_0_0_0_3_1_0 + 0.5*G0_1_0_0_0_0_3_1_1 - 0.5*G0_1_0_0_0_0_4_1_0 - 0.5*G0_1_0_0_0_0_5_1_1 + 0.5*G0_1_0_0_0_1_0_0_0 + 0.5*G0_1_0_0_0_1_0_0_1 - 0.5*G0_1_0_0_0_1_1_0_0 - 0.5*G0_1_0_0_0_1_2_0_1 + 0.5*G0_1_0_0_0_1_3_1_0 + 0.5*G0_1_0_0_0_1_3_1_1 - 0.5*G0_1_0_0_0_1_4_1_0 - 0.5*G0_1_0_0_0_1_5_1_1 - 0.5*G0_1_0_1_0_0_0_0_0 - 0.5*G0_1_0_1_0_0_0_0_1 + 0.5*G0_1_0_1_0_0_1_0_0 + 0.5*G0_1_0_1_0_0_2_0_1 - 0.5*G0_1_0_1_0_0_3_1_0 - 0.5*G0_1_0_1_0_0_3_1_1 + 0.5*G0_1_0_1_0_0_4_1_0 + 0.5*G0_1_0_1_0_0_5_1_1 - 0.5*G0_1_0_2_0_1_0_0_0 - 0.5*G0_1_0_2_0_1_0_0_1 + 0.5*G0_1_0_2_0_1_1_0_0 + 0.5*G0_1_0_2_0_1_2_0_1 - 0.5*G0_1_0_2_0_1_3_1_0 - 0.5*G0_1_0_2_0_1_3_1_1 + 0.5*G0_1_0_2_0_1_4_1_0 + 0.5*G0_1_0_2_0_1_5_1_1 + 0.5*G0_1_0_3_1_0_0_0_0 + 0.5*G0_1_0_3_1_0_0_0_1 - 0.5*G0_1_0_3_1_0_1_0_0 - 0.5*G0_1_0_3_1_0_2_0_1 + 0.5*G0_1_0_3_1_0_3_1_0 + 0.5*G0_1_0_3_1_0_3_1_1 - 0.5*G0_1_0_3_1_0_4_1_0 - 0.5*G0_1_0_3_1_0_5_1_1 + 0.5*G0_1_0_3_1_1_0_0_0 + 0.5*G0_1_0_3_1_1_0_0_1 - 0.5*G0_1_0_3_1_1_1_0_0 - 0.5*G0_1_0_3_1_1_2_0_1 + 0.5*G0_1_0_3_1_1_3_1_0 + 0.5*G0_1_0_3_1_1_3_1_1 - 0.5*G0_1_0_3_1_1_4_1_0 - 0.5*G0_1_0_3_1_1_5_1_1 - 0.5*G0_1_0_4_1_0_0_0_0 - 0.5*G0_1_0_4_1_0_0_0_1 + 0.5*G0_1_0_4_1_0_1_0_0 + 0.5*G0_1_0_4_1_0_2_0_1 - 0.5*G0_1_0_4_1_0_3_1_0 - 0.5*G0_1_0_4_1_0_3_1_1 + 0.5*G0_1_0_4_1_0_4_1_0 + 0.5*G0_1_0_4_1_0_5_1_1 - 0.5*G0_1_0_5_1_1_0_0_0 - 0.5*G0_1_0_5_1_1_0_0_1 + 0.5*G0_1_0_5_1_1_1_0_0 + 0.5*G0_1_0_5_1_1_2_0_1 - 0.5*G0_1_0_5_1_1_3_1_0 - 0.5*G0_1_0_5_1_1_3_1_1 + 0.5*G0_1_0_5_1_1_4_1_0 + 0.5*G0_1_0_5_1_1_5_1_1 + 0.5*G0_1_1_0_0_0_0_0_0 + 0.5*G0_1_1_0_0_0_0_0_1 - 0.5*G0_1_1_0_0_0_1_0_0 - 0.5*G0_1_1_0_0_0_2_0_1 + 0.5*G0_1_1_0_0_0_3_1_0 + 0.5*G0_1_1_0_0_0_3_1_1 - 0.5*G0_1_1_0_0_0_4_1_0 - 0.5*G0_1_1_0_0_0_5_1_1 + 0.5*G0_1_1_0_0_1_0_0_0 + 0.5*G0_1_1_0_0_1_0_0_1 - 0.5*G0_1_1_0_0_1_1_0_0 - 0.5*G0_1_1_0_0_1_2_0_1 + 0.5*G0_1_1_0_0_1_3_1_0 + 0.5*G0_1_1_0_0_1_3_1_1 - 0.5*G0_1_1_0_0_1_4_1_0 - 0.5*G0_1_1_0_0_1_5_1_1 - 0.5*G0_1_1_1_0_0_0_0_0 - 0.5*G0_1_1_1_0_0_0_0_1 + 0.5*G0_1_1_1_0_0_1_0_0 + 0.5*G0_1_1_1_0_0_2_0_1 - 0.5*G0_1_1_1_0_0_3_1_0 - 0.5*G0_1_1_1_0_0_3_1_1 + 0.5*G0_1_1_1_0_0_4_1_0 + 0.5*G0_1_1_1_0_0_5_1_1 - 0.5*G0_1_1_2_0_1_0_0_0 - 0.5*G0_1_1_2_0_1_0_0_1 + 0.5*G0_1_1_2_0_1_1_0_0 + 0.5*G0_1_1_2_0_1_2_0_1 - 0.5*G0_1_1_2_0_1_3_1_0 - 0.5*G0_1_1_2_0_1_3_1_1 + 0.5*G0_1_1_2_0_1_4_1_0 + 0.5*G0_1_1_2_0_1_5_1_1 + 0.5*G0_1_1_3_1_0_0_0_0 + 0.5*G0_1_1_3_1_0_0_0_1 - 0.5*G0_1_1_3_1_0_1_0_0 - 0.5*G0_1_1_3_1_0_2_0_1 + 0.5*G0_1_1_3_1_0_3_1_0 + 0.5*G0_1_1_3_1_0_3_1_1 - 0.5*G0_1_1_3_1_0_4_1_0 - 0.5*G0_1_1_3_1_0_5_1_1 + 0.5*G0_1_1_3_1_1_0_0_0 + 0.5*G0_1_1_3_1_1_0_0_1 - 0.5*G0_1_1_3_1_1_1_0_0 - 0.5*G0_1_1_3_1_1_2_0_1 + 0.5*G0_1_1_3_1_1_3_1_0 + 0.5*G0_1_1_3_1_1_3_1_1 - 0.5*G0_1_1_3_1_1_4_1_0 - 0.5*G0_1_1_3_1_1_5_1_1 - 0.5*G0_1_1_4_1_0_0_0_0 - 0.5*G0_1_1_4_1_0_0_0_1 + 0.5*G0_1_1_4_1_0_1_0_0 + 0.5*G0_1_1_4_1_0_2_0_1 - 0.5*G0_1_1_4_1_0_3_1_0 - 0.5*G0_1_1_4_1_0_3_1_1 + 0.5*G0_1_1_4_1_0_4_1_0 + 0.5*G0_1_1_4_1_0_5_1_1 - 0.5*G0_1_1_5_1_1_0_0_0 - 0.5*G0_1_1_5_1_1_0_0_1 + 0.5*G0_1_1_5_1_1_1_0_0 + 0.5*G0_1_1_5_1_1_2_0_1 - 0.5*G0_1_1_5_1_1_3_1_0 - 0.5*G0_1_1_5_1_1_3_1_1 + 0.5*G0_1_1_5_1_1_4_1_0 + 0.5*G0_1_1_5_1_1_5_1_1; + A[66] = 0.0; + A[134] = 0.0; + A[126] = A[48]; + A[91] = A[13]; + A[3] = 0.0; + A[14] = A[92]; + A[57] = 0.0; + A[39] = A[143]; + A[33] = 0.0; + A[97] = 0.0; + A[52] = A[143]; + A[75] = 0.0; + A[133] = 0.0; + A[94] = 0.0; + A[0] = A[78]; + A[107] = 0.0; + A[34] = 0.0; + A[118] = A[129]; + A[121] = 0.0; + A[93] = A[38]; + A[44] = 0.0; + A[24] = A[102]; + A[20] = 0.0; + A[104] = A[26]; + A[51] = A[129]; + A[113] = 0.0; + A[62] = 0.0; + A[138] = A[17]; + A[122] = 0.0; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f2_p1_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), Product(IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 2; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q2_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q2_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q2_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q3_excafe.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q3_excafe.h new file mode 100644 index 0000000..4ee1d73 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q3_excafe.h @@ -0,0 +1,572 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 4 minutes and 21.00 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + A[193] = 0.0000000000000000000000000; + A[363] = 0.0000000000000000000000000; + const double var_0 = -x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -x[0][0]; + const double var_3 = x[1][0] + var_2; + const double var_4 = x[1][1] + var_0; + const double var_5 = x[2][0] + var_2; + const double var_6 = -var_4*var_5 + var_1*var_3; + const double var_7 = var_6; + const double var_8 = std::abs(var_7); + const double var_9 = var_6; + const double var_10 = var_5*var_5*var_5*var_5*w[0][3]*w[1][3] + var_1*var_1*var_1*var_1*w[0][0]*w[1][0]; + const double var_11 = var_5*w[1][4] + var_4*w[1][2]; + const double var_12 = var_3*w[1][5] + var_1*w[1][1]; + const double var_13 = -var_11 + var_12; + const double var_14 = var_11 + -var_12; + const double var_15 = var_4*w[0][2] + var_5*w[0][4]; + const double var_16 = var_3*w[0][5] + var_1*w[0][1]; + const double var_17 = var_14*var_16 + var_13*var_15; + const double var_18 = 0.5000000000000000000000000*var_17; + const double var_19 = var_3*var_3; + const double var_20 = var_5*var_5; + const double var_21 = var_19 + var_20; + const double var_22 = var_3*var_5; + const double var_23 = -0.5000000000000000000000000*var_21 + var_22; + const double var_24 = -var_15 + var_16; + const double var_25 = var_13*w[0][3] + var_24*w[1][3]; + const double var_26 = var_15 + -var_16; + const double var_27 = var_26*w[1][3] + var_14*w[0][3]; + const double var_28 = var_27*var_5 + var_25*var_3; + const double var_29 = var_23*w[0][3]*w[1][3] + var_18 + 0.5000000000000000000000000*var_28; + const double var_30 = w[0][3]*w[1][0] + w[0][0]*w[1][3]; + const double var_31 = var_24*w[1][0] + var_13*w[0][0]; + const double var_32 = -var_3 + var_5; + const double var_33 = var_31 + var_30*var_32; + const double var_34 = 0.5000000000000000000000000*var_1*var_33 + var_29; + const double var_35 = var_4*var_4; + const double var_36 = var_1*var_1; + const double var_37 = var_35 + var_36; + const double var_38 = var_1*var_4; + const double var_39 = -0.5000000000000000000000000*var_37 + var_38; + const double var_40 = var_39*w[0][0]*w[1][0]; + const double var_41 = var_26*w[1][0] + var_14*w[0][0]; + const double var_42 = var_4*var_41 + var_1*var_31; + const double var_43 = var_18 + var_40 + 0.5000000000000000000000000*var_42; + const double var_44 = -var_4 + var_1; + const double var_45 = var_27 + var_30*var_44; + const double var_46 = var_43 + 0.5000000000000000000000000*var_45*var_5; + const double var_47 = var_1*var_1*var_34 + -0.5000000000000000000000000*var_10 + var_46*var_5*var_5; + const double var_48 = var_1*var_1*var_1*var_4*w[0][0]*w[1][0] + var_3*var_5*var_5*var_5*w[0][3]*w[1][3]; + const double var_49 = var_3*var_3*var_3*var_5*w[0][3]*w[1][3] + var_1*var_4*var_4*var_4*w[0][0]*w[1][0]; + const double var_50 = -var_5 + var_3; + const double var_51 = var_41 + var_30*var_50; + const double var_52 = -var_1 + var_4; + const double var_53 = var_25 + var_30*var_52; + const double var_54 = var_1*var_1*var_4*var_51 + var_3*var_5*var_5*var_53; + const double var_55 = var_3*var_3*var_45*var_5 + var_1*var_33*var_4*var_4; + const double var_56 = var_3*var_3*var_3*var_3*w[0][3]*w[1][3] + var_4*var_4*var_4*var_4*w[0][0]*w[1][0]; + const double var_57 = var_14*var_15 + var_13*var_16; + const double var_58 = 0.5000000000000000000000000*var_57; + const double var_59 = -var_3*var_5 + 0.5000000000000000000000000*var_21; + const double var_60 = var_27*var_3 + var_25*var_5; + const double var_61 = var_59*w[0][3]*w[1][3] + var_58 + 0.5000000000000000000000000*var_60; + const double var_62 = 0.5000000000000000000000000*var_33*var_4 + var_61; + const double var_63 = -var_1*var_4 + 0.5000000000000000000000000*var_37; + const double var_64 = var_63*w[0][0]*w[1][0]; + const double var_65 = var_31*var_4 + var_1*var_41; + const double var_66 = var_58 + var_64 + 0.5000000000000000000000000*var_65; + const double var_67 = var_66 + 0.5000000000000000000000000*var_3*var_45; + const double var_68 = var_4*var_4*var_62 + var_3*var_3*var_67 + 0.5000000000000000000000000*var_56; + const double var_69 = 0.0250000000000000013877788*var_68; + const double var_70 = var_1*var_4*var_61 + var_3*var_5*var_66; + const double var_71 = var_3*var_3*var_5*var_5*w[0][3]*w[1][3] + var_1*var_1*var_4*var_4*w[0][0]*w[1][0]; + const double var_72 = -1.5000000000000000000000000*var_71; + const double var_73 = var_70 + var_72; + const double var_74 = 0.4250000000000000444089210*var_73; + const double var_75 = var_69 + var_74 + 0.2000000000000000111022302*var_55 + 0.4375000000000000000000000*var_54 + 0.6625000000000000888178420*var_48 + 0.1875000000000000000000000*var_49 + 0.4500000000000000111022302*var_47; + A[7] = 3.0000000000000000000000000*var_75*var_8/(var_9*var_9*var_9*var_9); + const double var_76 = 0.5000000000000000000000000*var_1*var_51; + const double var_77 = var_62 + var_64 + var_76; + A[344] = 0.0000000000000000000000000; + const double var_78 = 0.5000000000000000000000000*var_4*var_51; + const double var_79 = var_78 + var_29; + const double var_80 = var_43 + 0.5000000000000000000000000*var_3*var_53; + const double var_81 = var_4*var_4*var_79 + -0.5000000000000000000000000*var_56 + var_3*var_3*var_80; + const double var_82 = var_76 + var_61; + const double var_83 = 0.5000000000000000000000000*var_5*var_53 + var_66; + const double var_84 = var_1*var_1*var_82 + 0.5000000000000000000000000*var_10 + var_5*var_5*var_83; + const double var_85 = 0.0250000000000000013877788*var_84; + const double var_86 = var_85 + 0.6625000000000000888178420*var_49 + 0.1875000000000000000000000*var_48 + 0.2000000000000000111022302*var_54 + 0.4500000000000000111022302*var_81 + 0.4375000000000000000000000*var_55 + var_74; + A[5] = 3.0000000000000000000000000*var_8*var_86/(var_9*var_9*var_9*var_9); + A[100] = A[5]; + const double var_87 = var_1*var_1*var_33*var_4 + var_3*var_45*var_5*var_5; + const double var_88 = var_3*var_43*var_5 + var_1*var_29*var_4; + const double var_89 = -var_49; + const double var_90 = var_1*var_4*var_4*var_51 + var_3*var_3*var_5*var_53; + const double var_91 = 0.5000000000000000000000000*var_90; + const double var_92 = 0.5000000000000000000000000*var_89 + var_88 + var_91; + const double var_93 = 0.1000000000000000055511151*var_84; + const double var_94 = 1.9500000000000001776356839*var_71; + const double var_95 = var_93 + -1.0500000000000000444089210*var_48 + 1.9000000000000001332267630*var_92 + var_87 + var_94; + A[23] = 0.7500000000000000000000000*var_8*var_95/(var_9*var_9*var_9*var_9); + A[61] = A[23]; + const double var_96 = var_47 + 1.5000000000000000000000000*var_48 + var_54; + const double var_97 = 0.2000000000000000111022302*var_70 + -0.3250000000000000111022302*var_71; + const double var_98 = 0.1250000000000000000000000*var_55 + 0.0500000000000000027755576*var_81 + 0.1500000000000000222044605*var_49 + 0.2000000000000000111022302*var_96 + var_97; + A[97] = 0.0000000000000000000000000; + const double var_99 = var_34 + var_40 + var_78; + const double var_100 = var_22 + var_38; + A[107] = 3.3750000000000000000000000*var_100*var_8*var_99/(var_9*var_9*var_9*var_9); + A[355] = A[107]; + const double var_101 = var_55 + var_49; + const double var_102 = var_70 + 0.5000000000000000000000000*var_101; + const double var_103 = var_96 + var_102 + var_72; + A[69] = 4.0499999999999998223643161*var_103*var_8/(var_9*var_9*var_9*var_9); + A[183] = A[69]; + const double var_104 = var_19 + var_35; + A[47] = 0.0750000000000000111022302*var_104*var_8*var_99/(var_9*var_9*var_9*var_9); + A[142] = A[47]; + const double var_105 = 0.3125000000000000000000000*var_71; + const double var_106 = -0.3250000000000000111022302*var_48 + 0.2250000000000000055511151*var_84 + 0.2125000000000000222044605*var_87 + 0.2000000000000000111022302*var_92 + var_105; + A[27] = 3.0000000000000000000000000*var_106*var_8/(var_9*var_9*var_9*var_9); + A[351] = A[27]; + A[129] = 4.0499999999999998223643161*var_100*var_8*var_99/(var_9*var_9*var_9*var_9); + const double var_107 = -var_48; + const double var_108 = 0.5000000000000000000000000*var_87; + const double var_109 = 0.5000000000000000000000000*var_107 + var_88 + var_108; + const double var_110 = 1.5000000000000000000000000*var_71; + const double var_111 = var_68 + var_90 + 1.5000000000000000000000000*var_89 + var_109 + var_110; + A[67] = 0.6750000000000000444089210*var_111*var_8/(var_9*var_9*var_9*var_9); + A[353] = A[67]; + A[90] = 0.0000000000000000000000000; + A[96] = 0.0000000000000000000000000; + const double var_112 = var_81 + var_47; + const double var_113 = 0.5000000000000000000000000*var_112; + const double var_114 = var_48 + var_49; + const double var_115 = var_55 + var_54; + const double var_116 = var_114 + var_73 + var_113 + 0.7500000000000000000000000*var_115; + A[3] = 0.1500000000000000222044605*var_116*var_8/(var_9*var_9*var_9*var_9); + A[290] = A[3]; + A[150] = 0.0000000000000000000000000; + A[206] = 0.0000000000000000000000000; + A[108] = 0.6750000000000000444089210*var_100*var_77*var_8/(var_9*var_9*var_9*var_9); + A[127] = A[108]; + A[300] = 0.0000000000000000000000000; + A[55] = 0.0000000000000000000000000; + const double var_117 = -1.4000000000000001332267630*var_71; + const double var_118 = 0.9500000000000000666133815*var_102 + 0.9000000000000000222044605*var_47 + var_117 + 0.9250000000000000444089210*var_54 + 1.3750000000000000000000000*var_48; + A[28] = 1.5000000000000000000000000*var_118*var_8/(var_9*var_9*var_9*var_9); + A[238] = A[28]; + A[248] = 0.0000000000000000000000000; + A[200] = 0.0000000000000000000000000; + A[111] = 0.0000000000000000000000000; + A[146] = A[108]; + A[240] = 0.0000000000000000000000000; + const double var_119 = var_48 + var_54; + const double var_120 = var_70 + 0.5000000000000000000000000*var_119; + const double var_121 = var_81 + var_55 + 1.5000000000000000000000000*var_49; + const double var_122 = var_121 + var_120 + var_72; + A[68] = 3.3750000000000000000000000*var_122*var_8/(var_9*var_9*var_9*var_9); + A[163] = A[68]; + A[287] = 0.0000000000000000000000000; + A[110] = 0.0000000000000000000000000; + A[398] = A[129]; + A[119] = 0.0000000000000000000000000; + A[279] = A[69]; + A[75] = 0.0000000000000000000000000; + A[148] = 13.5000000000000000000000000*var_8*var_98/(var_9*var_9*var_9*var_9); + A[167] = A[148]; + A[297] = A[67]; + A[288] = 0.0000000000000000000000000; + const double var_123 = 0.1250000000000000000000000*var_72; + const double var_124 = 0.0750000000000000111022302*var_48 + 0.0875000000000000083266727*var_54 + var_85 + 0.2000000000000000111022302*var_102 + var_123; + A[24] = 3.0000000000000000000000000*var_124*var_8/(var_9*var_9*var_9*var_9); + A[291] = A[24]; + const double var_125 = 1.5000000000000000000000000*var_107 + var_84 + var_87 + var_92 + var_110; + A[65] = 0.6750000000000000444089210*var_125*var_8/(var_9*var_9*var_9*var_9); + A[333] = A[65]; + const double var_126 = var_108 + var_71 + var_91; + const double var_127 = 0.5000000000000000000000000*var_126 + var_88 + var_113; + A[64] = 1.3500000000000000888178420*var_127*var_8/(var_9*var_9*var_9*var_9); + A[293] = A[64]; + A[51] = 0.0000000000000000000000000; + A[362] = 0.0000000000000000000000000; + A[172] = 0.0000000000000000000000000; + A[286] = 0.0000000000000000000000000; + A[303] = 0.0000000000000000000000000; + A[365] = 0.0000000000000000000000000; + A[133] = 0.0000000000000000000000000; + A[384] = 0.0000000000000000000000000; + A[161] = A[28]; + A[2] = 0.1750000000000000166533454*var_122*var_8/(var_9*var_9*var_9*var_9); + A[212] = A[2]; + A[157] = 0.0000000000000000000000000; + A[170] = 0.0000000000000000000000000; + A[201] = 0.0000000000000000000000000; + const double var_128 = -0.3250000000000000111022302*var_49 + 0.2125000000000000222044605*var_90 + var_105 + 0.2250000000000000055511151*var_68 + 0.2000000000000000111022302*var_109; + A[45] = 3.0000000000000000000000000*var_128*var_8/(var_9*var_9*var_9*var_9); + A[312] = A[45]; + A[83] = A[64]; + A[4] = A[3]; + const double var_129 = 0.0750000000000000111022302*var_49 + 0.0875000000000000083266727*var_55 + var_69 + var_123 + 0.2000000000000000111022302*var_120; + A[43] = 3.0000000000000000000000000*var_129*var_8/(var_9*var_9*var_9*var_9); + A[62] = A[43]; + A[30] = 0.0000000000000000000000000; + A[228] = 0.0000000000000000000000000; + A[307] = 0.0000000000000000000000000; + A[74] = 0.0000000000000000000000000; + A[11] = 0.0000000000000000000000000; + A[99] = 0.0000000000000000000000000; + A[209] = 0.0000000000000000000000000; + A[71] = 0.0000000000000000000000000; + A[395] = A[69]; + A[338] = A[108]; + A[361] = 0.0000000000000000000000000; + A[162] = A[47]; + A[320] = 0.0000000000000000000000000; + A[229] = 0.0000000000000000000000000; + A[132] = 0.0000000000000000000000000; + A[272] = A[43]; + A[305] = 0.0000000000000000000000000; + A[215] = A[5]; + A[179] = 0.0000000000000000000000000; + A[181] = 0.0000000000000000000000000; + A[261] = 0.0000000000000000000000000; + A[34] = 0.0000000000000000000000000; + A[89] = 4.0499999999999998223643161*var_122*var_8/(var_9*var_9*var_9*var_9); + A[299] = A[89]; + A[274] = A[64]; + A[202] = 0.0000000000000000000000000; + A[225] = 0.0000000000000000000000000; + A[306] = 0.0000000000000000000000000; + const double var_130 = var_68 + var_84; + const double var_131 = 0.5000000000000000000000000*var_130; + const double var_132 = -0.7500000000000000000000000*var_114 + 0.5000000000000000000000000*var_88 + var_126 + var_131; + A[63] = 6.7500000000000000000000000*var_132*var_8/(var_9*var_9*var_9*var_9); + A[315] = A[63]; + A[239] = 0.0000000000000000000000000; + A[285] = 0.0000000000000000000000000; + A[49] = 0.0000000000000000000000000; + A[260] = 0.0000000000000000000000000; + A[219] = 0.0000000000000000000000000; + A[86] = 3.3750000000000000000000000*var_103*var_8/(var_9*var_9*var_9*var_9); + A[334] = A[86]; + A[22] = 0.1750000000000000166533454*var_100*var_8*var_99/(var_9*var_9*var_9*var_9); + A[251] = A[22]; + A[244] = 0.0000000000000000000000000; + A[242] = 0.0000000000000000000000000; + A[378] = A[63]; + A[324] = 0.0000000000000000000000000; + A[249] = 0.0000000000000000000000000; + const double var_133 = var_20 + var_36; + A[21] = 0.8500000000000000888178420*var_133*var_77*var_8/(var_9*var_9*var_9*var_9); + A[277] = A[67]; + A[221] = 0.0000000000000000000000000; + A[321] = 0.0000000000000000000000000; + A[77] = 0.0000000000000000000000000; + A[17] = 0.0000000000000000000000000; + const double var_134 = var_89 + var_88 + var_107 + 1.5000000000000000000000000*var_126 + var_131; + const double var_135 = 0.1000000000000000055511151*var_68; + A[104] = A[65]; + A[188] = A[129]; + A[374] = A[67]; + A[275] = A[65]; + A[70] = 0.0000000000000000000000000; + const double var_136 = var_88 + var_110; + const double var_137 = var_93 + 0.5500000000000000444089210*var_87 + 0.6000000000000000888178420*var_107 + 0.9000000000000000222044605*var_68 + -1.4000000000000001332267630*var_49 + 0.9500000000000000666133815*var_90 + var_136; + A[0] = 1.7000000000000001776356839*var_134*var_8/(var_9*var_9*var_9*var_9); + A[210] = A[0]; + A[109] = A[69]; + A[130] = 0.0000000000000000000000000; + const double var_138 = -1.4000000000000001332267630*var_48 + var_136 + 0.5500000000000000444089210*var_90 + 0.9000000000000000222044605*var_84 + 0.9500000000000000666133815*var_87 + var_135 + 0.6000000000000000888178420*var_89; + A[8] = 0.7500000000000000000000000*var_138*var_8/(var_9*var_9*var_9*var_9); + A[218] = A[8]; + A[94] = 0.0000000000000000000000000; + A[35] = 0.0000000000000000000000000; + A[42] = 0.8500000000000000888178420*var_104*var_77*var_8/(var_9*var_9*var_9*var_9); + A[252] = A[42]; + A[92] = 0.0000000000000000000000000; + A[296] = A[86]; + A[231] = A[21]; + const double var_139 = 0.2000000000000000111022302*var_121 + 0.1500000000000000222044605*var_48 + 0.1250000000000000000000000*var_54 + 0.0500000000000000027755576*var_47 + var_97; + A[106] = 13.5000000000000000000000000*var_139*var_8/(var_9*var_9*var_9*var_9); + A[316] = A[106]; + A[383] = 0.0000000000000000000000000; + A[360] = 0.0000000000000000000000000; + A[187] = A[89]; + A[114] = 0.0000000000000000000000000; + A[203] = 0.0000000000000000000000000; + A[60] = A[3]; + A[14] = 0.0000000000000000000000000; + A[177] = 0.0000000000000000000000000; + A[273] = A[63]; + A[139] = 0.0000000000000000000000000; + A[151] = 0.0000000000000000000000000; + A[227] = 0.0000000000000000000000000; + A[364] = 0.0000000000000000000000000; + A[246] = 0.0000000000000000000000000; + A[369] = 0.0000000000000000000000000; + A[310] = A[5]; + A[233] = A[23]; + A[262] = 0.0000000000000000000000000; + A[356] = A[108]; + A[368] = 0.0000000000000000000000000; + A[282] = 0.0000000000000000000000000; + A[259] = 0.0000000000000000000000000; + A[208] = 0.0000000000000000000000000; + A[269] = 0.0000000000000000000000000; + A[264] = 0.0000000000000000000000000; + const double var_140 = var_135 + -1.0500000000000000444089210*var_49 + var_90 + 1.9000000000000001332267630*var_109 + var_94; + A[241] = 0.0000000000000000000000000; + A[345] = 0.0000000000000000000000000; + A[37] = 0.0000000000000000000000000; + A[29] = 0.0000000000000000000000000; + A[15] = 0.0000000000000000000000000; + A[283] = 0.0000000000000000000000000; + A[25] = 0.0750000000000000111022302*var_133*var_8*var_99/(var_9*var_9*var_9*var_9); + A[26] = A[25]; + A[335] = A[106]; + A[143] = A[67]; + A[346] = 0.0000000000000000000000000; + A[196] = 0.0000000000000000000000000; + A[36] = 0.0000000000000000000000000; + A[1] = 0.1750000000000000166533454*var_103*var_8/(var_9*var_9*var_9*var_9); + A[230] = A[1]; + A[289] = 0.0000000000000000000000000; + A[270] = A[3]; + A[32] = 0.0000000000000000000000000; + A[126] = A[63]; + A[232] = A[22]; + A[160] = A[8]; + A[112] = 0.0000000000000000000000000; + A[358] = A[148]; + A[191] = 0.0000000000000000000000000; + A[295] = A[65]; + A[388] = 0.0000000000000000000000000; + A[349] = 0.0000000000000000000000000; + A[79] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[322] = 0.0000000000000000000000000; + A[186] = A[129]; + A[265] = 0.0000000000000000000000000; + A[197] = 0.0000000000000000000000000; + A[396] = A[129]; + A[397] = A[89]; + A[41] = A[22]; + A[66] = A[65]; + A[224] = 0.0000000000000000000000000; + A[54] = 0.0000000000000000000000000; + A[124] = A[86]; + A[20] = A[1]; + A[331] = A[25]; + A[80] = A[3]; + A[78] = 0.0000000000000000000000000; + A[134] = 0.0000000000000000000000000; + A[147] = A[63]; + A[91] = 0.0000000000000000000000000; + A[135] = 0.0000000000000000000000000; + A[348] = 0.0000000000000000000000000; + A[88] = A[67]; + A[263] = 0.0000000000000000000000000; + A[103] = A[65]; + A[6] = 0.7500000000000000000000000*var_137*var_8/(var_9*var_9*var_9*var_9); + A[216] = A[6]; + A[382] = 0.0000000000000000000000000; + A[211] = A[1]; + A[278] = A[68]; + A[394] = A[89]; + A[116] = 0.0000000000000000000000000; + A[171] = 0.0000000000000000000000000; + A[12] = 0.0000000000000000000000000; + A[182] = 0.0000000000000000000000000; + A[375] = A[108]; + A[44] = 0.7500000000000000000000000*var_140*var_8/(var_9*var_9*var_9*var_9); + A[280] = 0.0000000000000000000000000; + A[329] = 0.0000000000000000000000000; + A[302] = 0.0000000000000000000000000; + A[123] = A[65]; + A[235] = A[25]; + A[19] = 0.0000000000000000000000000; + A[199] = 0.0000000000000000000000000; + A[226] = 0.0000000000000000000000000; + A[281] = 0.0000000000000000000000000; + A[31] = 0.0000000000000000000000000; + A[313] = A[65]; + A[165] = A[108]; + const double var_141 = 0.9500000000000000666133815*var_120 + 0.9000000000000000222044605*var_81 + 0.9250000000000000444089210*var_55 + 1.3750000000000000000000000*var_49 + var_117; + A[46] = 1.5000000000000000000000000*var_141*var_8/(var_9*var_9*var_9*var_9); + A[332] = A[46]; + A[237] = A[27]; + A[267] = 0.0000000000000000000000000; + A[72] = 0.0000000000000000000000000; + A[271] = A[23]; + A[141] = A[27]; + A[84] = A[63]; + A[372] = A[47]; + A[57] = 0.0000000000000000000000000; + A[352] = A[47]; + A[115] = 0.0000000000000000000000000; + A[234] = A[24]; + A[359] = A[89]; + A[194] = 0.0000000000000000000000000; + A[93] = 0.0000000000000000000000000; + A[118] = 0.0000000000000000000000000; + A[144] = A[67]; + A[87] = A[67]; + A[367] = 0.0000000000000000000000000; + A[311] = A[25]; + A[82] = A[44]; + A[317] = A[107]; + A[213] = A[3]; + A[153] = 0.0000000000000000000000000; + A[255] = A[45]; + A[95] = 0.0000000000000000000000000; + A[339] = A[129]; + A[52] = 0.0000000000000000000000000; + A[258] = A[47]; + A[377] = A[148]; + A[190] = 0.0000000000000000000000000; + A[145] = A[107]; + A[354] = A[67]; + A[175] = 0.0000000000000000000000000; + A[350] = A[7]; + A[180] = 0.0000000000000000000000000; + A[198] = 0.0000000000000000000000000; + A[16] = 0.0000000000000000000000000; + A[59] = 0.0000000000000000000000000; + A[39] = 0.0000000000000000000000000; + A[195] = 0.0000000000000000000000000; + A[73] = 0.0000000000000000000000000; + A[385] = 0.0000000000000000000000000; + A[256] = A[46]; + A[326] = 0.0000000000000000000000000; + A[381] = 0.0000000000000000000000000; + A[341] = 0.0000000000000000000000000; + A[217] = A[7]; + A[371] = A[28]; + A[304] = 0.0000000000000000000000000; + A[205] = 0.0000000000000000000000000; + A[373] = A[68]; + A[13] = 0.0000000000000000000000000; + A[185] = A[69]; + A[318] = A[108]; + A[276] = A[65]; + A[253] = A[43]; + A[98] = 0.0000000000000000000000000; + A[254] = A[44]; + A[85] = A[65]; + A[140] = A[7]; + A[393] = A[69]; + A[319] = A[69]; + A[156] = 0.0000000000000000000000000; + A[386] = 0.0000000000000000000000000; + A[178] = 0.0000000000000000000000000; + A[284] = 0.0000000000000000000000000; + A[121] = A[25]; + A[10] = 0.0000000000000000000000000; + A[152] = 0.0000000000000000000000000; + A[117] = 0.0000000000000000000000000; + A[33] = 0.0000000000000000000000000; + A[113] = 0.0000000000000000000000000; + A[294] = A[63]; + A[220] = 0.0000000000000000000000000; + A[53] = 0.0000000000000000000000000; + A[164] = A[67]; + A[40] = A[2]; + A[366] = 0.0000000000000000000000000; + A[137] = 0.0000000000000000000000000; + A[357] = A[63]; + A[301] = 0.0000000000000000000000000; + A[243] = 0.0000000000000000000000000; + A[189] = 16.1999999999999992894572642*var_132*var_8/(var_9*var_9*var_9*var_9); + A[399] = A[189]; + A[376] = A[108]; + A[214] = A[3]; + A[336] = A[63]; + A[207] = 0.0000000000000000000000000; + A[268] = 0.0000000000000000000000000; + A[340] = 0.0000000000000000000000000; + A[138] = 0.0000000000000000000000000; + A[155] = 0.0000000000000000000000000; + A[102] = A[45]; + A[245] = 0.0000000000000000000000000; + A[176] = 0.0000000000000000000000000; + A[81] = A[24]; + A[168] = A[63]; + A[391] = 0.0000000000000000000000000; + A[184] = A[89]; + A[58] = 0.0000000000000000000000000; + A[390] = 0.0000000000000000000000000; + A[223] = 0.0000000000000000000000000; + A[266] = 0.0000000000000000000000000; + A[327] = 0.0000000000000000000000000; + A[159] = 0.0000000000000000000000000; + A[50] = 0.0000000000000000000000000; + A[325] = 0.0000000000000000000000000; + A[120] = A[6]; + A[204] = 0.0000000000000000000000000; + A[136] = 0.0000000000000000000000000; + A[347] = 0.0000000000000000000000000; + A[337] = A[108]; + A[48] = A[47]; + A[370] = A[8]; + A[380] = 0.0000000000000000000000000; + A[192] = 0.0000000000000000000000000; + A[76] = 0.0000000000000000000000000; + A[173] = 0.0000000000000000000000000; + A[342] = 0.0000000000000000000000000; + A[309] = 0.0000000000000000000000000; + A[122] = A[46]; + A[101] = A[25]; + A[257] = A[47]; + A[169] = A[129]; + A[308] = 0.0000000000000000000000000; + A[292] = A[44]; + A[328] = 0.0000000000000000000000000; + A[298] = A[67]; + A[250] = A[2]; + A[379] = A[129]; + A[38] = 0.0000000000000000000000000; + A[149] = A[89]; + A[222] = 0.0000000000000000000000000; + A[166] = A[108]; + A[330] = A[6]; + A[389] = 0.0000000000000000000000000; + A[105] = A[63]; + A[154] = 0.0000000000000000000000000; + A[125] = A[106]; + A[131] = 0.0000000000000000000000000; + A[128] = A[108]; + A[56] = 0.0000000000000000000000000; + A[343] = 0.0000000000000000000000000; + A[158] = 0.0000000000000000000000000; + A[9] = 0.0000000000000000000000000; + A[387] = 0.0000000000000000000000000; + A[392] = 0.0000000000000000000000000; + A[247] = 0.0000000000000000000000000; + A[174] = 0.0000000000000000000000000; + A[236] = A[25]; + A[323] = 0.0000000000000000000000000; + A[314] = A[65]; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q3_quadrature.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q3_quadrature.h new file mode 100644 index 0000000..926fb0e --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q3_quadrature.h @@ -0,0 +1,12105 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F2_P1_Q3_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F2_P1_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q3_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q3_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q3_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q3_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q3_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q3_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f2_p1_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W6[6] = {0.054975871827661, 0.054975871827661, 0.054975871827661, 0.111690794839005, 0.111690794839005, 0.111690794839005}; + // Quadrature points on the UFC reference element: (0.816847572980459, 0.091576213509771), (0.091576213509771, 0.816847572980459), (0.091576213509771, 0.091576213509771), (0.10810301816807, 0.445948490915965), (0.445948490915965, 0.10810301816807), (0.445948490915965, 0.445948490915965) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[6][2] = \ + {{-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + static const double FE1_C0_D01[6][9] = \ + {{-0.289027817302694, 0.289027817302687, 5.33192534762283, -1.65611126921075, -0.113213738890623, 0.113213738890629, 1.65611126921077, -5.33192534762283, -2.06501482580279e-14}, + {-0.289027817302695, 2.65611126921076, -0.298879221903342, 1.60760984840734, 1.35723204730744, -3.72431549921551, 0.185665483012719, 0.298879221903341, -1.79327533142006}, + {-2.65611126921075, 0.289027817302687, -0.298879221903341, -0.185665483012718, 3.72431549921547, -1.35723204730741, -1.60760984840734, 0.298879221903342, 1.79327533142006}, + {0.328790654815627, -0.328790654815627, -0.328699037506192, 0.815162619262507, -2.68474576342806, 2.68474576342806, -0.815162619262507, 0.328699037506193, 0.0}, + {0.328790654815627, 0.184837380737491, 0.677977554306217, -0.70514200810302, -0.137185064956293, -0.376442970596826, -3.36272331773427, -0.677977554306216, 4.06786532583729}, + {-0.184837380737492, -0.328790654815627, 0.677977554306215, 3.36272331773427, 0.376442970596826, 0.137185064956294, 0.70514200810302, -0.677977554306216, -4.06786532583729}}; + + // Array of non-zero columns + static const unsigned int nzc10[9] = {10, 12, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc7[9] = {0, 2, 3, 4, 5, 6, 7, 8, 9}; + + static const double FE1_C0_D10[6][9] = \ + {{-0.289027817302695, 2.65611126921076, 1.60760984840734, -0.298879221903343, 0.185665483012717, 0.298879221903344, 1.35723204730743, -3.7243154992155, -1.79327533142006}, + {-0.289027817302695, 0.289027817302689, -1.65611126921075, 5.33192534762283, 1.65611126921078, -5.33192534762283, -0.113213738890622, 0.113213738890627, -2.16402533218167e-14}, + {-2.65611126921075, 0.289027817302688, -0.185665483012718, -0.298879221903344, -1.60760984840734, 0.298879221903344, 3.72431549921547, -1.35723204730741, 1.79327533142006}, + {0.328790654815627, 0.184837380737492, -0.70514200810302, 0.677977554306215, -3.36272331773427, -0.677977554306215, -0.137185064956292, -0.376442970596827, 4.06786532583729}, + {0.328790654815627, -0.328790654815627, 0.815162619262508, -0.328699037506193, -0.815162619262508, 0.328699037506194, -2.68474576342806, 2.68474576342806, 0.0}, + {-0.184837380737492, -0.328790654815627, 3.36272331773427, 0.677977554306218, 0.705142008103019, -0.677977554306217, 0.376442970596827, 0.137185064956292, -4.06786532583729}}; + + // Array of non-zero columns + static const unsigned int nzc11[9] = {10, 11, 13, 14, 15, 16, 17, 18, 19}; + + // Array of non-zero columns + static const unsigned int nzc8[9] = {0, 1, 3, 4, 5, 6, 7, 8, 9}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 400; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 180. + double G[30]; + G[0] = K_00*K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_00*K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_00*K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_00*K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_10*K_10*det*(K_10*K_10 + K_11*K_11); + G[5] = K_01*K_10*det*(K_10*K_10 + K_11*K_11); + G[6] = K_10*K_11*det*(K_10*K_10 + K_11*K_11); + G[7] = K_01*K_01*det*(K_10*K_10 + K_11*K_11); + G[8] = K_01*K_11*det*(K_10*K_10 + K_11*K_11); + G[9] = K_11*K_11*det*(K_10*K_10 + K_11*K_11); + G[10] = K_00*K_00*det*(K_00*K_10 + K_01*K_11); + G[11] = K_00*K_10*det*(K_00*K_10 + K_01*K_11); + G[12] = K_00*K_01*det*(K_00*K_10 + K_01*K_11); + G[13] = K_00*K_11*det*(K_00*K_10 + K_01*K_11); + G[14] = K_10*K_10*det*(K_00*K_10 + K_01*K_11); + G[15] = K_01*K_10*det*(K_00*K_10 + K_01*K_11); + G[16] = K_10*K_11*det*(K_00*K_10 + K_01*K_11); + G[17] = K_01*K_01*det*(K_00*K_10 + K_01*K_11); + G[18] = K_01*K_11*det*(K_00*K_10 + K_01*K_11); + G[19] = K_11*K_11*det*(K_00*K_10 + K_01*K_11); + G[20] = K_00*K_00*det*(K_00*K_00 + K_01*K_01); + G[21] = K_00*K_10*det*(K_00*K_00 + K_01*K_01); + G[22] = K_00*K_01*det*(K_00*K_00 + K_01*K_01); + G[23] = K_00*K_11*det*(K_00*K_00 + K_01*K_01); + G[24] = K_10*K_10*det*(K_00*K_00 + K_01*K_01); + G[25] = K_01*K_10*det*(K_00*K_00 + K_01*K_01); + G[26] = K_10*K_11*det*(K_00*K_00 + K_01*K_01); + G[27] = K_01*K_01*det*(K_00*K_00 + K_01*K_01); + G[28] = K_01*K_11*det*(K_00*K_00 + K_01*K_01); + G[29] = K_11*K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 12504 + for (unsigned int ip = 0; ip < 6; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + double F4 = 0.0; + double F5 = 0.0; + double F6 = 0.0; + double F7 = 0.0; + + // Total number of operations to compute function values = 32 + for (unsigned int r = 0; r < 2; r++) + { + F0 += FE0_C0_D01[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D01[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + F4 += FE0_C0_D01[ip][r]*w[1][nzc2[r]]; + F5 += FE0_C0_D01[ip][r]*w[1][nzc1[r]]; + F6 += FE0_C0_D01[ip][r]*w[1][nzc5[r]]; + F7 += FE0_C0_D01[ip][r]*w[1][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 108 + double I[3]; + // Number of operations: 36 + I[0] = W6[ip]*(F4*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]) + F5*(F0*G[1] + F1*G[4] + F2*G[5] + F3*G[6]) + F6*(F0*G[2] + F1*G[5] + F2*G[7] + F3*G[8]) + F7*(F0*G[3] + F1*G[6] + F2*G[8] + F3*G[9])); + + // Number of operations: 36 + I[1] = W6[ip]*(F4*(F0*G[10] + F1*G[11] + F2*G[12] + F3*G[13]) + F5*(F0*G[11] + F1*G[14] + F2*G[15] + F3*G[16]) + F6*(F0*G[12] + F1*G[15] + F2*G[17] + F3*G[18]) + F7*(F0*G[13] + F1*G[16] + F2*G[18] + F3*G[19])); + + // Number of operations: 36 + I[2] = W6[ip]*(F4*(F0*G[20] + F1*G[21] + F2*G[22] + F3*G[23]) + F5*(F0*G[21] + F1*G[24] + F2*G[25] + F3*G[26]) + F6*(F0*G[22] + F1*G[25] + F2*G[27] + F3*G[28]) + F7*(F0*G[23] + F1*G[26] + F2*G[28] + F3*G[29])); + + + // Number of operations for primary indices: 1944 + for (unsigned int j = 0; j < 9; j++) + { + for (unsigned int k = 0; k < 9; k++) + { + // Number of operations to compute entry: 3 + A[nzc10[j]*20 + nzc10[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc10[j]*20 + nzc11[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*20 + nzc10[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*20 + nzc11[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc7[j]*20 + nzc7[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc7[j]*20 + nzc8[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*20 + nzc7[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*20 + nzc8[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f2_p1_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), Product(IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 2; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q3_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q3_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q3_tensor.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q3_tensor.h new file mode 100644 index 0000000..6051baf --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q3_tensor.h @@ -0,0 +1,12604 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F2_P1_Q3_TENSOR_H +#define __VECTOR_LAPLACIAN_F2_P1_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q3_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 10; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 10; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q3_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 20; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Compute value(s). + for (unsigned int r = 0; r < 10; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 1: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 2: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 4: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 5: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 6: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 7: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 8: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 9: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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 10: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791033, -0.0288675134594813, -0.0166666666666666, 0.0782460796435952, 0.0606091526731326, 0.0349927106111883, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0288675134594813, -0.0166666666666666, 0.0782460796435952, -0.0606091526731327, 0.0349927106111883, 0.0601337794302955, -0.0508223195384204, 0.0393667994375868, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.0471404520791032, 0.0, 0.0333333333333334, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 0.0, 0.0909137290096989}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, 0.117369119465393, 0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, -0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, 0.151522881682832, 0.0262445329583912, 0.0, 0.0, 0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, 0.117369119465393, -0.0606091526731326, -0.0787335988751736, 0.0, 0.101644639076841, 0.131222664791956, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.0, 0.3, 0.0, -0.151522881682832, 0.0262445329583912, 0.0, 0.0, -0.131222664791956, -0.136370593514548}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, -0.259807621135332, -0.15, -0.0782460796435952, 0.090913729009699, 0.0962299541807677, 0.180401338290886, 0.0508223195384204, -0.0131222664791956, -0.0227284322524247}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.106066017177982, 0.259807621135332, -0.15, -0.0782460796435952, -0.090913729009699, 0.0962299541807678, -0.180401338290886, 0.0508223195384204, 0.0131222664791956, -0.0227284322524248}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[6] *= std::sqrt(14.0); + + // Table(s) of coefficients. + static const double coefficients0[10] = \ + {0.636396103067893, 0.0, 0.0, -0.234738238930785, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 0.0, 0.090913729009699}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556636, 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, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470957, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; 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 < 10; s++) + { + for (unsigned int t = 0; t < 10; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 20; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 12: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 13: + { + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 14: + { + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 15: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[1]; + y[0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[1]; + y[0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + y[1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + y[1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + y[1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[10]; + vertex_values[3] = dof_values[11]; + vertex_values[5] = dof_values[12]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q3_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q3_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 2*m.num_entities[1] + m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 10; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 10; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 1; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q3_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q3_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 4*m.num_entities[1] + 2*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 20; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 20; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 8; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 4; + break; + } + case 2: + { + return 2; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 2*c.entity_indices[1][0]; + dofs[4] = offset + 2*c.entity_indices[1][0] + 1; + dofs[5] = offset + 2*c.entity_indices[1][1]; + dofs[6] = offset + 2*c.entity_indices[1][1] + 1; + dofs[7] = offset + 2*c.entity_indices[1][2]; + dofs[8] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[9] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + dofs[10] = offset + c.entity_indices[0][0]; + dofs[11] = offset + c.entity_indices[0][1]; + dofs[12] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[13] = offset + 2*c.entity_indices[1][0]; + dofs[14] = offset + 2*c.entity_indices[1][0] + 1; + dofs[15] = offset + 2*c.entity_indices[1][1]; + dofs[16] = offset + 2*c.entity_indices[1][1] + 1; + dofs[17] = offset + 2*c.entity_indices[1][2]; + dofs[18] = offset + 2*c.entity_indices[1][2] + 1; + offset += 2*m.num_entities[1]; + dofs[19] = offset + c.entity_indices[2][0]; + offset += m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 11; + dofs[5] = 12; + dofs[6] = 13; + dofs[7] = 14; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 5; + dofs[3] = 6; + dofs[4] = 10; + dofs[5] = 12; + dofs[6] = 15; + dofs[7] = 16; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 7; + dofs[3] = 8; + dofs[4] = 10; + dofs[5] = 11; + dofs[6] = 17; + dofs[7] = 18; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 10; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 11; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 12; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 13; + dofs[3] = 14; + break; + } + case 1: + { + dofs[0] = 5; + dofs[1] = 6; + dofs[2] = 15; + dofs[3] = 16; + break; + } + case 2: + { + dofs[0] = 7; + dofs[1] = 8; + dofs[2] = 17; + dofs[3] = 18; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 9; + dofs[1] = 19; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[3][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[4][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[4][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[5][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[5][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[6][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[6][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[7][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[7][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[8][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[8][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[9][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[9][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[10][0] = x[0][0]; + coordinates[10][1] = x[0][1]; + coordinates[11][0] = x[1][0]; + coordinates[11][1] = x[1][1]; + coordinates[12][0] = x[2][0]; + coordinates[12][1] = x[2][1]; + coordinates[13][0] = 0.666666666666667*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[13][1] = 0.666666666666667*x[1][1] + 0.333333333333333*x[2][1]; + coordinates[14][0] = 0.333333333333333*x[1][0] + 0.666666666666667*x[2][0]; + coordinates[14][1] = 0.333333333333333*x[1][1] + 0.666666666666667*x[2][1]; + coordinates[15][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[2][0]; + coordinates[15][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[2][1]; + coordinates[16][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[2][0]; + coordinates[16][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[2][1]; + coordinates[17][0] = 0.666666666666667*x[0][0] + 0.333333333333333*x[1][0]; + coordinates[17][1] = 0.666666666666667*x[0][1] + 0.333333333333333*x[1][1]; + coordinates[18][0] = 0.333333333333333*x[0][0] + 0.666666666666667*x[1][0]; + coordinates[18][1] = 0.333333333333333*x[0][1] + 0.666666666666667*x[1][1]; + coordinates[19][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0]; + coordinates[19][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f2_p1_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 1024 + // Number of operations (multiply-add pairs) for tensor contraction: 3906 + // Total number of operations (multiply-add pairs): 4941 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[143] = 0.168750000000007*G0_0_1_0_0_0_0_0_0 + 0.168750000000007*G0_0_1_0_0_0_0_0_1 - 0.168750000000007*G0_0_1_0_0_0_1_0_0 - 0.168750000000007*G0_0_1_0_0_0_2_0_1 + 0.168750000000007*G0_0_1_0_0_0_3_1_0 + 0.168750000000007*G0_0_1_0_0_0_3_1_1 - 0.168750000000007*G0_0_1_0_0_0_4_1_0 - 0.168750000000007*G0_0_1_0_0_0_5_1_1 + 0.168750000000007*G0_0_1_0_0_1_0_0_0 + 0.168750000000007*G0_0_1_0_0_1_0_0_1 - 0.168750000000007*G0_0_1_0_0_1_1_0_0 - 0.168750000000007*G0_0_1_0_0_1_2_0_1 + 0.168750000000007*G0_0_1_0_0_1_3_1_0 + 0.168750000000007*G0_0_1_0_0_1_3_1_1 - 0.168750000000007*G0_0_1_0_0_1_4_1_0 - 0.168750000000007*G0_0_1_0_0_1_5_1_1 - 0.168750000000007*G0_0_1_1_0_0_0_0_0 - 0.168750000000007*G0_0_1_1_0_0_0_0_1 + 0.168750000000007*G0_0_1_1_0_0_1_0_0 + 0.168750000000007*G0_0_1_1_0_0_2_0_1 - 0.168750000000007*G0_0_1_1_0_0_3_1_0 - 0.168750000000007*G0_0_1_1_0_0_3_1_1 + 0.168750000000007*G0_0_1_1_0_0_4_1_0 + 0.168750000000007*G0_0_1_1_0_0_5_1_1 - 0.168750000000007*G0_0_1_2_0_1_0_0_0 - 0.168750000000007*G0_0_1_2_0_1_0_0_1 + 0.168750000000007*G0_0_1_2_0_1_1_0_0 + 0.168750000000007*G0_0_1_2_0_1_2_0_1 - 0.168750000000007*G0_0_1_2_0_1_3_1_0 - 0.168750000000007*G0_0_1_2_0_1_3_1_1 + 0.168750000000007*G0_0_1_2_0_1_4_1_0 + 0.168750000000007*G0_0_1_2_0_1_5_1_1 + 0.168750000000007*G0_0_1_3_1_0_0_0_0 + 0.168750000000007*G0_0_1_3_1_0_0_0_1 - 0.168750000000007*G0_0_1_3_1_0_1_0_0 - 0.168750000000007*G0_0_1_3_1_0_2_0_1 + 0.168750000000007*G0_0_1_3_1_0_3_1_0 + 0.168750000000007*G0_0_1_3_1_0_3_1_1 - 0.168750000000007*G0_0_1_3_1_0_4_1_0 - 0.168750000000007*G0_0_1_3_1_0_5_1_1 + 0.168750000000007*G0_0_1_3_1_1_0_0_0 + 0.168750000000007*G0_0_1_3_1_1_0_0_1 - 0.168750000000007*G0_0_1_3_1_1_1_0_0 - 0.168750000000007*G0_0_1_3_1_1_2_0_1 + 0.168750000000007*G0_0_1_3_1_1_3_1_0 + 0.168750000000007*G0_0_1_3_1_1_3_1_1 - 0.168750000000007*G0_0_1_3_1_1_4_1_0 - 0.168750000000007*G0_0_1_3_1_1_5_1_1 - 0.168750000000007*G0_0_1_4_1_0_0_0_0 - 0.168750000000007*G0_0_1_4_1_0_0_0_1 + 0.168750000000007*G0_0_1_4_1_0_1_0_0 + 0.168750000000007*G0_0_1_4_1_0_2_0_1 - 0.168750000000007*G0_0_1_4_1_0_3_1_0 - 0.168750000000007*G0_0_1_4_1_0_3_1_1 + 0.168750000000007*G0_0_1_4_1_0_4_1_0 + 0.168750000000007*G0_0_1_4_1_0_5_1_1 - 0.168750000000007*G0_0_1_5_1_1_0_0_0 - 0.168750000000007*G0_0_1_5_1_1_0_0_1 + 0.168750000000007*G0_0_1_5_1_1_1_0_0 + 0.168750000000007*G0_0_1_5_1_1_2_0_1 - 0.168750000000007*G0_0_1_5_1_1_3_1_0 - 0.168750000000007*G0_0_1_5_1_1_3_1_1 + 0.168750000000007*G0_0_1_5_1_1_4_1_0 + 0.168750000000007*G0_0_1_5_1_1_5_1_1 + 0.168750000000004*G0_1_0_0_0_0_0_0_0 + 0.168750000000004*G0_1_0_0_0_0_0_0_1 - 0.168750000000004*G0_1_0_0_0_0_1_0_0 - 0.168750000000004*G0_1_0_0_0_0_2_0_1 + 0.168750000000004*G0_1_0_0_0_0_3_1_0 + 0.168750000000004*G0_1_0_0_0_0_3_1_1 - 0.168750000000004*G0_1_0_0_0_0_4_1_0 - 0.168750000000004*G0_1_0_0_0_0_5_1_1 + 0.168750000000004*G0_1_0_0_0_1_0_0_0 + 0.168750000000004*G0_1_0_0_0_1_0_0_1 - 0.168750000000004*G0_1_0_0_0_1_1_0_0 - 0.168750000000004*G0_1_0_0_0_1_2_0_1 + 0.168750000000004*G0_1_0_0_0_1_3_1_0 + 0.168750000000004*G0_1_0_0_0_1_3_1_1 - 0.168750000000004*G0_1_0_0_0_1_4_1_0 - 0.168750000000004*G0_1_0_0_0_1_5_1_1 - 0.168750000000004*G0_1_0_1_0_0_0_0_0 - 0.168750000000004*G0_1_0_1_0_0_0_0_1 + 0.168750000000004*G0_1_0_1_0_0_1_0_0 + 0.168750000000004*G0_1_0_1_0_0_2_0_1 - 0.168750000000004*G0_1_0_1_0_0_3_1_0 - 0.168750000000004*G0_1_0_1_0_0_3_1_1 + 0.168750000000004*G0_1_0_1_0_0_4_1_0 + 0.168750000000004*G0_1_0_1_0_0_5_1_1 - 0.168750000000004*G0_1_0_2_0_1_0_0_0 - 0.168750000000004*G0_1_0_2_0_1_0_0_1 + 0.168750000000004*G0_1_0_2_0_1_1_0_0 + 0.168750000000004*G0_1_0_2_0_1_2_0_1 - 0.168750000000004*G0_1_0_2_0_1_3_1_0 - 0.168750000000004*G0_1_0_2_0_1_3_1_1 + 0.168750000000004*G0_1_0_2_0_1_4_1_0 + 0.168750000000004*G0_1_0_2_0_1_5_1_1 + 0.168750000000004*G0_1_0_3_1_0_0_0_0 + 0.168750000000004*G0_1_0_3_1_0_0_0_1 - 0.168750000000004*G0_1_0_3_1_0_1_0_0 - 0.168750000000004*G0_1_0_3_1_0_2_0_1 + 0.168750000000004*G0_1_0_3_1_0_3_1_0 + 0.168750000000004*G0_1_0_3_1_0_3_1_1 - 0.168750000000004*G0_1_0_3_1_0_4_1_0 - 0.168750000000004*G0_1_0_3_1_0_5_1_1 + 0.168750000000004*G0_1_0_3_1_1_0_0_0 + 0.168750000000004*G0_1_0_3_1_1_0_0_1 - 0.168750000000004*G0_1_0_3_1_1_1_0_0 - 0.168750000000004*G0_1_0_3_1_1_2_0_1 + 0.168750000000004*G0_1_0_3_1_1_3_1_0 + 0.168750000000004*G0_1_0_3_1_1_3_1_1 - 0.168750000000004*G0_1_0_3_1_1_4_1_0 - 0.168750000000004*G0_1_0_3_1_1_5_1_1 - 0.168750000000004*G0_1_0_4_1_0_0_0_0 - 0.168750000000004*G0_1_0_4_1_0_0_0_1 + 0.168750000000004*G0_1_0_4_1_0_1_0_0 + 0.168750000000004*G0_1_0_4_1_0_2_0_1 - 0.168750000000004*G0_1_0_4_1_0_3_1_0 - 0.168750000000004*G0_1_0_4_1_0_3_1_1 + 0.168750000000004*G0_1_0_4_1_0_4_1_0 + 0.168750000000004*G0_1_0_4_1_0_5_1_1 - 0.168750000000004*G0_1_0_5_1_1_0_0_0 - 0.168750000000004*G0_1_0_5_1_1_0_0_1 + 0.168750000000004*G0_1_0_5_1_1_1_0_0 + 0.168750000000004*G0_1_0_5_1_1_2_0_1 - 0.168750000000004*G0_1_0_5_1_1_3_1_0 - 0.168750000000004*G0_1_0_5_1_1_3_1_1 + 0.168750000000004*G0_1_0_5_1_1_4_1_0 + 0.168750000000004*G0_1_0_5_1_1_5_1_1 + 0.337500000000006*G0_1_1_0_0_0_0_0_0 + 0.337500000000006*G0_1_1_0_0_0_0_0_1 - 0.337500000000006*G0_1_1_0_0_0_1_0_0 - 0.337500000000006*G0_1_1_0_0_0_2_0_1 + 0.337500000000006*G0_1_1_0_0_0_3_1_0 + 0.337500000000006*G0_1_1_0_0_0_3_1_1 - 0.337500000000006*G0_1_1_0_0_0_4_1_0 - 0.337500000000006*G0_1_1_0_0_0_5_1_1 + 0.337500000000006*G0_1_1_0_0_1_0_0_0 + 0.337500000000006*G0_1_1_0_0_1_0_0_1 - 0.337500000000006*G0_1_1_0_0_1_1_0_0 - 0.337500000000006*G0_1_1_0_0_1_2_0_1 + 0.337500000000006*G0_1_1_0_0_1_3_1_0 + 0.337500000000006*G0_1_1_0_0_1_3_1_1 - 0.337500000000006*G0_1_1_0_0_1_4_1_0 - 0.337500000000006*G0_1_1_0_0_1_5_1_1 - 0.337500000000006*G0_1_1_1_0_0_0_0_0 - 0.337500000000006*G0_1_1_1_0_0_0_0_1 + 0.337500000000006*G0_1_1_1_0_0_1_0_0 + 0.337500000000006*G0_1_1_1_0_0_2_0_1 - 0.337500000000006*G0_1_1_1_0_0_3_1_0 - 0.337500000000006*G0_1_1_1_0_0_3_1_1 + 0.337500000000006*G0_1_1_1_0_0_4_1_0 + 0.337500000000006*G0_1_1_1_0_0_5_1_1 - 0.337500000000006*G0_1_1_2_0_1_0_0_0 - 0.337500000000006*G0_1_1_2_0_1_0_0_1 + 0.337500000000006*G0_1_1_2_0_1_1_0_0 + 0.337500000000006*G0_1_1_2_0_1_2_0_1 - 0.337500000000006*G0_1_1_2_0_1_3_1_0 - 0.337500000000006*G0_1_1_2_0_1_3_1_1 + 0.337500000000006*G0_1_1_2_0_1_4_1_0 + 0.337500000000006*G0_1_1_2_0_1_5_1_1 + 0.337500000000006*G0_1_1_3_1_0_0_0_0 + 0.337500000000006*G0_1_1_3_1_0_0_0_1 - 0.337500000000006*G0_1_1_3_1_0_1_0_0 - 0.337500000000006*G0_1_1_3_1_0_2_0_1 + 0.337500000000006*G0_1_1_3_1_0_3_1_0 + 0.337500000000006*G0_1_1_3_1_0_3_1_1 - 0.337500000000006*G0_1_1_3_1_0_4_1_0 - 0.337500000000006*G0_1_1_3_1_0_5_1_1 + 0.337500000000006*G0_1_1_3_1_1_0_0_0 + 0.337500000000006*G0_1_1_3_1_1_0_0_1 - 0.337500000000006*G0_1_1_3_1_1_1_0_0 - 0.337500000000006*G0_1_1_3_1_1_2_0_1 + 0.337500000000006*G0_1_1_3_1_1_3_1_0 + 0.337500000000006*G0_1_1_3_1_1_3_1_1 - 0.337500000000006*G0_1_1_3_1_1_4_1_0 - 0.337500000000006*G0_1_1_3_1_1_5_1_1 - 0.337500000000006*G0_1_1_4_1_0_0_0_0 - 0.337500000000006*G0_1_1_4_1_0_0_0_1 + 0.337500000000006*G0_1_1_4_1_0_1_0_0 + 0.337500000000006*G0_1_1_4_1_0_2_0_1 - 0.337500000000006*G0_1_1_4_1_0_3_1_0 - 0.337500000000006*G0_1_1_4_1_0_3_1_1 + 0.337500000000006*G0_1_1_4_1_0_4_1_0 + 0.337500000000006*G0_1_1_4_1_0_5_1_1 - 0.337500000000006*G0_1_1_5_1_1_0_0_0 - 0.337500000000006*G0_1_1_5_1_1_0_0_1 + 0.337500000000006*G0_1_1_5_1_1_1_0_0 + 0.337500000000006*G0_1_1_5_1_1_2_0_1 - 0.337500000000006*G0_1_1_5_1_1_3_1_0 - 0.337500000000006*G0_1_1_5_1_1_3_1_1 + 0.337500000000006*G0_1_1_5_1_1_4_1_0 + 0.337500000000006*G0_1_1_5_1_1_5_1_1; + A[329] = 0.0; + A[384] = 0.0; + A[180] = 0.0; + A[207] = 0.0; + A[17] = 0.0; + A[281] = 0.0; + A[257] = -0.0374999999999996*G0_1_1_0_0_0_0_0_0 - 0.0374999999999996*G0_1_1_0_0_0_0_0_1 + 0.0374999999999996*G0_1_1_0_0_0_1_0_0 + 0.0374999999999996*G0_1_1_0_0_0_2_0_1 - 0.0374999999999996*G0_1_1_0_0_0_3_1_0 - 0.0374999999999996*G0_1_1_0_0_0_3_1_1 + 0.0374999999999996*G0_1_1_0_0_0_4_1_0 + 0.0374999999999996*G0_1_1_0_0_0_5_1_1 - 0.0374999999999996*G0_1_1_0_0_1_0_0_0 - 0.0374999999999996*G0_1_1_0_0_1_0_0_1 + 0.0374999999999996*G0_1_1_0_0_1_1_0_0 + 0.0374999999999996*G0_1_1_0_0_1_2_0_1 - 0.0374999999999996*G0_1_1_0_0_1_3_1_0 - 0.0374999999999996*G0_1_1_0_0_1_3_1_1 + 0.0374999999999996*G0_1_1_0_0_1_4_1_0 + 0.0374999999999996*G0_1_1_0_0_1_5_1_1 + 0.0374999999999996*G0_1_1_1_0_0_0_0_0 + 0.0374999999999996*G0_1_1_1_0_0_0_0_1 - 0.0374999999999996*G0_1_1_1_0_0_1_0_0 - 0.0374999999999996*G0_1_1_1_0_0_2_0_1 + 0.0374999999999996*G0_1_1_1_0_0_3_1_0 + 0.0374999999999996*G0_1_1_1_0_0_3_1_1 - 0.0374999999999996*G0_1_1_1_0_0_4_1_0 - 0.0374999999999996*G0_1_1_1_0_0_5_1_1 + 0.0374999999999996*G0_1_1_2_0_1_0_0_0 + 0.0374999999999996*G0_1_1_2_0_1_0_0_1 - 0.0374999999999996*G0_1_1_2_0_1_1_0_0 - 0.0374999999999996*G0_1_1_2_0_1_2_0_1 + 0.0374999999999996*G0_1_1_2_0_1_3_1_0 + 0.0374999999999996*G0_1_1_2_0_1_3_1_1 - 0.0374999999999996*G0_1_1_2_0_1_4_1_0 - 0.0374999999999996*G0_1_1_2_0_1_5_1_1 - 0.0374999999999996*G0_1_1_3_1_0_0_0_0 - 0.0374999999999996*G0_1_1_3_1_0_0_0_1 + 0.0374999999999996*G0_1_1_3_1_0_1_0_0 + 0.0374999999999996*G0_1_1_3_1_0_2_0_1 - 0.0374999999999996*G0_1_1_3_1_0_3_1_0 - 0.0374999999999996*G0_1_1_3_1_0_3_1_1 + 0.0374999999999996*G0_1_1_3_1_0_4_1_0 + 0.0374999999999996*G0_1_1_3_1_0_5_1_1 - 0.0374999999999996*G0_1_1_3_1_1_0_0_0 - 0.0374999999999996*G0_1_1_3_1_1_0_0_1 + 0.0374999999999996*G0_1_1_3_1_1_1_0_0 + 0.0374999999999996*G0_1_1_3_1_1_2_0_1 - 0.0374999999999996*G0_1_1_3_1_1_3_1_0 - 0.0374999999999996*G0_1_1_3_1_1_3_1_1 + 0.0374999999999996*G0_1_1_3_1_1_4_1_0 + 0.0374999999999996*G0_1_1_3_1_1_5_1_1 + 0.0374999999999996*G0_1_1_4_1_0_0_0_0 + 0.0374999999999996*G0_1_1_4_1_0_0_0_1 - 0.0374999999999996*G0_1_1_4_1_0_1_0_0 - 0.0374999999999996*G0_1_1_4_1_0_2_0_1 + 0.0374999999999996*G0_1_1_4_1_0_3_1_0 + 0.0374999999999996*G0_1_1_4_1_0_3_1_1 - 0.0374999999999996*G0_1_1_4_1_0_4_1_0 - 0.0374999999999996*G0_1_1_4_1_0_5_1_1 + 0.0374999999999996*G0_1_1_5_1_1_0_0_0 + 0.0374999999999996*G0_1_1_5_1_1_0_0_1 - 0.0374999999999996*G0_1_1_5_1_1_1_0_0 - 0.0374999999999996*G0_1_1_5_1_1_2_0_1 + 0.0374999999999996*G0_1_1_5_1_1_3_1_0 + 0.0374999999999996*G0_1_1_5_1_1_3_1_1 - 0.0374999999999996*G0_1_1_5_1_1_4_1_0 - 0.0374999999999996*G0_1_1_5_1_1_5_1_1; + A[304] = 0.0; + A[62] = -A[257] - 0.3*G0_0_1_0_0_0_0_0_0 - 0.3*G0_0_1_0_0_0_0_0_1 + 0.3*G0_0_1_0_0_0_1_0_0 + 0.3*G0_0_1_0_0_0_2_0_1 - 0.3*G0_0_1_0_0_0_3_1_0 - 0.3*G0_0_1_0_0_0_3_1_1 + 0.3*G0_0_1_0_0_0_4_1_0 + 0.3*G0_0_1_0_0_0_5_1_1 - 0.3*G0_0_1_0_0_1_0_0_0 - 0.3*G0_0_1_0_0_1_0_0_1 + 0.3*G0_0_1_0_0_1_1_0_0 + 0.3*G0_0_1_0_0_1_2_0_1 - 0.3*G0_0_1_0_0_1_3_1_0 - 0.3*G0_0_1_0_0_1_3_1_1 + 0.3*G0_0_1_0_0_1_4_1_0 + 0.3*G0_0_1_0_0_1_5_1_1 + 0.3*G0_0_1_1_0_0_0_0_0 + 0.3*G0_0_1_1_0_0_0_0_1 - 0.3*G0_0_1_1_0_0_1_0_0 - 0.3*G0_0_1_1_0_0_2_0_1 + 0.3*G0_0_1_1_0_0_3_1_0 + 0.3*G0_0_1_1_0_0_3_1_1 - 0.3*G0_0_1_1_0_0_4_1_0 - 0.3*G0_0_1_1_0_0_5_1_1 + 0.3*G0_0_1_2_0_1_0_0_0 + 0.3*G0_0_1_2_0_1_0_0_1 - 0.3*G0_0_1_2_0_1_1_0_0 - 0.3*G0_0_1_2_0_1_2_0_1 + 0.3*G0_0_1_2_0_1_3_1_0 + 0.3*G0_0_1_2_0_1_3_1_1 - 0.3*G0_0_1_2_0_1_4_1_0 - 0.3*G0_0_1_2_0_1_5_1_1 - 0.3*G0_0_1_3_1_0_0_0_0 - 0.3*G0_0_1_3_1_0_0_0_1 + 0.3*G0_0_1_3_1_0_1_0_0 + 0.3*G0_0_1_3_1_0_2_0_1 - 0.3*G0_0_1_3_1_0_3_1_0 - 0.3*G0_0_1_3_1_0_3_1_1 + 0.3*G0_0_1_3_1_0_4_1_0 + 0.3*G0_0_1_3_1_0_5_1_1 - 0.3*G0_0_1_3_1_1_0_0_0 - 0.3*G0_0_1_3_1_1_0_0_1 + 0.3*G0_0_1_3_1_1_1_0_0 + 0.3*G0_0_1_3_1_1_2_0_1 - 0.3*G0_0_1_3_1_1_3_1_0 - 0.3*G0_0_1_3_1_1_3_1_1 + 0.3*G0_0_1_3_1_1_4_1_0 + 0.3*G0_0_1_3_1_1_5_1_1 + 0.3*G0_0_1_4_1_0_0_0_0 + 0.3*G0_0_1_4_1_0_0_0_1 - 0.3*G0_0_1_4_1_0_1_0_0 - 0.3*G0_0_1_4_1_0_2_0_1 + 0.3*G0_0_1_4_1_0_3_1_0 + 0.3*G0_0_1_4_1_0_3_1_1 - 0.3*G0_0_1_4_1_0_4_1_0 - 0.3*G0_0_1_4_1_0_5_1_1 + 0.3*G0_0_1_5_1_1_0_0_0 + 0.3*G0_0_1_5_1_1_0_0_1 - 0.3*G0_0_1_5_1_1_1_0_0 - 0.3*G0_0_1_5_1_1_2_0_1 + 0.3*G0_0_1_5_1_1_3_1_0 + 0.3*G0_0_1_5_1_1_3_1_1 - 0.3*G0_0_1_5_1_1_4_1_0 - 0.3*G0_0_1_5_1_1_5_1_1; + A[320] = 0.0; + A[353] = A[143]; + A[172] = 0.0; + A[178] = 0.0; + A[235] = -0.0375*G0_0_0_0_0_0_0_0_0 - 0.0375*G0_0_0_0_0_0_0_0_1 + 0.0375*G0_0_0_0_0_0_1_0_0 + 0.0375*G0_0_0_0_0_0_2_0_1 - 0.0375*G0_0_0_0_0_0_3_1_0 - 0.0375*G0_0_0_0_0_0_3_1_1 + 0.0375*G0_0_0_0_0_0_4_1_0 + 0.0375*G0_0_0_0_0_0_5_1_1 - 0.0375*G0_0_0_0_0_1_0_0_0 - 0.0375*G0_0_0_0_0_1_0_0_1 + 0.0375*G0_0_0_0_0_1_1_0_0 + 0.0375*G0_0_0_0_0_1_2_0_1 - 0.0375*G0_0_0_0_0_1_3_1_0 - 0.0375*G0_0_0_0_0_1_3_1_1 + 0.0375*G0_0_0_0_0_1_4_1_0 + 0.0375*G0_0_0_0_0_1_5_1_1 + 0.0375*G0_0_0_1_0_0_0_0_0 + 0.0375*G0_0_0_1_0_0_0_0_1 - 0.0375*G0_0_0_1_0_0_1_0_0 - 0.0375*G0_0_0_1_0_0_2_0_1 + 0.0375*G0_0_0_1_0_0_3_1_0 + 0.0375*G0_0_0_1_0_0_3_1_1 - 0.0375*G0_0_0_1_0_0_4_1_0 - 0.0375*G0_0_0_1_0_0_5_1_1 + 0.0375*G0_0_0_2_0_1_0_0_0 + 0.0375*G0_0_0_2_0_1_0_0_1 - 0.0375*G0_0_0_2_0_1_1_0_0 - 0.0375*G0_0_0_2_0_1_2_0_1 + 0.0375*G0_0_0_2_0_1_3_1_0 + 0.0375*G0_0_0_2_0_1_3_1_1 - 0.0375*G0_0_0_2_0_1_4_1_0 - 0.0375*G0_0_0_2_0_1_5_1_1 - 0.0375*G0_0_0_3_1_0_0_0_0 - 0.0375*G0_0_0_3_1_0_0_0_1 + 0.0375*G0_0_0_3_1_0_1_0_0 + 0.0375*G0_0_0_3_1_0_2_0_1 - 0.0375*G0_0_0_3_1_0_3_1_0 - 0.0375*G0_0_0_3_1_0_3_1_1 + 0.0375*G0_0_0_3_1_0_4_1_0 + 0.0375*G0_0_0_3_1_0_5_1_1 - 0.0375*G0_0_0_3_1_1_0_0_0 - 0.0375*G0_0_0_3_1_1_0_0_1 + 0.0375*G0_0_0_3_1_1_1_0_0 + 0.0375*G0_0_0_3_1_1_2_0_1 - 0.0375*G0_0_0_3_1_1_3_1_0 - 0.0375*G0_0_0_3_1_1_3_1_1 + 0.0375*G0_0_0_3_1_1_4_1_0 + 0.0375*G0_0_0_3_1_1_5_1_1 + 0.0375*G0_0_0_4_1_0_0_0_0 + 0.0375*G0_0_0_4_1_0_0_0_1 - 0.0375*G0_0_0_4_1_0_1_0_0 - 0.0375*G0_0_0_4_1_0_2_0_1 + 0.0375*G0_0_0_4_1_0_3_1_0 + 0.0375*G0_0_0_4_1_0_3_1_1 - 0.0375*G0_0_0_4_1_0_4_1_0 - 0.0375*G0_0_0_4_1_0_5_1_1 + 0.0375*G0_0_0_5_1_1_0_0_0 + 0.0375*G0_0_0_5_1_1_0_0_1 - 0.0375*G0_0_0_5_1_1_1_0_0 - 0.0375*G0_0_0_5_1_1_2_0_1 + 0.0375*G0_0_0_5_1_1_3_1_0 + 0.0375*G0_0_0_5_1_1_3_1_1 - 0.0375*G0_0_0_5_1_1_4_1_0 - 0.0375*G0_0_0_5_1_1_5_1_1; + A[199] = 0.0; + A[288] = 0.0; + A[248] = 0.0; + A[58] = 0.0; + A[14] = 0.0; + A[71] = 0.0; + A[35] = 0.0; + A[92] = 0.0; + A[52] = 0.0; + A[101] = A[235]; + A[77] = 0.0; + A[327] = 0.0; + A[134] = 0.0; + A[346] = 0.0; + A[155] = 0.0; + A[365] = 0.0; + A[209] = 0.0; + A[224] = 0.0; + A[299] = -5.9999999999998*A[143]; + A[379] = -A[299] - 2.025*G0_1_1_0_0_0_0_0_0 - 2.025*G0_1_1_0_0_0_0_0_1 + 2.025*G0_1_1_0_0_0_1_0_0 + 2.025*G0_1_1_0_0_0_2_0_1 - 2.025*G0_1_1_0_0_0_3_1_0 - 2.025*G0_1_1_0_0_0_3_1_1 + 2.025*G0_1_1_0_0_0_4_1_0 + 2.025*G0_1_1_0_0_0_5_1_1 - 2.025*G0_1_1_0_0_1_0_0_0 - 2.025*G0_1_1_0_0_1_0_0_1 + 2.025*G0_1_1_0_0_1_1_0_0 + 2.025*G0_1_1_0_0_1_2_0_1 - 2.025*G0_1_1_0_0_1_3_1_0 - 2.025*G0_1_1_0_0_1_3_1_1 + 2.025*G0_1_1_0_0_1_4_1_0 + 2.025*G0_1_1_0_0_1_5_1_1 + 2.025*G0_1_1_1_0_0_0_0_0 + 2.025*G0_1_1_1_0_0_0_0_1 - 2.025*G0_1_1_1_0_0_1_0_0 - 2.025*G0_1_1_1_0_0_2_0_1 + 2.025*G0_1_1_1_0_0_3_1_0 + 2.025*G0_1_1_1_0_0_3_1_1 - 2.025*G0_1_1_1_0_0_4_1_0 - 2.025*G0_1_1_1_0_0_5_1_1 + 2.025*G0_1_1_2_0_1_0_0_0 + 2.025*G0_1_1_2_0_1_0_0_1 - 2.025*G0_1_1_2_0_1_1_0_0 - 2.025*G0_1_1_2_0_1_2_0_1 + 2.025*G0_1_1_2_0_1_3_1_0 + 2.025*G0_1_1_2_0_1_3_1_1 - 2.025*G0_1_1_2_0_1_4_1_0 - 2.025*G0_1_1_2_0_1_5_1_1 - 2.025*G0_1_1_3_1_0_0_0_0 - 2.025*G0_1_1_3_1_0_0_0_1 + 2.025*G0_1_1_3_1_0_1_0_0 + 2.025*G0_1_1_3_1_0_2_0_1 - 2.025*G0_1_1_3_1_0_3_1_0 - 2.025*G0_1_1_3_1_0_3_1_1 + 2.025*G0_1_1_3_1_0_4_1_0 + 2.025*G0_1_1_3_1_0_5_1_1 - 2.025*G0_1_1_3_1_1_0_0_0 - 2.025*G0_1_1_3_1_1_0_0_1 + 2.025*G0_1_1_3_1_1_1_0_0 + 2.025*G0_1_1_3_1_1_2_0_1 - 2.025*G0_1_1_3_1_1_3_1_0 - 2.025*G0_1_1_3_1_1_3_1_1 + 2.025*G0_1_1_3_1_1_4_1_0 + 2.025*G0_1_1_3_1_1_5_1_1 + 2.025*G0_1_1_4_1_0_0_0_0 + 2.025*G0_1_1_4_1_0_0_0_1 - 2.025*G0_1_1_4_1_0_1_0_0 - 2.025*G0_1_1_4_1_0_2_0_1 + 2.025*G0_1_1_4_1_0_3_1_0 + 2.025*G0_1_1_4_1_0_3_1_1 - 2.025*G0_1_1_4_1_0_4_1_0 - 2.025*G0_1_1_4_1_0_5_1_1 + 2.025*G0_1_1_5_1_1_0_0_0 + 2.025*G0_1_1_5_1_1_0_0_1 - 2.025*G0_1_1_5_1_1_1_0_0 - 2.025*G0_1_1_5_1_1_2_0_1 + 2.025*G0_1_1_5_1_1_3_1_0 + 2.025*G0_1_1_5_1_1_3_1_1 - 2.025*G0_1_1_5_1_1_4_1_0 - 2.025*G0_1_1_5_1_1_5_1_1; + A[165] = -0.166666666666662*A[379]; + A[85] = -A[165] + 0.337500000000009*G0_0_0_0_0_0_0_0_0 + 0.337500000000009*G0_0_0_0_0_0_0_0_1 - 0.337500000000009*G0_0_0_0_0_0_1_0_0 - 0.337500000000009*G0_0_0_0_0_0_2_0_1 + 0.337500000000009*G0_0_0_0_0_0_3_1_0 + 0.337500000000009*G0_0_0_0_0_0_3_1_1 - 0.337500000000009*G0_0_0_0_0_0_4_1_0 - 0.337500000000009*G0_0_0_0_0_0_5_1_1 + 0.337500000000009*G0_0_0_0_0_1_0_0_0 + 0.337500000000009*G0_0_0_0_0_1_0_0_1 - 0.337500000000009*G0_0_0_0_0_1_1_0_0 - 0.337500000000009*G0_0_0_0_0_1_2_0_1 + 0.337500000000009*G0_0_0_0_0_1_3_1_0 + 0.337500000000009*G0_0_0_0_0_1_3_1_1 - 0.337500000000009*G0_0_0_0_0_1_4_1_0 - 0.337500000000009*G0_0_0_0_0_1_5_1_1 - 0.337500000000009*G0_0_0_1_0_0_0_0_0 - 0.337500000000009*G0_0_0_1_0_0_0_0_1 + 0.337500000000009*G0_0_0_1_0_0_1_0_0 + 0.337500000000009*G0_0_0_1_0_0_2_0_1 - 0.337500000000009*G0_0_0_1_0_0_3_1_0 - 0.337500000000009*G0_0_0_1_0_0_3_1_1 + 0.337500000000009*G0_0_0_1_0_0_4_1_0 + 0.337500000000009*G0_0_0_1_0_0_5_1_1 - 0.337500000000009*G0_0_0_2_0_1_0_0_0 - 0.337500000000009*G0_0_0_2_0_1_0_0_1 + 0.337500000000009*G0_0_0_2_0_1_1_0_0 + 0.337500000000009*G0_0_0_2_0_1_2_0_1 - 0.337500000000009*G0_0_0_2_0_1_3_1_0 - 0.337500000000009*G0_0_0_2_0_1_3_1_1 + 0.337500000000009*G0_0_0_2_0_1_4_1_0 + 0.337500000000009*G0_0_0_2_0_1_5_1_1 + 0.337500000000009*G0_0_0_3_1_0_0_0_0 + 0.337500000000009*G0_0_0_3_1_0_0_0_1 - 0.337500000000009*G0_0_0_3_1_0_1_0_0 - 0.337500000000009*G0_0_0_3_1_0_2_0_1 + 0.337500000000009*G0_0_0_3_1_0_3_1_0 + 0.337500000000009*G0_0_0_3_1_0_3_1_1 - 0.337500000000009*G0_0_0_3_1_0_4_1_0 - 0.337500000000009*G0_0_0_3_1_0_5_1_1 + 0.337500000000009*G0_0_0_3_1_1_0_0_0 + 0.337500000000009*G0_0_0_3_1_1_0_0_1 - 0.337500000000009*G0_0_0_3_1_1_1_0_0 - 0.337500000000009*G0_0_0_3_1_1_2_0_1 + 0.337500000000009*G0_0_0_3_1_1_3_1_0 + 0.337500000000009*G0_0_0_3_1_1_3_1_1 - 0.337500000000009*G0_0_0_3_1_1_4_1_0 - 0.337500000000009*G0_0_0_3_1_1_5_1_1 - 0.337500000000009*G0_0_0_4_1_0_0_0_0 - 0.337500000000009*G0_0_0_4_1_0_0_0_1 + 0.337500000000009*G0_0_0_4_1_0_1_0_0 + 0.337500000000009*G0_0_0_4_1_0_2_0_1 - 0.337500000000009*G0_0_0_4_1_0_3_1_0 - 0.337500000000009*G0_0_0_4_1_0_3_1_1 + 0.337500000000009*G0_0_0_4_1_0_4_1_0 + 0.337500000000009*G0_0_0_4_1_0_5_1_1 - 0.337500000000009*G0_0_0_5_1_1_0_0_0 - 0.337500000000009*G0_0_0_5_1_1_0_0_1 + 0.337500000000009*G0_0_0_5_1_1_1_0_0 + 0.337500000000009*G0_0_0_5_1_1_2_0_1 - 0.337500000000009*G0_0_0_5_1_1_3_1_0 - 0.337500000000009*G0_0_0_5_1_1_3_1_1 + 0.337500000000009*G0_0_0_5_1_1_4_1_0 + 0.337500000000009*G0_0_0_5_1_1_5_1_1; + A[393] = -5.99999999999986*A[85]; + A[370] = A[85] + 0.168749999999992*G0_0_1_0_0_0_0_0_0 + 0.168749999999992*G0_0_1_0_0_0_0_0_1 - 0.168749999999992*G0_0_1_0_0_0_1_0_0 - 0.168749999999992*G0_0_1_0_0_0_2_0_1 + 0.168749999999992*G0_0_1_0_0_0_3_1_0 + 0.168749999999992*G0_0_1_0_0_0_3_1_1 - 0.168749999999992*G0_0_1_0_0_0_4_1_0 - 0.168749999999992*G0_0_1_0_0_0_5_1_1 + 0.168749999999992*G0_0_1_0_0_1_0_0_0 + 0.168749999999992*G0_0_1_0_0_1_0_0_1 - 0.168749999999992*G0_0_1_0_0_1_1_0_0 - 0.168749999999992*G0_0_1_0_0_1_2_0_1 + 0.168749999999992*G0_0_1_0_0_1_3_1_0 + 0.168749999999992*G0_0_1_0_0_1_3_1_1 - 0.168749999999992*G0_0_1_0_0_1_4_1_0 - 0.168749999999992*G0_0_1_0_0_1_5_1_1 - 0.168749999999992*G0_0_1_1_0_0_0_0_0 - 0.168749999999992*G0_0_1_1_0_0_0_0_1 + 0.168749999999992*G0_0_1_1_0_0_1_0_0 + 0.168749999999992*G0_0_1_1_0_0_2_0_1 - 0.168749999999992*G0_0_1_1_0_0_3_1_0 - 0.168749999999992*G0_0_1_1_0_0_3_1_1 + 0.168749999999992*G0_0_1_1_0_0_4_1_0 + 0.168749999999992*G0_0_1_1_0_0_5_1_1 - 0.168749999999992*G0_0_1_2_0_1_0_0_0 - 0.168749999999992*G0_0_1_2_0_1_0_0_1 + 0.168749999999992*G0_0_1_2_0_1_1_0_0 + 0.168749999999992*G0_0_1_2_0_1_2_0_1 - 0.168749999999992*G0_0_1_2_0_1_3_1_0 - 0.168749999999992*G0_0_1_2_0_1_3_1_1 + 0.168749999999992*G0_0_1_2_0_1_4_1_0 + 0.168749999999992*G0_0_1_2_0_1_5_1_1 + 0.168749999999992*G0_0_1_3_1_0_0_0_0 + 0.168749999999992*G0_0_1_3_1_0_0_0_1 - 0.168749999999992*G0_0_1_3_1_0_1_0_0 - 0.168749999999992*G0_0_1_3_1_0_2_0_1 + 0.168749999999992*G0_0_1_3_1_0_3_1_0 + 0.168749999999992*G0_0_1_3_1_0_3_1_1 - 0.168749999999992*G0_0_1_3_1_0_4_1_0 - 0.168749999999992*G0_0_1_3_1_0_5_1_1 + 0.168749999999992*G0_0_1_3_1_1_0_0_0 + 0.168749999999992*G0_0_1_3_1_1_0_0_1 - 0.168749999999992*G0_0_1_3_1_1_1_0_0 - 0.168749999999992*G0_0_1_3_1_1_2_0_1 + 0.168749999999992*G0_0_1_3_1_1_3_1_0 + 0.168749999999992*G0_0_1_3_1_1_3_1_1 - 0.168749999999992*G0_0_1_3_1_1_4_1_0 - 0.168749999999992*G0_0_1_3_1_1_5_1_1 - 0.168749999999992*G0_0_1_4_1_0_0_0_0 - 0.168749999999992*G0_0_1_4_1_0_0_0_1 + 0.168749999999992*G0_0_1_4_1_0_1_0_0 + 0.168749999999992*G0_0_1_4_1_0_2_0_1 - 0.168749999999992*G0_0_1_4_1_0_3_1_0 - 0.168749999999992*G0_0_1_4_1_0_3_1_1 + 0.168749999999992*G0_0_1_4_1_0_4_1_0 + 0.168749999999992*G0_0_1_4_1_0_5_1_1 - 0.168749999999992*G0_0_1_5_1_1_0_0_0 - 0.168749999999992*G0_0_1_5_1_1_0_0_1 + 0.168749999999992*G0_0_1_5_1_1_1_0_0 + 0.168749999999992*G0_0_1_5_1_1_2_0_1 - 0.168749999999992*G0_0_1_5_1_1_3_1_0 - 0.168749999999992*G0_0_1_5_1_1_3_1_1 + 0.168749999999992*G0_0_1_5_1_1_4_1_0 + 0.168749999999992*G0_0_1_5_1_1_5_1_1 - 0.131250000000003*G0_1_0_0_0_0_0_0_0 - 0.131250000000003*G0_1_0_0_0_0_0_0_1 + 0.131250000000003*G0_1_0_0_0_0_1_0_0 + 0.131250000000003*G0_1_0_0_0_0_2_0_1 - 0.131250000000003*G0_1_0_0_0_0_3_1_0 - 0.131250000000003*G0_1_0_0_0_0_3_1_1 + 0.131250000000003*G0_1_0_0_0_0_4_1_0 + 0.131250000000003*G0_1_0_0_0_0_5_1_1 - 0.131250000000003*G0_1_0_0_0_1_0_0_0 - 0.131250000000003*G0_1_0_0_0_1_0_0_1 + 0.131250000000003*G0_1_0_0_0_1_1_0_0 + 0.131250000000003*G0_1_0_0_0_1_2_0_1 - 0.131250000000003*G0_1_0_0_0_1_3_1_0 - 0.131250000000003*G0_1_0_0_0_1_3_1_1 + 0.131250000000003*G0_1_0_0_0_1_4_1_0 + 0.131250000000003*G0_1_0_0_0_1_5_1_1 + 0.131250000000003*G0_1_0_1_0_0_0_0_0 + 0.131250000000003*G0_1_0_1_0_0_0_0_1 - 0.131250000000003*G0_1_0_1_0_0_1_0_0 - 0.131250000000003*G0_1_0_1_0_0_2_0_1 + 0.131250000000003*G0_1_0_1_0_0_3_1_0 + 0.131250000000003*G0_1_0_1_0_0_3_1_1 - 0.131250000000003*G0_1_0_1_0_0_4_1_0 - 0.131250000000003*G0_1_0_1_0_0_5_1_1 + 0.131250000000003*G0_1_0_2_0_1_0_0_0 + 0.131250000000003*G0_1_0_2_0_1_0_0_1 - 0.131250000000003*G0_1_0_2_0_1_1_0_0 - 0.131250000000003*G0_1_0_2_0_1_2_0_1 + 0.131250000000003*G0_1_0_2_0_1_3_1_0 + 0.131250000000003*G0_1_0_2_0_1_3_1_1 - 0.131250000000003*G0_1_0_2_0_1_4_1_0 - 0.131250000000003*G0_1_0_2_0_1_5_1_1 - 0.131250000000003*G0_1_0_3_1_0_0_0_0 - 0.131250000000003*G0_1_0_3_1_0_0_0_1 + 0.131250000000003*G0_1_0_3_1_0_1_0_0 + 0.131250000000003*G0_1_0_3_1_0_2_0_1 - 0.131250000000003*G0_1_0_3_1_0_3_1_0 - 0.131250000000003*G0_1_0_3_1_0_3_1_1 + 0.131250000000003*G0_1_0_3_1_0_4_1_0 + 0.131250000000003*G0_1_0_3_1_0_5_1_1 - 0.131250000000003*G0_1_0_3_1_1_0_0_0 - 0.131250000000003*G0_1_0_3_1_1_0_0_1 + 0.131250000000003*G0_1_0_3_1_1_1_0_0 + 0.131250000000003*G0_1_0_3_1_1_2_0_1 - 0.131250000000003*G0_1_0_3_1_1_3_1_0 - 0.131250000000003*G0_1_0_3_1_1_3_1_1 + 0.131250000000003*G0_1_0_3_1_1_4_1_0 + 0.131250000000003*G0_1_0_3_1_1_5_1_1 + 0.131250000000003*G0_1_0_4_1_0_0_0_0 + 0.131250000000003*G0_1_0_4_1_0_0_0_1 - 0.131250000000003*G0_1_0_4_1_0_1_0_0 - 0.131250000000003*G0_1_0_4_1_0_2_0_1 + 0.131250000000003*G0_1_0_4_1_0_3_1_0 + 0.131250000000003*G0_1_0_4_1_0_3_1_1 - 0.131250000000003*G0_1_0_4_1_0_4_1_0 - 0.131250000000003*G0_1_0_4_1_0_5_1_1 + 0.131250000000003*G0_1_0_5_1_1_0_0_0 + 0.131250000000003*G0_1_0_5_1_1_0_0_1 - 0.131250000000003*G0_1_0_5_1_1_1_0_0 - 0.131250000000003*G0_1_0_5_1_1_2_0_1 + 0.131250000000003*G0_1_0_5_1_1_3_1_0 + 0.131250000000003*G0_1_0_5_1_1_3_1_1 - 0.131250000000003*G0_1_0_5_1_1_4_1_0 - 0.131250000000003*G0_1_0_5_1_1_5_1_1 + 0.0374999999999979*G0_1_1_0_0_0_0_0_0 + 0.0374999999999979*G0_1_1_0_0_0_0_0_1 - 0.0374999999999979*G0_1_1_0_0_0_1_0_0 - 0.0374999999999979*G0_1_1_0_0_0_2_0_1 + 0.0374999999999979*G0_1_1_0_0_0_3_1_0 + 0.0374999999999979*G0_1_1_0_0_0_3_1_1 - 0.0374999999999979*G0_1_1_0_0_0_4_1_0 - 0.0374999999999979*G0_1_1_0_0_0_5_1_1 + 0.0374999999999979*G0_1_1_0_0_1_0_0_0 + 0.0374999999999979*G0_1_1_0_0_1_0_0_1 - 0.0374999999999979*G0_1_1_0_0_1_1_0_0 - 0.0374999999999979*G0_1_1_0_0_1_2_0_1 + 0.0374999999999979*G0_1_1_0_0_1_3_1_0 + 0.0374999999999979*G0_1_1_0_0_1_3_1_1 - 0.0374999999999979*G0_1_1_0_0_1_4_1_0 - 0.0374999999999979*G0_1_1_0_0_1_5_1_1 - 0.0374999999999979*G0_1_1_1_0_0_0_0_0 - 0.0374999999999979*G0_1_1_1_0_0_0_0_1 + 0.0374999999999979*G0_1_1_1_0_0_1_0_0 + 0.0374999999999979*G0_1_1_1_0_0_2_0_1 - 0.0374999999999979*G0_1_1_1_0_0_3_1_0 - 0.0374999999999979*G0_1_1_1_0_0_3_1_1 + 0.0374999999999979*G0_1_1_1_0_0_4_1_0 + 0.0374999999999979*G0_1_1_1_0_0_5_1_1 - 0.0374999999999979*G0_1_1_2_0_1_0_0_0 - 0.0374999999999979*G0_1_1_2_0_1_0_0_1 + 0.0374999999999979*G0_1_1_2_0_1_1_0_0 + 0.0374999999999979*G0_1_1_2_0_1_2_0_1 - 0.0374999999999979*G0_1_1_2_0_1_3_1_0 - 0.0374999999999979*G0_1_1_2_0_1_3_1_1 + 0.0374999999999979*G0_1_1_2_0_1_4_1_0 + 0.0374999999999979*G0_1_1_2_0_1_5_1_1 + 0.0374999999999979*G0_1_1_3_1_0_0_0_0 + 0.0374999999999979*G0_1_1_3_1_0_0_0_1 - 0.0374999999999979*G0_1_1_3_1_0_1_0_0 - 0.0374999999999979*G0_1_1_3_1_0_2_0_1 + 0.0374999999999979*G0_1_1_3_1_0_3_1_0 + 0.0374999999999979*G0_1_1_3_1_0_3_1_1 - 0.0374999999999979*G0_1_1_3_1_0_4_1_0 - 0.0374999999999979*G0_1_1_3_1_0_5_1_1 + 0.0374999999999979*G0_1_1_3_1_1_0_0_0 + 0.0374999999999979*G0_1_1_3_1_1_0_0_1 - 0.0374999999999979*G0_1_1_3_1_1_1_0_0 - 0.0374999999999979*G0_1_1_3_1_1_2_0_1 + 0.0374999999999979*G0_1_1_3_1_1_3_1_0 + 0.0374999999999979*G0_1_1_3_1_1_3_1_1 - 0.0374999999999979*G0_1_1_3_1_1_4_1_0 - 0.0374999999999979*G0_1_1_3_1_1_5_1_1 - 0.0374999999999979*G0_1_1_4_1_0_0_0_0 - 0.0374999999999979*G0_1_1_4_1_0_0_0_1 + 0.0374999999999979*G0_1_1_4_1_0_1_0_0 + 0.0374999999999979*G0_1_1_4_1_0_2_0_1 - 0.0374999999999979*G0_1_1_4_1_0_3_1_0 - 0.0374999999999979*G0_1_1_4_1_0_3_1_1 + 0.0374999999999979*G0_1_1_4_1_0_4_1_0 + 0.0374999999999979*G0_1_1_4_1_0_5_1_1 - 0.0374999999999979*G0_1_1_5_1_1_0_0_0 - 0.0374999999999979*G0_1_1_5_1_1_0_0_1 + 0.0374999999999979*G0_1_1_5_1_1_1_0_0 + 0.0374999999999979*G0_1_1_5_1_1_2_0_1 - 0.0374999999999979*G0_1_1_5_1_1_3_1_0 - 0.0374999999999979*G0_1_1_5_1_1_3_1_1 + 0.0374999999999979*G0_1_1_5_1_1_4_1_0 + 0.0374999999999979*G0_1_1_5_1_1_5_1_1; + A[214] = -A[370] + 0.299999999999998*G0_0_0_0_0_0_0_0_0 + 0.299999999999998*G0_0_0_0_0_0_0_0_1 - 0.299999999999998*G0_0_0_0_0_0_1_0_0 - 0.299999999999998*G0_0_0_0_0_0_2_0_1 + 0.299999999999998*G0_0_0_0_0_0_3_1_0 + 0.299999999999998*G0_0_0_0_0_0_3_1_1 - 0.299999999999998*G0_0_0_0_0_0_4_1_0 - 0.299999999999998*G0_0_0_0_0_0_5_1_1 + 0.299999999999998*G0_0_0_0_0_1_0_0_0 + 0.299999999999998*G0_0_0_0_0_1_0_0_1 - 0.299999999999998*G0_0_0_0_0_1_1_0_0 - 0.299999999999998*G0_0_0_0_0_1_2_0_1 + 0.299999999999998*G0_0_0_0_0_1_3_1_0 + 0.299999999999998*G0_0_0_0_0_1_3_1_1 - 0.299999999999998*G0_0_0_0_0_1_4_1_0 - 0.299999999999998*G0_0_0_0_0_1_5_1_1 - 0.299999999999998*G0_0_0_1_0_0_0_0_0 - 0.299999999999998*G0_0_0_1_0_0_0_0_1 + 0.299999999999998*G0_0_0_1_0_0_1_0_0 + 0.299999999999998*G0_0_0_1_0_0_2_0_1 - 0.299999999999998*G0_0_0_1_0_0_3_1_0 - 0.299999999999998*G0_0_0_1_0_0_3_1_1 + 0.299999999999998*G0_0_0_1_0_0_4_1_0 + 0.299999999999998*G0_0_0_1_0_0_5_1_1 - 0.299999999999998*G0_0_0_2_0_1_0_0_0 - 0.299999999999998*G0_0_0_2_0_1_0_0_1 + 0.299999999999998*G0_0_0_2_0_1_1_0_0 + 0.299999999999998*G0_0_0_2_0_1_2_0_1 - 0.299999999999998*G0_0_0_2_0_1_3_1_0 - 0.299999999999998*G0_0_0_2_0_1_3_1_1 + 0.299999999999998*G0_0_0_2_0_1_4_1_0 + 0.299999999999998*G0_0_0_2_0_1_5_1_1 + 0.299999999999998*G0_0_0_3_1_0_0_0_0 + 0.299999999999998*G0_0_0_3_1_0_0_0_1 - 0.299999999999998*G0_0_0_3_1_0_1_0_0 - 0.299999999999998*G0_0_0_3_1_0_2_0_1 + 0.299999999999998*G0_0_0_3_1_0_3_1_0 + 0.299999999999998*G0_0_0_3_1_0_3_1_1 - 0.299999999999998*G0_0_0_3_1_0_4_1_0 - 0.299999999999998*G0_0_0_3_1_0_5_1_1 + 0.299999999999998*G0_0_0_3_1_1_0_0_0 + 0.299999999999998*G0_0_0_3_1_1_0_0_1 - 0.299999999999998*G0_0_0_3_1_1_1_0_0 - 0.299999999999998*G0_0_0_3_1_1_2_0_1 + 0.299999999999998*G0_0_0_3_1_1_3_1_0 + 0.299999999999998*G0_0_0_3_1_1_3_1_1 - 0.299999999999998*G0_0_0_3_1_1_4_1_0 - 0.299999999999998*G0_0_0_3_1_1_5_1_1 - 0.299999999999998*G0_0_0_4_1_0_0_0_0 - 0.299999999999998*G0_0_0_4_1_0_0_0_1 + 0.299999999999998*G0_0_0_4_1_0_1_0_0 + 0.299999999999998*G0_0_0_4_1_0_2_0_1 - 0.299999999999998*G0_0_0_4_1_0_3_1_0 - 0.299999999999998*G0_0_0_4_1_0_3_1_1 + 0.299999999999998*G0_0_0_4_1_0_4_1_0 + 0.299999999999998*G0_0_0_4_1_0_5_1_1 - 0.299999999999998*G0_0_0_5_1_1_0_0_0 - 0.299999999999998*G0_0_0_5_1_1_0_0_1 + 0.299999999999998*G0_0_0_5_1_1_1_0_0 + 0.299999999999998*G0_0_0_5_1_1_2_0_1 - 0.299999999999998*G0_0_0_5_1_1_3_1_0 - 0.299999999999998*G0_0_0_5_1_1_3_1_1 + 0.299999999999998*G0_0_0_5_1_1_4_1_0 + 0.299999999999998*G0_0_0_5_1_1_5_1_1 + 0.299999999999999*G0_0_1_0_0_0_0_0_0 + 0.299999999999999*G0_0_1_0_0_0_0_0_1 - 0.299999999999999*G0_0_1_0_0_0_1_0_0 - 0.299999999999999*G0_0_1_0_0_0_2_0_1 + 0.299999999999999*G0_0_1_0_0_0_3_1_0 + 0.299999999999999*G0_0_1_0_0_0_3_1_1 - 0.299999999999999*G0_0_1_0_0_0_4_1_0 - 0.299999999999999*G0_0_1_0_0_0_5_1_1 + 0.299999999999999*G0_0_1_0_0_1_0_0_0 + 0.299999999999999*G0_0_1_0_0_1_0_0_1 - 0.299999999999999*G0_0_1_0_0_1_1_0_0 - 0.299999999999999*G0_0_1_0_0_1_2_0_1 + 0.299999999999999*G0_0_1_0_0_1_3_1_0 + 0.299999999999999*G0_0_1_0_0_1_3_1_1 - 0.299999999999999*G0_0_1_0_0_1_4_1_0 - 0.299999999999999*G0_0_1_0_0_1_5_1_1 - 0.299999999999999*G0_0_1_1_0_0_0_0_0 - 0.299999999999999*G0_0_1_1_0_0_0_0_1 + 0.299999999999999*G0_0_1_1_0_0_1_0_0 + 0.299999999999999*G0_0_1_1_0_0_2_0_1 - 0.299999999999999*G0_0_1_1_0_0_3_1_0 - 0.299999999999999*G0_0_1_1_0_0_3_1_1 + 0.299999999999999*G0_0_1_1_0_0_4_1_0 + 0.299999999999999*G0_0_1_1_0_0_5_1_1 - 0.299999999999999*G0_0_1_2_0_1_0_0_0 - 0.299999999999999*G0_0_1_2_0_1_0_0_1 + 0.299999999999999*G0_0_1_2_0_1_1_0_0 + 0.299999999999999*G0_0_1_2_0_1_2_0_1 - 0.299999999999999*G0_0_1_2_0_1_3_1_0 - 0.299999999999999*G0_0_1_2_0_1_3_1_1 + 0.299999999999999*G0_0_1_2_0_1_4_1_0 + 0.299999999999999*G0_0_1_2_0_1_5_1_1 + 0.299999999999999*G0_0_1_3_1_0_0_0_0 + 0.299999999999999*G0_0_1_3_1_0_0_0_1 - 0.299999999999999*G0_0_1_3_1_0_1_0_0 - 0.299999999999999*G0_0_1_3_1_0_2_0_1 + 0.299999999999999*G0_0_1_3_1_0_3_1_0 + 0.299999999999999*G0_0_1_3_1_0_3_1_1 - 0.299999999999999*G0_0_1_3_1_0_4_1_0 - 0.299999999999999*G0_0_1_3_1_0_5_1_1 + 0.299999999999999*G0_0_1_3_1_1_0_0_0 + 0.299999999999999*G0_0_1_3_1_1_0_0_1 - 0.299999999999999*G0_0_1_3_1_1_1_0_0 - 0.299999999999999*G0_0_1_3_1_1_2_0_1 + 0.299999999999999*G0_0_1_3_1_1_3_1_0 + 0.299999999999999*G0_0_1_3_1_1_3_1_1 - 0.299999999999999*G0_0_1_3_1_1_4_1_0 - 0.299999999999999*G0_0_1_3_1_1_5_1_1 - 0.299999999999999*G0_0_1_4_1_0_0_0_0 - 0.299999999999999*G0_0_1_4_1_0_0_0_1 + 0.299999999999999*G0_0_1_4_1_0_1_0_0 + 0.299999999999999*G0_0_1_4_1_0_2_0_1 - 0.299999999999999*G0_0_1_4_1_0_3_1_0 - 0.299999999999999*G0_0_1_4_1_0_3_1_1 + 0.299999999999999*G0_0_1_4_1_0_4_1_0 + 0.299999999999999*G0_0_1_4_1_0_5_1_1 - 0.299999999999999*G0_0_1_5_1_1_0_0_0 - 0.299999999999999*G0_0_1_5_1_1_0_0_1 + 0.299999999999999*G0_0_1_5_1_1_1_0_0 + 0.299999999999999*G0_0_1_5_1_1_2_0_1 - 0.299999999999999*G0_0_1_5_1_1_3_1_0 - 0.299999999999999*G0_0_1_5_1_1_3_1_1 + 0.299999999999999*G0_0_1_5_1_1_4_1_0 + 0.299999999999999*G0_0_1_5_1_1_5_1_1; + A[313] = A[85]; + A[398] = A[379]; + A[247] = 0.0; + A[219] = 0.0; + A[310] = -A[214] - 0.7125*G0_1_0_0_0_0_0_0_0 - 0.7125*G0_1_0_0_0_0_0_0_1 + 0.7125*G0_1_0_0_0_0_1_0_0 + 0.7125*G0_1_0_0_0_0_2_0_1 - 0.7125*G0_1_0_0_0_0_3_1_0 - 0.7125*G0_1_0_0_0_0_3_1_1 + 0.7125*G0_1_0_0_0_0_4_1_0 + 0.7125*G0_1_0_0_0_0_5_1_1 - 0.7125*G0_1_0_0_0_1_0_0_0 - 0.7125*G0_1_0_0_0_1_0_0_1 + 0.7125*G0_1_0_0_0_1_1_0_0 + 0.7125*G0_1_0_0_0_1_2_0_1 - 0.7125*G0_1_0_0_0_1_3_1_0 - 0.7125*G0_1_0_0_0_1_3_1_1 + 0.7125*G0_1_0_0_0_1_4_1_0 + 0.7125*G0_1_0_0_0_1_5_1_1 + 0.7125*G0_1_0_1_0_0_0_0_0 + 0.7125*G0_1_0_1_0_0_0_0_1 - 0.7125*G0_1_0_1_0_0_1_0_0 - 0.7125*G0_1_0_1_0_0_2_0_1 + 0.7125*G0_1_0_1_0_0_3_1_0 + 0.7125*G0_1_0_1_0_0_3_1_1 - 0.7125*G0_1_0_1_0_0_4_1_0 - 0.7125*G0_1_0_1_0_0_5_1_1 + 0.7125*G0_1_0_2_0_1_0_0_0 + 0.7125*G0_1_0_2_0_1_0_0_1 - 0.7125*G0_1_0_2_0_1_1_0_0 - 0.7125*G0_1_0_2_0_1_2_0_1 + 0.7125*G0_1_0_2_0_1_3_1_0 + 0.7125*G0_1_0_2_0_1_3_1_1 - 0.7125*G0_1_0_2_0_1_4_1_0 - 0.7125*G0_1_0_2_0_1_5_1_1 - 0.7125*G0_1_0_3_1_0_0_0_0 - 0.7125*G0_1_0_3_1_0_0_0_1 + 0.7125*G0_1_0_3_1_0_1_0_0 + 0.7125*G0_1_0_3_1_0_2_0_1 - 0.7125*G0_1_0_3_1_0_3_1_0 - 0.7125*G0_1_0_3_1_0_3_1_1 + 0.7125*G0_1_0_3_1_0_4_1_0 + 0.7125*G0_1_0_3_1_0_5_1_1 - 0.7125*G0_1_0_3_1_1_0_0_0 - 0.7125*G0_1_0_3_1_1_0_0_1 + 0.7125*G0_1_0_3_1_1_1_0_0 + 0.7125*G0_1_0_3_1_1_2_0_1 - 0.7125*G0_1_0_3_1_1_3_1_0 - 0.7125*G0_1_0_3_1_1_3_1_1 + 0.7125*G0_1_0_3_1_1_4_1_0 + 0.7125*G0_1_0_3_1_1_5_1_1 + 0.7125*G0_1_0_4_1_0_0_0_0 + 0.7125*G0_1_0_4_1_0_0_0_1 - 0.7125*G0_1_0_4_1_0_1_0_0 - 0.7125*G0_1_0_4_1_0_2_0_1 + 0.7125*G0_1_0_4_1_0_3_1_0 + 0.7125*G0_1_0_4_1_0_3_1_1 - 0.7125*G0_1_0_4_1_0_4_1_0 - 0.7125*G0_1_0_4_1_0_5_1_1 + 0.7125*G0_1_0_5_1_1_0_0_0 + 0.7125*G0_1_0_5_1_1_0_0_1 - 0.7125*G0_1_0_5_1_1_1_0_0 - 0.7125*G0_1_0_5_1_1_2_0_1 + 0.7125*G0_1_0_5_1_1_3_1_0 + 0.7125*G0_1_0_5_1_1_3_1_1 - 0.7125*G0_1_0_5_1_1_4_1_0 - 0.7125*G0_1_0_5_1_1_5_1_1 - 0.712499999999999*G0_1_1_0_0_0_0_0_0 - 0.712499999999999*G0_1_1_0_0_0_0_0_1 + 0.712499999999999*G0_1_1_0_0_0_1_0_0 + 0.712499999999999*G0_1_1_0_0_0_2_0_1 - 0.712499999999999*G0_1_1_0_0_0_3_1_0 - 0.712499999999999*G0_1_1_0_0_0_3_1_1 + 0.712499999999999*G0_1_1_0_0_0_4_1_0 + 0.712499999999999*G0_1_1_0_0_0_5_1_1 - 0.712499999999999*G0_1_1_0_0_1_0_0_0 - 0.712499999999999*G0_1_1_0_0_1_0_0_1 + 0.712499999999999*G0_1_1_0_0_1_1_0_0 + 0.712499999999999*G0_1_1_0_0_1_2_0_1 - 0.712499999999999*G0_1_1_0_0_1_3_1_0 - 0.712499999999999*G0_1_1_0_0_1_3_1_1 + 0.712499999999999*G0_1_1_0_0_1_4_1_0 + 0.712499999999999*G0_1_1_0_0_1_5_1_1 + 0.712499999999999*G0_1_1_1_0_0_0_0_0 + 0.712499999999999*G0_1_1_1_0_0_0_0_1 - 0.712499999999999*G0_1_1_1_0_0_1_0_0 - 0.712499999999999*G0_1_1_1_0_0_2_0_1 + 0.712499999999999*G0_1_1_1_0_0_3_1_0 + 0.712499999999999*G0_1_1_1_0_0_3_1_1 - 0.712499999999999*G0_1_1_1_0_0_4_1_0 - 0.712499999999999*G0_1_1_1_0_0_5_1_1 + 0.712499999999999*G0_1_1_2_0_1_0_0_0 + 0.712499999999999*G0_1_1_2_0_1_0_0_1 - 0.712499999999999*G0_1_1_2_0_1_1_0_0 - 0.712499999999999*G0_1_1_2_0_1_2_0_1 + 0.712499999999999*G0_1_1_2_0_1_3_1_0 + 0.712499999999999*G0_1_1_2_0_1_3_1_1 - 0.712499999999999*G0_1_1_2_0_1_4_1_0 - 0.712499999999999*G0_1_1_2_0_1_5_1_1 - 0.712499999999999*G0_1_1_3_1_0_0_0_0 - 0.712499999999999*G0_1_1_3_1_0_0_0_1 + 0.712499999999999*G0_1_1_3_1_0_1_0_0 + 0.712499999999999*G0_1_1_3_1_0_2_0_1 - 0.712499999999999*G0_1_1_3_1_0_3_1_0 - 0.712499999999999*G0_1_1_3_1_0_3_1_1 + 0.712499999999999*G0_1_1_3_1_0_4_1_0 + 0.712499999999999*G0_1_1_3_1_0_5_1_1 - 0.712499999999999*G0_1_1_3_1_1_0_0_0 - 0.712499999999999*G0_1_1_3_1_1_0_0_1 + 0.712499999999999*G0_1_1_3_1_1_1_0_0 + 0.712499999999999*G0_1_1_3_1_1_2_0_1 - 0.712499999999999*G0_1_1_3_1_1_3_1_0 - 0.712499999999999*G0_1_1_3_1_1_3_1_1 + 0.712499999999999*G0_1_1_3_1_1_4_1_0 + 0.712499999999999*G0_1_1_3_1_1_5_1_1 + 0.712499999999999*G0_1_1_4_1_0_0_0_0 + 0.712499999999999*G0_1_1_4_1_0_0_0_1 - 0.712499999999999*G0_1_1_4_1_0_1_0_0 - 0.712499999999999*G0_1_1_4_1_0_2_0_1 + 0.712499999999999*G0_1_1_4_1_0_3_1_0 + 0.712499999999999*G0_1_1_4_1_0_3_1_1 - 0.712499999999999*G0_1_1_4_1_0_4_1_0 - 0.712499999999999*G0_1_1_4_1_0_5_1_1 + 0.712499999999999*G0_1_1_5_1_1_0_0_0 + 0.712499999999999*G0_1_1_5_1_1_0_0_1 - 0.712499999999999*G0_1_1_5_1_1_1_0_0 - 0.712499999999999*G0_1_1_5_1_1_2_0_1 + 0.712499999999999*G0_1_1_5_1_1_3_1_0 + 0.712499999999999*G0_1_1_5_1_1_3_1_1 - 0.712499999999999*G0_1_1_5_1_1_4_1_0 - 0.712499999999999*G0_1_1_5_1_1_5_1_1; + A[266] = 0.0; + A[5] = -A[214] - 0.712499999999999*G0_0_1_0_0_0_0_0_0 - 0.712499999999999*G0_0_1_0_0_0_0_0_1 + 0.712499999999999*G0_0_1_0_0_0_1_0_0 + 0.712499999999999*G0_0_1_0_0_0_2_0_1 - 0.712499999999999*G0_0_1_0_0_0_3_1_0 - 0.712499999999999*G0_0_1_0_0_0_3_1_1 + 0.712499999999999*G0_0_1_0_0_0_4_1_0 + 0.712499999999999*G0_0_1_0_0_0_5_1_1 - 0.712499999999999*G0_0_1_0_0_1_0_0_0 - 0.712499999999999*G0_0_1_0_0_1_0_0_1 + 0.712499999999999*G0_0_1_0_0_1_1_0_0 + 0.712499999999999*G0_0_1_0_0_1_2_0_1 - 0.712499999999999*G0_0_1_0_0_1_3_1_0 - 0.712499999999999*G0_0_1_0_0_1_3_1_1 + 0.712499999999999*G0_0_1_0_0_1_4_1_0 + 0.712499999999999*G0_0_1_0_0_1_5_1_1 + 0.712499999999999*G0_0_1_1_0_0_0_0_0 + 0.712499999999999*G0_0_1_1_0_0_0_0_1 - 0.712499999999999*G0_0_1_1_0_0_1_0_0 - 0.712499999999999*G0_0_1_1_0_0_2_0_1 + 0.712499999999999*G0_0_1_1_0_0_3_1_0 + 0.712499999999999*G0_0_1_1_0_0_3_1_1 - 0.712499999999999*G0_0_1_1_0_0_4_1_0 - 0.712499999999999*G0_0_1_1_0_0_5_1_1 + 0.712499999999999*G0_0_1_2_0_1_0_0_0 + 0.712499999999999*G0_0_1_2_0_1_0_0_1 - 0.712499999999999*G0_0_1_2_0_1_1_0_0 - 0.712499999999999*G0_0_1_2_0_1_2_0_1 + 0.712499999999999*G0_0_1_2_0_1_3_1_0 + 0.712499999999999*G0_0_1_2_0_1_3_1_1 - 0.712499999999999*G0_0_1_2_0_1_4_1_0 - 0.712499999999999*G0_0_1_2_0_1_5_1_1 - 0.712499999999999*G0_0_1_3_1_0_0_0_0 - 0.712499999999999*G0_0_1_3_1_0_0_0_1 + 0.712499999999999*G0_0_1_3_1_0_1_0_0 + 0.712499999999999*G0_0_1_3_1_0_2_0_1 - 0.712499999999999*G0_0_1_3_1_0_3_1_0 - 0.712499999999999*G0_0_1_3_1_0_3_1_1 + 0.712499999999999*G0_0_1_3_1_0_4_1_0 + 0.712499999999999*G0_0_1_3_1_0_5_1_1 - 0.712499999999999*G0_0_1_3_1_1_0_0_0 - 0.712499999999999*G0_0_1_3_1_1_0_0_1 + 0.712499999999999*G0_0_1_3_1_1_1_0_0 + 0.712499999999999*G0_0_1_3_1_1_2_0_1 - 0.712499999999999*G0_0_1_3_1_1_3_1_0 - 0.712499999999999*G0_0_1_3_1_1_3_1_1 + 0.712499999999999*G0_0_1_3_1_1_4_1_0 + 0.712499999999999*G0_0_1_3_1_1_5_1_1 + 0.712499999999999*G0_0_1_4_1_0_0_0_0 + 0.712499999999999*G0_0_1_4_1_0_0_0_1 - 0.712499999999999*G0_0_1_4_1_0_1_0_0 - 0.712499999999999*G0_0_1_4_1_0_2_0_1 + 0.712499999999999*G0_0_1_4_1_0_3_1_0 + 0.712499999999999*G0_0_1_4_1_0_3_1_1 - 0.712499999999999*G0_0_1_4_1_0_4_1_0 - 0.712499999999999*G0_0_1_4_1_0_5_1_1 + 0.712499999999999*G0_0_1_5_1_1_0_0_0 + 0.712499999999999*G0_0_1_5_1_1_0_0_1 - 0.712499999999999*G0_0_1_5_1_1_1_0_0 - 0.712499999999999*G0_0_1_5_1_1_2_0_1 + 0.712499999999999*G0_0_1_5_1_1_3_1_0 + 0.712499999999999*G0_0_1_5_1_1_3_1_1 - 0.712499999999999*G0_0_1_5_1_1_4_1_0 - 0.712499999999999*G0_0_1_5_1_1_5_1_1 - 0.712499999999999*G0_1_1_0_0_0_0_0_0 - 0.712499999999999*G0_1_1_0_0_0_0_0_1 + 0.712499999999999*G0_1_1_0_0_0_1_0_0 + 0.712499999999999*G0_1_1_0_0_0_2_0_1 - 0.712499999999999*G0_1_1_0_0_0_3_1_0 - 0.712499999999999*G0_1_1_0_0_0_3_1_1 + 0.712499999999999*G0_1_1_0_0_0_4_1_0 + 0.712499999999999*G0_1_1_0_0_0_5_1_1 - 0.712499999999999*G0_1_1_0_0_1_0_0_0 - 0.712499999999999*G0_1_1_0_0_1_0_0_1 + 0.712499999999999*G0_1_1_0_0_1_1_0_0 + 0.712499999999999*G0_1_1_0_0_1_2_0_1 - 0.712499999999999*G0_1_1_0_0_1_3_1_0 - 0.712499999999999*G0_1_1_0_0_1_3_1_1 + 0.712499999999999*G0_1_1_0_0_1_4_1_0 + 0.712499999999999*G0_1_1_0_0_1_5_1_1 + 0.712499999999999*G0_1_1_1_0_0_0_0_0 + 0.712499999999999*G0_1_1_1_0_0_0_0_1 - 0.712499999999999*G0_1_1_1_0_0_1_0_0 - 0.712499999999999*G0_1_1_1_0_0_2_0_1 + 0.712499999999999*G0_1_1_1_0_0_3_1_0 + 0.712499999999999*G0_1_1_1_0_0_3_1_1 - 0.712499999999999*G0_1_1_1_0_0_4_1_0 - 0.712499999999999*G0_1_1_1_0_0_5_1_1 + 0.712499999999999*G0_1_1_2_0_1_0_0_0 + 0.712499999999999*G0_1_1_2_0_1_0_0_1 - 0.712499999999999*G0_1_1_2_0_1_1_0_0 - 0.712499999999999*G0_1_1_2_0_1_2_0_1 + 0.712499999999999*G0_1_1_2_0_1_3_1_0 + 0.712499999999999*G0_1_1_2_0_1_3_1_1 - 0.712499999999999*G0_1_1_2_0_1_4_1_0 - 0.712499999999999*G0_1_1_2_0_1_5_1_1 - 0.712499999999999*G0_1_1_3_1_0_0_0_0 - 0.712499999999999*G0_1_1_3_1_0_0_0_1 + 0.712499999999999*G0_1_1_3_1_0_1_0_0 + 0.712499999999999*G0_1_1_3_1_0_2_0_1 - 0.712499999999999*G0_1_1_3_1_0_3_1_0 - 0.712499999999999*G0_1_1_3_1_0_3_1_1 + 0.712499999999999*G0_1_1_3_1_0_4_1_0 + 0.712499999999999*G0_1_1_3_1_0_5_1_1 - 0.712499999999999*G0_1_1_3_1_1_0_0_0 - 0.712499999999999*G0_1_1_3_1_1_0_0_1 + 0.712499999999999*G0_1_1_3_1_1_1_0_0 + 0.712499999999999*G0_1_1_3_1_1_2_0_1 - 0.712499999999999*G0_1_1_3_1_1_3_1_0 - 0.712499999999999*G0_1_1_3_1_1_3_1_1 + 0.712499999999999*G0_1_1_3_1_1_4_1_0 + 0.712499999999999*G0_1_1_3_1_1_5_1_1 + 0.712499999999999*G0_1_1_4_1_0_0_0_0 + 0.712499999999999*G0_1_1_4_1_0_0_0_1 - 0.712499999999999*G0_1_1_4_1_0_1_0_0 - 0.712499999999999*G0_1_1_4_1_0_2_0_1 + 0.712499999999999*G0_1_1_4_1_0_3_1_0 + 0.712499999999999*G0_1_1_4_1_0_3_1_1 - 0.712499999999999*G0_1_1_4_1_0_4_1_0 - 0.712499999999999*G0_1_1_4_1_0_5_1_1 + 0.712499999999999*G0_1_1_5_1_1_0_0_0 + 0.712499999999999*G0_1_1_5_1_1_0_0_1 - 0.712499999999999*G0_1_1_5_1_1_1_0_0 - 0.712499999999999*G0_1_1_5_1_1_2_0_1 + 0.712499999999999*G0_1_1_5_1_1_3_1_0 + 0.712499999999999*G0_1_1_5_1_1_3_1_1 - 0.712499999999999*G0_1_1_5_1_1_4_1_0 - 0.712499999999999*G0_1_1_5_1_1_5_1_1; + A[91] = 0.0; + A[47] = A[257]; + A[110] = 0.0; + A[121] = A[235]; + A[97] = 0.0; + A[144] = A[143]; + A[381] = 0.0; + A[160] = A[370]; + A[319] = A[393]; + A[239] = 0.0; + A[331] = A[235]; + A[138] = 0.0; + A[386] = 0.0; + A[350] = A[370] - 1.0125*G0_0_0_0_0_0_0_0_0 - 1.0125*G0_0_0_0_0_0_0_0_1 + 1.0125*G0_0_0_0_0_0_1_0_0 + 1.0125*G0_0_0_0_0_0_2_0_1 - 1.0125*G0_0_0_0_0_0_3_1_0 - 1.0125*G0_0_0_0_0_0_3_1_1 + 1.0125*G0_0_0_0_0_0_4_1_0 + 1.0125*G0_0_0_0_0_0_5_1_1 - 1.0125*G0_0_0_0_0_1_0_0_0 - 1.0125*G0_0_0_0_0_1_0_0_1 + 1.0125*G0_0_0_0_0_1_1_0_0 + 1.0125*G0_0_0_0_0_1_2_0_1 - 1.0125*G0_0_0_0_0_1_3_1_0 - 1.0125*G0_0_0_0_0_1_3_1_1 + 1.0125*G0_0_0_0_0_1_4_1_0 + 1.0125*G0_0_0_0_0_1_5_1_1 + 1.0125*G0_0_0_1_0_0_0_0_0 + 1.0125*G0_0_0_1_0_0_0_0_1 - 1.0125*G0_0_0_1_0_0_1_0_0 - 1.0125*G0_0_0_1_0_0_2_0_1 + 1.0125*G0_0_0_1_0_0_3_1_0 + 1.0125*G0_0_0_1_0_0_3_1_1 - 1.0125*G0_0_0_1_0_0_4_1_0 - 1.0125*G0_0_0_1_0_0_5_1_1 + 1.0125*G0_0_0_2_0_1_0_0_0 + 1.0125*G0_0_0_2_0_1_0_0_1 - 1.0125*G0_0_0_2_0_1_1_0_0 - 1.0125*G0_0_0_2_0_1_2_0_1 + 1.0125*G0_0_0_2_0_1_3_1_0 + 1.0125*G0_0_0_2_0_1_3_1_1 - 1.0125*G0_0_0_2_0_1_4_1_0 - 1.0125*G0_0_0_2_0_1_5_1_1 - 1.0125*G0_0_0_3_1_0_0_0_0 - 1.0125*G0_0_0_3_1_0_0_0_1 + 1.0125*G0_0_0_3_1_0_1_0_0 + 1.0125*G0_0_0_3_1_0_2_0_1 - 1.0125*G0_0_0_3_1_0_3_1_0 - 1.0125*G0_0_0_3_1_0_3_1_1 + 1.0125*G0_0_0_3_1_0_4_1_0 + 1.0125*G0_0_0_3_1_0_5_1_1 - 1.0125*G0_0_0_3_1_1_0_0_0 - 1.0125*G0_0_0_3_1_1_0_0_1 + 1.0125*G0_0_0_3_1_1_1_0_0 + 1.0125*G0_0_0_3_1_1_2_0_1 - 1.0125*G0_0_0_3_1_1_3_1_0 - 1.0125*G0_0_0_3_1_1_3_1_1 + 1.0125*G0_0_0_3_1_1_4_1_0 + 1.0125*G0_0_0_3_1_1_5_1_1 + 1.0125*G0_0_0_4_1_0_0_0_0 + 1.0125*G0_0_0_4_1_0_0_0_1 - 1.0125*G0_0_0_4_1_0_1_0_0 - 1.0125*G0_0_0_4_1_0_2_0_1 + 1.0125*G0_0_0_4_1_0_3_1_0 + 1.0125*G0_0_0_4_1_0_3_1_1 - 1.0125*G0_0_0_4_1_0_4_1_0 - 1.0125*G0_0_0_4_1_0_5_1_1 + 1.0125*G0_0_0_5_1_1_0_0_0 + 1.0125*G0_0_0_5_1_1_0_0_1 - 1.0125*G0_0_0_5_1_1_1_0_0 - 1.0125*G0_0_0_5_1_1_2_0_1 + 1.0125*G0_0_0_5_1_1_3_1_0 + 1.0125*G0_0_0_5_1_1_3_1_1 - 1.0125*G0_0_0_5_1_1_4_1_0 - 1.0125*G0_0_0_5_1_1_5_1_1 - 1.0125*G0_0_1_0_0_0_0_0_0 - 1.0125*G0_0_1_0_0_0_0_0_1 + 1.0125*G0_0_1_0_0_0_1_0_0 + 1.0125*G0_0_1_0_0_0_2_0_1 - 1.0125*G0_0_1_0_0_0_3_1_0 - 1.0125*G0_0_1_0_0_0_3_1_1 + 1.0125*G0_0_1_0_0_0_4_1_0 + 1.0125*G0_0_1_0_0_0_5_1_1 - 1.0125*G0_0_1_0_0_1_0_0_0 - 1.0125*G0_0_1_0_0_1_0_0_1 + 1.0125*G0_0_1_0_0_1_1_0_0 + 1.0125*G0_0_1_0_0_1_2_0_1 - 1.0125*G0_0_1_0_0_1_3_1_0 - 1.0125*G0_0_1_0_0_1_3_1_1 + 1.0125*G0_0_1_0_0_1_4_1_0 + 1.0125*G0_0_1_0_0_1_5_1_1 + 1.0125*G0_0_1_1_0_0_0_0_0 + 1.0125*G0_0_1_1_0_0_0_0_1 - 1.0125*G0_0_1_1_0_0_1_0_0 - 1.0125*G0_0_1_1_0_0_2_0_1 + 1.0125*G0_0_1_1_0_0_3_1_0 + 1.0125*G0_0_1_1_0_0_3_1_1 - 1.0125*G0_0_1_1_0_0_4_1_0 - 1.0125*G0_0_1_1_0_0_5_1_1 + 1.0125*G0_0_1_2_0_1_0_0_0 + 1.0125*G0_0_1_2_0_1_0_0_1 - 1.0125*G0_0_1_2_0_1_1_0_0 - 1.0125*G0_0_1_2_0_1_2_0_1 + 1.0125*G0_0_1_2_0_1_3_1_0 + 1.0125*G0_0_1_2_0_1_3_1_1 - 1.0125*G0_0_1_2_0_1_4_1_0 - 1.0125*G0_0_1_2_0_1_5_1_1 - 1.0125*G0_0_1_3_1_0_0_0_0 - 1.0125*G0_0_1_3_1_0_0_0_1 + 1.0125*G0_0_1_3_1_0_1_0_0 + 1.0125*G0_0_1_3_1_0_2_0_1 - 1.0125*G0_0_1_3_1_0_3_1_0 - 1.0125*G0_0_1_3_1_0_3_1_1 + 1.0125*G0_0_1_3_1_0_4_1_0 + 1.0125*G0_0_1_3_1_0_5_1_1 - 1.0125*G0_0_1_3_1_1_0_0_0 - 1.0125*G0_0_1_3_1_1_0_0_1 + 1.0125*G0_0_1_3_1_1_1_0_0 + 1.0125*G0_0_1_3_1_1_2_0_1 - 1.0125*G0_0_1_3_1_1_3_1_0 - 1.0125*G0_0_1_3_1_1_3_1_1 + 1.0125*G0_0_1_3_1_1_4_1_0 + 1.0125*G0_0_1_3_1_1_5_1_1 + 1.0125*G0_0_1_4_1_0_0_0_0 + 1.0125*G0_0_1_4_1_0_0_0_1 - 1.0125*G0_0_1_4_1_0_1_0_0 - 1.0125*G0_0_1_4_1_0_2_0_1 + 1.0125*G0_0_1_4_1_0_3_1_0 + 1.0125*G0_0_1_4_1_0_3_1_1 - 1.0125*G0_0_1_4_1_0_4_1_0 - 1.0125*G0_0_1_4_1_0_5_1_1 + 1.0125*G0_0_1_5_1_1_0_0_0 + 1.0125*G0_0_1_5_1_1_0_0_1 - 1.0125*G0_0_1_5_1_1_1_0_0 - 1.0125*G0_0_1_5_1_1_2_0_1 + 1.0125*G0_0_1_5_1_1_3_1_0 + 1.0125*G0_0_1_5_1_1_3_1_1 - 1.0125*G0_0_1_5_1_1_4_1_0 - 1.0125*G0_0_1_5_1_1_5_1_1; + A[377] = -A[143] - 1.35*G0_0_0_0_0_0_0_0_0 - 1.35*G0_0_0_0_0_0_0_0_1 + 1.35*G0_0_0_0_0_0_1_0_0 + 1.35*G0_0_0_0_0_0_2_0_1 - 1.35*G0_0_0_0_0_0_3_1_0 - 1.35*G0_0_0_0_0_0_3_1_1 + 1.35*G0_0_0_0_0_0_4_1_0 + 1.35*G0_0_0_0_0_0_5_1_1 - 1.35*G0_0_0_0_0_1_0_0_0 - 1.35*G0_0_0_0_0_1_0_0_1 + 1.35*G0_0_0_0_0_1_1_0_0 + 1.35*G0_0_0_0_0_1_2_0_1 - 1.35*G0_0_0_0_0_1_3_1_0 - 1.35*G0_0_0_0_0_1_3_1_1 + 1.35*G0_0_0_0_0_1_4_1_0 + 1.35*G0_0_0_0_0_1_5_1_1 + 1.35*G0_0_0_1_0_0_0_0_0 + 1.35*G0_0_0_1_0_0_0_0_1 - 1.35*G0_0_0_1_0_0_1_0_0 - 1.35*G0_0_0_1_0_0_2_0_1 + 1.35*G0_0_0_1_0_0_3_1_0 + 1.35*G0_0_0_1_0_0_3_1_1 - 1.35*G0_0_0_1_0_0_4_1_0 - 1.35*G0_0_0_1_0_0_5_1_1 + 1.35*G0_0_0_2_0_1_0_0_0 + 1.35*G0_0_0_2_0_1_0_0_1 - 1.35*G0_0_0_2_0_1_1_0_0 - 1.35*G0_0_0_2_0_1_2_0_1 + 1.35*G0_0_0_2_0_1_3_1_0 + 1.35*G0_0_0_2_0_1_3_1_1 - 1.35*G0_0_0_2_0_1_4_1_0 - 1.35*G0_0_0_2_0_1_5_1_1 - 1.35*G0_0_0_3_1_0_0_0_0 - 1.35*G0_0_0_3_1_0_0_0_1 + 1.35*G0_0_0_3_1_0_1_0_0 + 1.35*G0_0_0_3_1_0_2_0_1 - 1.35*G0_0_0_3_1_0_3_1_0 - 1.35*G0_0_0_3_1_0_3_1_1 + 1.35*G0_0_0_3_1_0_4_1_0 + 1.35*G0_0_0_3_1_0_5_1_1 - 1.35*G0_0_0_3_1_1_0_0_0 - 1.35*G0_0_0_3_1_1_0_0_1 + 1.35*G0_0_0_3_1_1_1_0_0 + 1.35*G0_0_0_3_1_1_2_0_1 - 1.35*G0_0_0_3_1_1_3_1_0 - 1.35*G0_0_0_3_1_1_3_1_1 + 1.35*G0_0_0_3_1_1_4_1_0 + 1.35*G0_0_0_3_1_1_5_1_1 + 1.35*G0_0_0_4_1_0_0_0_0 + 1.35*G0_0_0_4_1_0_0_0_1 - 1.35*G0_0_0_4_1_0_1_0_0 - 1.35*G0_0_0_4_1_0_2_0_1 + 1.35*G0_0_0_4_1_0_3_1_0 + 1.35*G0_0_0_4_1_0_3_1_1 - 1.35*G0_0_0_4_1_0_4_1_0 - 1.35*G0_0_0_4_1_0_5_1_1 + 1.35*G0_0_0_5_1_1_0_0_0 + 1.35*G0_0_0_5_1_1_0_0_1 - 1.35*G0_0_0_5_1_1_1_0_0 - 1.35*G0_0_0_5_1_1_2_0_1 + 1.35*G0_0_0_5_1_1_3_1_0 + 1.35*G0_0_0_5_1_1_3_1_1 - 1.35*G0_0_0_5_1_1_4_1_0 - 1.35*G0_0_0_5_1_1_5_1_1 - 1.0125*G0_0_1_0_0_0_0_0_0 - 1.0125*G0_0_1_0_0_0_0_0_1 + 1.0125*G0_0_1_0_0_0_1_0_0 + 1.0125*G0_0_1_0_0_0_2_0_1 - 1.0125*G0_0_1_0_0_0_3_1_0 - 1.0125*G0_0_1_0_0_0_3_1_1 + 1.0125*G0_0_1_0_0_0_4_1_0 + 1.0125*G0_0_1_0_0_0_5_1_1 - 1.0125*G0_0_1_0_0_1_0_0_0 - 1.0125*G0_0_1_0_0_1_0_0_1 + 1.0125*G0_0_1_0_0_1_1_0_0 + 1.0125*G0_0_1_0_0_1_2_0_1 - 1.0125*G0_0_1_0_0_1_3_1_0 - 1.0125*G0_0_1_0_0_1_3_1_1 + 1.0125*G0_0_1_0_0_1_4_1_0 + 1.0125*G0_0_1_0_0_1_5_1_1 + 1.0125*G0_0_1_1_0_0_0_0_0 + 1.0125*G0_0_1_1_0_0_0_0_1 - 1.0125*G0_0_1_1_0_0_1_0_0 - 1.0125*G0_0_1_1_0_0_2_0_1 + 1.0125*G0_0_1_1_0_0_3_1_0 + 1.0125*G0_0_1_1_0_0_3_1_1 - 1.0125*G0_0_1_1_0_0_4_1_0 - 1.0125*G0_0_1_1_0_0_5_1_1 + 1.0125*G0_0_1_2_0_1_0_0_0 + 1.0125*G0_0_1_2_0_1_0_0_1 - 1.0125*G0_0_1_2_0_1_1_0_0 - 1.0125*G0_0_1_2_0_1_2_0_1 + 1.0125*G0_0_1_2_0_1_3_1_0 + 1.0125*G0_0_1_2_0_1_3_1_1 - 1.0125*G0_0_1_2_0_1_4_1_0 - 1.0125*G0_0_1_2_0_1_5_1_1 - 1.0125*G0_0_1_3_1_0_0_0_0 - 1.0125*G0_0_1_3_1_0_0_0_1 + 1.0125*G0_0_1_3_1_0_1_0_0 + 1.0125*G0_0_1_3_1_0_2_0_1 - 1.0125*G0_0_1_3_1_0_3_1_0 - 1.0125*G0_0_1_3_1_0_3_1_1 + 1.0125*G0_0_1_3_1_0_4_1_0 + 1.0125*G0_0_1_3_1_0_5_1_1 - 1.0125*G0_0_1_3_1_1_0_0_0 - 1.0125*G0_0_1_3_1_1_0_0_1 + 1.0125*G0_0_1_3_1_1_1_0_0 + 1.0125*G0_0_1_3_1_1_2_0_1 - 1.0125*G0_0_1_3_1_1_3_1_0 - 1.0125*G0_0_1_3_1_1_3_1_1 + 1.0125*G0_0_1_3_1_1_4_1_0 + 1.0125*G0_0_1_3_1_1_5_1_1 + 1.0125*G0_0_1_4_1_0_0_0_0 + 1.0125*G0_0_1_4_1_0_0_0_1 - 1.0125*G0_0_1_4_1_0_1_0_0 - 1.0125*G0_0_1_4_1_0_2_0_1 + 1.0125*G0_0_1_4_1_0_3_1_0 + 1.0125*G0_0_1_4_1_0_3_1_1 - 1.0125*G0_0_1_4_1_0_4_1_0 - 1.0125*G0_0_1_4_1_0_5_1_1 + 1.0125*G0_0_1_5_1_1_0_0_0 + 1.0125*G0_0_1_5_1_1_0_0_1 - 1.0125*G0_0_1_5_1_1_1_0_0 - 1.0125*G0_0_1_5_1_1_2_0_1 + 1.0125*G0_0_1_5_1_1_3_1_0 + 1.0125*G0_0_1_5_1_1_3_1_1 - 1.0125*G0_0_1_5_1_1_4_1_0 - 1.0125*G0_0_1_5_1_1_5_1_1; + A[167] = A[377]; + A[186] = A[379]; + A[205] = 0.0; + A[228] = 0.0; + A[19] = 0.0; + A[287] = 0.0; + A[259] = 0.0; + A[38] = 0.0; + A[306] = 0.0; + A[278] = -4.99999999999982*A[143]; + A[273] = -A[278] + 1.68749999999999*G0_0_0_0_0_0_0_0_0 + 1.68749999999999*G0_0_0_0_0_0_0_0_1 - 1.68749999999999*G0_0_0_0_0_0_1_0_0 - 1.68749999999999*G0_0_0_0_0_0_2_0_1 + 1.68749999999999*G0_0_0_0_0_0_3_1_0 + 1.68749999999999*G0_0_0_0_0_0_3_1_1 - 1.68749999999999*G0_0_0_0_0_0_4_1_0 - 1.68749999999999*G0_0_0_0_0_0_5_1_1 + 1.68749999999999*G0_0_0_0_0_1_0_0_0 + 1.68749999999999*G0_0_0_0_0_1_0_0_1 - 1.68749999999999*G0_0_0_0_0_1_1_0_0 - 1.68749999999999*G0_0_0_0_0_1_2_0_1 + 1.68749999999999*G0_0_0_0_0_1_3_1_0 + 1.68749999999999*G0_0_0_0_0_1_3_1_1 - 1.68749999999999*G0_0_0_0_0_1_4_1_0 - 1.68749999999999*G0_0_0_0_0_1_5_1_1 - 1.68749999999999*G0_0_0_1_0_0_0_0_0 - 1.68749999999999*G0_0_0_1_0_0_0_0_1 + 1.68749999999999*G0_0_0_1_0_0_1_0_0 + 1.68749999999999*G0_0_0_1_0_0_2_0_1 - 1.68749999999999*G0_0_0_1_0_0_3_1_0 - 1.68749999999999*G0_0_0_1_0_0_3_1_1 + 1.68749999999999*G0_0_0_1_0_0_4_1_0 + 1.68749999999999*G0_0_0_1_0_0_5_1_1 - 1.68749999999999*G0_0_0_2_0_1_0_0_0 - 1.68749999999999*G0_0_0_2_0_1_0_0_1 + 1.68749999999999*G0_0_0_2_0_1_1_0_0 + 1.68749999999999*G0_0_0_2_0_1_2_0_1 - 1.68749999999999*G0_0_0_2_0_1_3_1_0 - 1.68749999999999*G0_0_0_2_0_1_3_1_1 + 1.68749999999999*G0_0_0_2_0_1_4_1_0 + 1.68749999999999*G0_0_0_2_0_1_5_1_1 + 1.68749999999999*G0_0_0_3_1_0_0_0_0 + 1.68749999999999*G0_0_0_3_1_0_0_0_1 - 1.68749999999999*G0_0_0_3_1_0_1_0_0 - 1.68749999999999*G0_0_0_3_1_0_2_0_1 + 1.68749999999999*G0_0_0_3_1_0_3_1_0 + 1.68749999999999*G0_0_0_3_1_0_3_1_1 - 1.68749999999999*G0_0_0_3_1_0_4_1_0 - 1.68749999999999*G0_0_0_3_1_0_5_1_1 + 1.68749999999999*G0_0_0_3_1_1_0_0_0 + 1.68749999999999*G0_0_0_3_1_1_0_0_1 - 1.68749999999999*G0_0_0_3_1_1_1_0_0 - 1.68749999999999*G0_0_0_3_1_1_2_0_1 + 1.68749999999999*G0_0_0_3_1_1_3_1_0 + 1.68749999999999*G0_0_0_3_1_1_3_1_1 - 1.68749999999999*G0_0_0_3_1_1_4_1_0 - 1.68749999999999*G0_0_0_3_1_1_5_1_1 - 1.68749999999999*G0_0_0_4_1_0_0_0_0 - 1.68749999999999*G0_0_0_4_1_0_0_0_1 + 1.68749999999999*G0_0_0_4_1_0_1_0_0 + 1.68749999999999*G0_0_0_4_1_0_2_0_1 - 1.68749999999999*G0_0_0_4_1_0_3_1_0 - 1.68749999999999*G0_0_0_4_1_0_3_1_1 + 1.68749999999999*G0_0_0_4_1_0_4_1_0 + 1.68749999999999*G0_0_0_4_1_0_5_1_1 - 1.68749999999999*G0_0_0_5_1_1_0_0_0 - 1.68749999999999*G0_0_0_5_1_1_0_0_1 + 1.68749999999999*G0_0_0_5_1_1_1_0_0 + 1.68749999999999*G0_0_0_5_1_1_2_0_1 - 1.68749999999999*G0_0_0_5_1_1_3_1_0 - 1.68749999999999*G0_0_0_5_1_1_3_1_1 + 1.68749999999999*G0_0_0_5_1_1_4_1_0 + 1.68749999999999*G0_0_0_5_1_1_5_1_1; + A[189] = 2.4*A[273]; + A[357] = A[273]; + A[9] = 0.0; + A[64] = -A[143] - 0.337499999999997*G0_0_0_0_0_0_0_0_0 - 0.337499999999997*G0_0_0_0_0_0_0_0_1 + 0.337499999999997*G0_0_0_0_0_0_1_0_0 + 0.337499999999997*G0_0_0_0_0_0_2_0_1 - 0.337499999999997*G0_0_0_0_0_0_3_1_0 - 0.337499999999997*G0_0_0_0_0_0_3_1_1 + 0.337499999999997*G0_0_0_0_0_0_4_1_0 + 0.337499999999997*G0_0_0_0_0_0_5_1_1 - 0.337499999999997*G0_0_0_0_0_1_0_0_0 - 0.337499999999997*G0_0_0_0_0_1_0_0_1 + 0.337499999999997*G0_0_0_0_0_1_1_0_0 + 0.337499999999997*G0_0_0_0_0_1_2_0_1 - 0.337499999999997*G0_0_0_0_0_1_3_1_0 - 0.337499999999997*G0_0_0_0_0_1_3_1_1 + 0.337499999999997*G0_0_0_0_0_1_4_1_0 + 0.337499999999997*G0_0_0_0_0_1_5_1_1 + 0.337499999999997*G0_0_0_1_0_0_0_0_0 + 0.337499999999997*G0_0_0_1_0_0_0_0_1 - 0.337499999999997*G0_0_0_1_0_0_1_0_0 - 0.337499999999997*G0_0_0_1_0_0_2_0_1 + 0.337499999999997*G0_0_0_1_0_0_3_1_0 + 0.337499999999997*G0_0_0_1_0_0_3_1_1 - 0.337499999999997*G0_0_0_1_0_0_4_1_0 - 0.337499999999997*G0_0_0_1_0_0_5_1_1 + 0.337499999999997*G0_0_0_2_0_1_0_0_0 + 0.337499999999997*G0_0_0_2_0_1_0_0_1 - 0.337499999999997*G0_0_0_2_0_1_1_0_0 - 0.337499999999997*G0_0_0_2_0_1_2_0_1 + 0.337499999999997*G0_0_0_2_0_1_3_1_0 + 0.337499999999997*G0_0_0_2_0_1_3_1_1 - 0.337499999999997*G0_0_0_2_0_1_4_1_0 - 0.337499999999997*G0_0_0_2_0_1_5_1_1 - 0.337499999999997*G0_0_0_3_1_0_0_0_0 - 0.337499999999997*G0_0_0_3_1_0_0_0_1 + 0.337499999999997*G0_0_0_3_1_0_1_0_0 + 0.337499999999997*G0_0_0_3_1_0_2_0_1 - 0.337499999999997*G0_0_0_3_1_0_3_1_0 - 0.337499999999997*G0_0_0_3_1_0_3_1_1 + 0.337499999999997*G0_0_0_3_1_0_4_1_0 + 0.337499999999997*G0_0_0_3_1_0_5_1_1 - 0.337499999999997*G0_0_0_3_1_1_0_0_0 - 0.337499999999997*G0_0_0_3_1_1_0_0_1 + 0.337499999999997*G0_0_0_3_1_1_1_0_0 + 0.337499999999997*G0_0_0_3_1_1_2_0_1 - 0.337499999999997*G0_0_0_3_1_1_3_1_0 - 0.337499999999997*G0_0_0_3_1_1_3_1_1 + 0.337499999999997*G0_0_0_3_1_1_4_1_0 + 0.337499999999997*G0_0_0_3_1_1_5_1_1 + 0.337499999999997*G0_0_0_4_1_0_0_0_0 + 0.337499999999997*G0_0_0_4_1_0_0_0_1 - 0.337499999999997*G0_0_0_4_1_0_1_0_0 - 0.337499999999997*G0_0_0_4_1_0_2_0_1 + 0.337499999999997*G0_0_0_4_1_0_3_1_0 + 0.337499999999997*G0_0_0_4_1_0_3_1_1 - 0.337499999999997*G0_0_0_4_1_0_4_1_0 - 0.337499999999997*G0_0_0_4_1_0_5_1_1 + 0.337499999999997*G0_0_0_5_1_1_0_0_0 + 0.337499999999997*G0_0_0_5_1_1_0_0_1 - 0.337499999999997*G0_0_0_5_1_1_1_0_0 - 0.337499999999997*G0_0_0_5_1_1_2_0_1 + 0.337499999999997*G0_0_0_5_1_1_3_1_0 + 0.337499999999997*G0_0_0_5_1_1_3_1_1 - 0.337499999999997*G0_0_0_5_1_1_4_1_0 - 0.337499999999997*G0_0_0_5_1_1_5_1_1 + 1.01250000000001*G0_0_1_0_0_0_0_0_0 + 1.01250000000001*G0_0_1_0_0_0_0_0_1 - 1.01250000000001*G0_0_1_0_0_0_1_0_0 - 1.01250000000001*G0_0_1_0_0_0_2_0_1 + 1.01250000000001*G0_0_1_0_0_0_3_1_0 + 1.01250000000001*G0_0_1_0_0_0_3_1_1 - 1.01250000000001*G0_0_1_0_0_0_4_1_0 - 1.01250000000001*G0_0_1_0_0_0_5_1_1 + 1.01250000000001*G0_0_1_0_0_1_0_0_0 + 1.01250000000001*G0_0_1_0_0_1_0_0_1 - 1.01250000000001*G0_0_1_0_0_1_1_0_0 - 1.01250000000001*G0_0_1_0_0_1_2_0_1 + 1.01250000000001*G0_0_1_0_0_1_3_1_0 + 1.01250000000001*G0_0_1_0_0_1_3_1_1 - 1.01250000000001*G0_0_1_0_0_1_4_1_0 - 1.01250000000001*G0_0_1_0_0_1_5_1_1 - 1.01250000000001*G0_0_1_1_0_0_0_0_0 - 1.01250000000001*G0_0_1_1_0_0_0_0_1 + 1.01250000000001*G0_0_1_1_0_0_1_0_0 + 1.01250000000001*G0_0_1_1_0_0_2_0_1 - 1.01250000000001*G0_0_1_1_0_0_3_1_0 - 1.01250000000001*G0_0_1_1_0_0_3_1_1 + 1.01250000000001*G0_0_1_1_0_0_4_1_0 + 1.01250000000001*G0_0_1_1_0_0_5_1_1 - 1.01250000000001*G0_0_1_2_0_1_0_0_0 - 1.01250000000001*G0_0_1_2_0_1_0_0_1 + 1.01250000000001*G0_0_1_2_0_1_1_0_0 + 1.01250000000001*G0_0_1_2_0_1_2_0_1 - 1.01250000000001*G0_0_1_2_0_1_3_1_0 - 1.01250000000001*G0_0_1_2_0_1_3_1_1 + 1.01250000000001*G0_0_1_2_0_1_4_1_0 + 1.01250000000001*G0_0_1_2_0_1_5_1_1 + 1.01250000000001*G0_0_1_3_1_0_0_0_0 + 1.01250000000001*G0_0_1_3_1_0_0_0_1 - 1.01250000000001*G0_0_1_3_1_0_1_0_0 - 1.01250000000001*G0_0_1_3_1_0_2_0_1 + 1.01250000000001*G0_0_1_3_1_0_3_1_0 + 1.01250000000001*G0_0_1_3_1_0_3_1_1 - 1.01250000000001*G0_0_1_3_1_0_4_1_0 - 1.01250000000001*G0_0_1_3_1_0_5_1_1 + 1.01250000000001*G0_0_1_3_1_1_0_0_0 + 1.01250000000001*G0_0_1_3_1_1_0_0_1 - 1.01250000000001*G0_0_1_3_1_1_1_0_0 - 1.01250000000001*G0_0_1_3_1_1_2_0_1 + 1.01250000000001*G0_0_1_3_1_1_3_1_0 + 1.01250000000001*G0_0_1_3_1_1_3_1_1 - 1.01250000000001*G0_0_1_3_1_1_4_1_0 - 1.01250000000001*G0_0_1_3_1_1_5_1_1 - 1.01250000000001*G0_0_1_4_1_0_0_0_0 - 1.01250000000001*G0_0_1_4_1_0_0_0_1 + 1.01250000000001*G0_0_1_4_1_0_1_0_0 + 1.01250000000001*G0_0_1_4_1_0_2_0_1 - 1.01250000000001*G0_0_1_4_1_0_3_1_0 - 1.01250000000001*G0_0_1_4_1_0_3_1_1 + 1.01250000000001*G0_0_1_4_1_0_4_1_0 + 1.01250000000001*G0_0_1_4_1_0_5_1_1 - 1.01250000000001*G0_0_1_5_1_1_0_0_0 - 1.01250000000001*G0_0_1_5_1_1_0_0_1 + 1.01250000000001*G0_0_1_5_1_1_1_0_0 + 1.01250000000001*G0_0_1_5_1_1_2_0_1 - 1.01250000000001*G0_0_1_5_1_1_3_1_0 - 1.01250000000001*G0_0_1_5_1_1_3_1_1 + 1.01250000000001*G0_0_1_5_1_1_4_1_0 + 1.01250000000001*G0_0_1_5_1_1_5_1_1; + A[87] = A[143]; + A[106] = -A[85] - 1.0125*G0_0_1_0_0_0_0_0_0 - 1.0125*G0_0_1_0_0_0_0_0_1 + 1.0125*G0_0_1_0_0_0_1_0_0 + 1.0125*G0_0_1_0_0_0_2_0_1 - 1.0125*G0_0_1_0_0_0_3_1_0 - 1.0125*G0_0_1_0_0_0_3_1_1 + 1.0125*G0_0_1_0_0_0_4_1_0 + 1.0125*G0_0_1_0_0_0_5_1_1 - 1.0125*G0_0_1_0_0_1_0_0_0 - 1.0125*G0_0_1_0_0_1_0_0_1 + 1.0125*G0_0_1_0_0_1_1_0_0 + 1.0125*G0_0_1_0_0_1_2_0_1 - 1.0125*G0_0_1_0_0_1_3_1_0 - 1.0125*G0_0_1_0_0_1_3_1_1 + 1.0125*G0_0_1_0_0_1_4_1_0 + 1.0125*G0_0_1_0_0_1_5_1_1 + 1.0125*G0_0_1_1_0_0_0_0_0 + 1.0125*G0_0_1_1_0_0_0_0_1 - 1.0125*G0_0_1_1_0_0_1_0_0 - 1.0125*G0_0_1_1_0_0_2_0_1 + 1.0125*G0_0_1_1_0_0_3_1_0 + 1.0125*G0_0_1_1_0_0_3_1_1 - 1.0125*G0_0_1_1_0_0_4_1_0 - 1.0125*G0_0_1_1_0_0_5_1_1 + 1.0125*G0_0_1_2_0_1_0_0_0 + 1.0125*G0_0_1_2_0_1_0_0_1 - 1.0125*G0_0_1_2_0_1_1_0_0 - 1.0125*G0_0_1_2_0_1_2_0_1 + 1.0125*G0_0_1_2_0_1_3_1_0 + 1.0125*G0_0_1_2_0_1_3_1_1 - 1.0125*G0_0_1_2_0_1_4_1_0 - 1.0125*G0_0_1_2_0_1_5_1_1 - 1.0125*G0_0_1_3_1_0_0_0_0 - 1.0125*G0_0_1_3_1_0_0_0_1 + 1.0125*G0_0_1_3_1_0_1_0_0 + 1.0125*G0_0_1_3_1_0_2_0_1 - 1.0125*G0_0_1_3_1_0_3_1_0 - 1.0125*G0_0_1_3_1_0_3_1_1 + 1.0125*G0_0_1_3_1_0_4_1_0 + 1.0125*G0_0_1_3_1_0_5_1_1 - 1.0125*G0_0_1_3_1_1_0_0_0 - 1.0125*G0_0_1_3_1_1_0_0_1 + 1.0125*G0_0_1_3_1_1_1_0_0 + 1.0125*G0_0_1_3_1_1_2_0_1 - 1.0125*G0_0_1_3_1_1_3_1_0 - 1.0125*G0_0_1_3_1_1_3_1_1 + 1.0125*G0_0_1_3_1_1_4_1_0 + 1.0125*G0_0_1_3_1_1_5_1_1 + 1.0125*G0_0_1_4_1_0_0_0_0 + 1.0125*G0_0_1_4_1_0_0_0_1 - 1.0125*G0_0_1_4_1_0_1_0_0 - 1.0125*G0_0_1_4_1_0_2_0_1 + 1.0125*G0_0_1_4_1_0_3_1_0 + 1.0125*G0_0_1_4_1_0_3_1_1 - 1.0125*G0_0_1_4_1_0_4_1_0 - 1.0125*G0_0_1_4_1_0_5_1_1 + 1.0125*G0_0_1_5_1_1_0_0_0 + 1.0125*G0_0_1_5_1_1_0_0_1 - 1.0125*G0_0_1_5_1_1_1_0_0 - 1.0125*G0_0_1_5_1_1_2_0_1 + 1.0125*G0_0_1_5_1_1_3_1_0 + 1.0125*G0_0_1_5_1_1_3_1_1 - 1.0125*G0_0_1_5_1_1_4_1_0 - 1.0125*G0_0_1_5_1_1_5_1_1 - 1.35*G0_1_1_0_0_0_0_0_0 - 1.35*G0_1_1_0_0_0_0_0_1 + 1.35*G0_1_1_0_0_0_1_0_0 + 1.35*G0_1_1_0_0_0_2_0_1 - 1.35*G0_1_1_0_0_0_3_1_0 - 1.35*G0_1_1_0_0_0_3_1_1 + 1.35*G0_1_1_0_0_0_4_1_0 + 1.35*G0_1_1_0_0_0_5_1_1 - 1.35*G0_1_1_0_0_1_0_0_0 - 1.35*G0_1_1_0_0_1_0_0_1 + 1.35*G0_1_1_0_0_1_1_0_0 + 1.35*G0_1_1_0_0_1_2_0_1 - 1.35*G0_1_1_0_0_1_3_1_0 - 1.35*G0_1_1_0_0_1_3_1_1 + 1.35*G0_1_1_0_0_1_4_1_0 + 1.35*G0_1_1_0_0_1_5_1_1 + 1.35*G0_1_1_1_0_0_0_0_0 + 1.35*G0_1_1_1_0_0_0_0_1 - 1.35*G0_1_1_1_0_0_1_0_0 - 1.35*G0_1_1_1_0_0_2_0_1 + 1.35*G0_1_1_1_0_0_3_1_0 + 1.35*G0_1_1_1_0_0_3_1_1 - 1.35*G0_1_1_1_0_0_4_1_0 - 1.35*G0_1_1_1_0_0_5_1_1 + 1.35*G0_1_1_2_0_1_0_0_0 + 1.35*G0_1_1_2_0_1_0_0_1 - 1.35*G0_1_1_2_0_1_1_0_0 - 1.35*G0_1_1_2_0_1_2_0_1 + 1.35*G0_1_1_2_0_1_3_1_0 + 1.35*G0_1_1_2_0_1_3_1_1 - 1.35*G0_1_1_2_0_1_4_1_0 - 1.35*G0_1_1_2_0_1_5_1_1 - 1.35*G0_1_1_3_1_0_0_0_0 - 1.35*G0_1_1_3_1_0_0_0_1 + 1.35*G0_1_1_3_1_0_1_0_0 + 1.35*G0_1_1_3_1_0_2_0_1 - 1.35*G0_1_1_3_1_0_3_1_0 - 1.35*G0_1_1_3_1_0_3_1_1 + 1.35*G0_1_1_3_1_0_4_1_0 + 1.35*G0_1_1_3_1_0_5_1_1 - 1.35*G0_1_1_3_1_1_0_0_0 - 1.35*G0_1_1_3_1_1_0_0_1 + 1.35*G0_1_1_3_1_1_1_0_0 + 1.35*G0_1_1_3_1_1_2_0_1 - 1.35*G0_1_1_3_1_1_3_1_0 - 1.35*G0_1_1_3_1_1_3_1_1 + 1.35*G0_1_1_3_1_1_4_1_0 + 1.35*G0_1_1_3_1_1_5_1_1 + 1.35*G0_1_1_4_1_0_0_0_0 + 1.35*G0_1_1_4_1_0_0_0_1 - 1.35*G0_1_1_4_1_0_1_0_0 - 1.35*G0_1_1_4_1_0_2_0_1 + 1.35*G0_1_1_4_1_0_3_1_0 + 1.35*G0_1_1_4_1_0_3_1_1 - 1.35*G0_1_1_4_1_0_4_1_0 - 1.35*G0_1_1_4_1_0_5_1_1 + 1.35*G0_1_1_5_1_1_0_0_0 + 1.35*G0_1_1_5_1_1_0_0_1 - 1.35*G0_1_1_5_1_1_1_0_0 - 1.35*G0_1_1_5_1_1_2_0_1 + 1.35*G0_1_1_5_1_1_3_1_0 + 1.35*G0_1_1_5_1_1_3_1_1 - 1.35*G0_1_1_5_1_1_4_1_0 - 1.35*G0_1_1_5_1_1_5_1_1; + A[322] = 0.0; + A[395] = A[393]; + A[343] = 0.0; + A[156] = 0.0; + A[368] = 0.0; + A[174] = 0.0; + A[195] = 0.0; + A[221] = 0.0; + A[197] = 0.0; + A[294] = A[273]; + A[315] = A[273]; + A[271] = -A[235] + 0.712500000000004*G0_1_0_0_0_0_0_0_0 + 0.712500000000004*G0_1_0_0_0_0_0_0_1 - 0.712500000000004*G0_1_0_0_0_0_1_0_0 - 0.712500000000004*G0_1_0_0_0_0_2_0_1 + 0.712500000000004*G0_1_0_0_0_0_3_1_0 + 0.712500000000004*G0_1_0_0_0_0_3_1_1 - 0.712500000000004*G0_1_0_0_0_0_4_1_0 - 0.712500000000004*G0_1_0_0_0_0_5_1_1 + 0.712500000000004*G0_1_0_0_0_1_0_0_0 + 0.712500000000004*G0_1_0_0_0_1_0_0_1 - 0.712500000000004*G0_1_0_0_0_1_1_0_0 - 0.712500000000004*G0_1_0_0_0_1_2_0_1 + 0.712500000000004*G0_1_0_0_0_1_3_1_0 + 0.712500000000004*G0_1_0_0_0_1_3_1_1 - 0.712500000000004*G0_1_0_0_0_1_4_1_0 - 0.712500000000004*G0_1_0_0_0_1_5_1_1 - 0.712500000000004*G0_1_0_1_0_0_0_0_0 - 0.712500000000004*G0_1_0_1_0_0_0_0_1 + 0.712500000000004*G0_1_0_1_0_0_1_0_0 + 0.712500000000004*G0_1_0_1_0_0_2_0_1 - 0.712500000000004*G0_1_0_1_0_0_3_1_0 - 0.712500000000004*G0_1_0_1_0_0_3_1_1 + 0.712500000000004*G0_1_0_1_0_0_4_1_0 + 0.712500000000004*G0_1_0_1_0_0_5_1_1 - 0.712500000000004*G0_1_0_2_0_1_0_0_0 - 0.712500000000004*G0_1_0_2_0_1_0_0_1 + 0.712500000000004*G0_1_0_2_0_1_1_0_0 + 0.712500000000004*G0_1_0_2_0_1_2_0_1 - 0.712500000000004*G0_1_0_2_0_1_3_1_0 - 0.712500000000004*G0_1_0_2_0_1_3_1_1 + 0.712500000000004*G0_1_0_2_0_1_4_1_0 + 0.712500000000004*G0_1_0_2_0_1_5_1_1 + 0.712500000000004*G0_1_0_3_1_0_0_0_0 + 0.712500000000004*G0_1_0_3_1_0_0_0_1 - 0.712500000000004*G0_1_0_3_1_0_1_0_0 - 0.712500000000004*G0_1_0_3_1_0_2_0_1 + 0.712500000000004*G0_1_0_3_1_0_3_1_0 + 0.712500000000004*G0_1_0_3_1_0_3_1_1 - 0.712500000000004*G0_1_0_3_1_0_4_1_0 - 0.712500000000004*G0_1_0_3_1_0_5_1_1 + 0.712500000000004*G0_1_0_3_1_1_0_0_0 + 0.712500000000004*G0_1_0_3_1_1_0_0_1 - 0.712500000000004*G0_1_0_3_1_1_1_0_0 - 0.712500000000004*G0_1_0_3_1_1_2_0_1 + 0.712500000000004*G0_1_0_3_1_1_3_1_0 + 0.712500000000004*G0_1_0_3_1_1_3_1_1 - 0.712500000000004*G0_1_0_3_1_1_4_1_0 - 0.712500000000004*G0_1_0_3_1_1_5_1_1 - 0.712500000000004*G0_1_0_4_1_0_0_0_0 - 0.712500000000004*G0_1_0_4_1_0_0_0_1 + 0.712500000000004*G0_1_0_4_1_0_1_0_0 + 0.712500000000004*G0_1_0_4_1_0_2_0_1 - 0.712500000000004*G0_1_0_4_1_0_3_1_0 - 0.712500000000004*G0_1_0_4_1_0_3_1_1 + 0.712500000000004*G0_1_0_4_1_0_4_1_0 + 0.712500000000004*G0_1_0_4_1_0_5_1_1 - 0.712500000000004*G0_1_0_5_1_1_0_0_0 - 0.712500000000004*G0_1_0_5_1_1_0_0_1 + 0.712500000000004*G0_1_0_5_1_1_1_0_0 + 0.712500000000004*G0_1_0_5_1_1_2_0_1 - 0.712500000000004*G0_1_0_5_1_1_3_1_0 - 0.712500000000004*G0_1_0_5_1_1_3_1_1 + 0.712500000000004*G0_1_0_5_1_1_4_1_0 + 0.712500000000004*G0_1_0_5_1_1_5_1_1; + A[56] = 0.0; + A[0] = -11.3333333333328*A[214]; + A[73] = 0.0; + A[33] = 0.0; + A[94] = 0.0; + A[50] = 0.0; + A[115] = 0.0; + A[79] = 0.0; + A[132] = 0.0; + A[344] = 0.0; + A[149] = A[299]; + A[363] = 0.0; + A[226] = 0.0; + A[297] = A[143]; + A[241] = 0.0; + A[217] = -A[214] - 0.7125*G0_0_0_0_0_0_0_0_0 - 0.7125*G0_0_0_0_0_0_0_0_1 + 0.7125*G0_0_0_0_0_0_1_0_0 + 0.7125*G0_0_0_0_0_0_2_0_1 - 0.7125*G0_0_0_0_0_0_3_1_0 - 0.7125*G0_0_0_0_0_0_3_1_1 + 0.7125*G0_0_0_0_0_0_4_1_0 + 0.7125*G0_0_0_0_0_0_5_1_1 - 0.7125*G0_0_0_0_0_1_0_0_0 - 0.7125*G0_0_0_0_0_1_0_0_1 + 0.7125*G0_0_0_0_0_1_1_0_0 + 0.7125*G0_0_0_0_0_1_2_0_1 - 0.7125*G0_0_0_0_0_1_3_1_0 - 0.7125*G0_0_0_0_0_1_3_1_1 + 0.7125*G0_0_0_0_0_1_4_1_0 + 0.7125*G0_0_0_0_0_1_5_1_1 + 0.7125*G0_0_0_1_0_0_0_0_0 + 0.7125*G0_0_0_1_0_0_0_0_1 - 0.7125*G0_0_0_1_0_0_1_0_0 - 0.7125*G0_0_0_1_0_0_2_0_1 + 0.7125*G0_0_0_1_0_0_3_1_0 + 0.7125*G0_0_0_1_0_0_3_1_1 - 0.7125*G0_0_0_1_0_0_4_1_0 - 0.7125*G0_0_0_1_0_0_5_1_1 + 0.7125*G0_0_0_2_0_1_0_0_0 + 0.7125*G0_0_0_2_0_1_0_0_1 - 0.7125*G0_0_0_2_0_1_1_0_0 - 0.7125*G0_0_0_2_0_1_2_0_1 + 0.7125*G0_0_0_2_0_1_3_1_0 + 0.7125*G0_0_0_2_0_1_3_1_1 - 0.7125*G0_0_0_2_0_1_4_1_0 - 0.7125*G0_0_0_2_0_1_5_1_1 - 0.7125*G0_0_0_3_1_0_0_0_0 - 0.7125*G0_0_0_3_1_0_0_0_1 + 0.7125*G0_0_0_3_1_0_1_0_0 + 0.7125*G0_0_0_3_1_0_2_0_1 - 0.7125*G0_0_0_3_1_0_3_1_0 - 0.7125*G0_0_0_3_1_0_3_1_1 + 0.7125*G0_0_0_3_1_0_4_1_0 + 0.7125*G0_0_0_3_1_0_5_1_1 - 0.7125*G0_0_0_3_1_1_0_0_0 - 0.7125*G0_0_0_3_1_1_0_0_1 + 0.7125*G0_0_0_3_1_1_1_0_0 + 0.7125*G0_0_0_3_1_1_2_0_1 - 0.7125*G0_0_0_3_1_1_3_1_0 - 0.7125*G0_0_0_3_1_1_3_1_1 + 0.7125*G0_0_0_3_1_1_4_1_0 + 0.7125*G0_0_0_3_1_1_5_1_1 + 0.7125*G0_0_0_4_1_0_0_0_0 + 0.7125*G0_0_0_4_1_0_0_0_1 - 0.7125*G0_0_0_4_1_0_1_0_0 - 0.7125*G0_0_0_4_1_0_2_0_1 + 0.7125*G0_0_0_4_1_0_3_1_0 + 0.7125*G0_0_0_4_1_0_3_1_1 - 0.7125*G0_0_0_4_1_0_4_1_0 - 0.7125*G0_0_0_4_1_0_5_1_1 + 0.7125*G0_0_0_5_1_1_0_0_0 + 0.7125*G0_0_0_5_1_1_0_0_1 - 0.7125*G0_0_0_5_1_1_1_0_0 - 0.7125*G0_0_0_5_1_1_2_0_1 + 0.7125*G0_0_0_5_1_1_3_1_0 + 0.7125*G0_0_0_5_1_1_3_1_1 - 0.7125*G0_0_0_5_1_1_4_1_0 - 0.7125*G0_0_0_5_1_1_5_1_1 - 0.7125*G0_1_0_0_0_0_0_0_0 - 0.7125*G0_1_0_0_0_0_0_0_1 + 0.7125*G0_1_0_0_0_0_1_0_0 + 0.7125*G0_1_0_0_0_0_2_0_1 - 0.7125*G0_1_0_0_0_0_3_1_0 - 0.7125*G0_1_0_0_0_0_3_1_1 + 0.7125*G0_1_0_0_0_0_4_1_0 + 0.7125*G0_1_0_0_0_0_5_1_1 - 0.7125*G0_1_0_0_0_1_0_0_0 - 0.7125*G0_1_0_0_0_1_0_0_1 + 0.7125*G0_1_0_0_0_1_1_0_0 + 0.7125*G0_1_0_0_0_1_2_0_1 - 0.7125*G0_1_0_0_0_1_3_1_0 - 0.7125*G0_1_0_0_0_1_3_1_1 + 0.7125*G0_1_0_0_0_1_4_1_0 + 0.7125*G0_1_0_0_0_1_5_1_1 + 0.7125*G0_1_0_1_0_0_0_0_0 + 0.7125*G0_1_0_1_0_0_0_0_1 - 0.7125*G0_1_0_1_0_0_1_0_0 - 0.7125*G0_1_0_1_0_0_2_0_1 + 0.7125*G0_1_0_1_0_0_3_1_0 + 0.7125*G0_1_0_1_0_0_3_1_1 - 0.7125*G0_1_0_1_0_0_4_1_0 - 0.7125*G0_1_0_1_0_0_5_1_1 + 0.7125*G0_1_0_2_0_1_0_0_0 + 0.7125*G0_1_0_2_0_1_0_0_1 - 0.7125*G0_1_0_2_0_1_1_0_0 - 0.7125*G0_1_0_2_0_1_2_0_1 + 0.7125*G0_1_0_2_0_1_3_1_0 + 0.7125*G0_1_0_2_0_1_3_1_1 - 0.7125*G0_1_0_2_0_1_4_1_0 - 0.7125*G0_1_0_2_0_1_5_1_1 - 0.7125*G0_1_0_3_1_0_0_0_0 - 0.7125*G0_1_0_3_1_0_0_0_1 + 0.7125*G0_1_0_3_1_0_1_0_0 + 0.7125*G0_1_0_3_1_0_2_0_1 - 0.7125*G0_1_0_3_1_0_3_1_0 - 0.7125*G0_1_0_3_1_0_3_1_1 + 0.7125*G0_1_0_3_1_0_4_1_0 + 0.7125*G0_1_0_3_1_0_5_1_1 - 0.7125*G0_1_0_3_1_1_0_0_0 - 0.7125*G0_1_0_3_1_1_0_0_1 + 0.7125*G0_1_0_3_1_1_1_0_0 + 0.7125*G0_1_0_3_1_1_2_0_1 - 0.7125*G0_1_0_3_1_1_3_1_0 - 0.7125*G0_1_0_3_1_1_3_1_1 + 0.7125*G0_1_0_3_1_1_4_1_0 + 0.7125*G0_1_0_3_1_1_5_1_1 + 0.7125*G0_1_0_4_1_0_0_0_0 + 0.7125*G0_1_0_4_1_0_0_0_1 - 0.7125*G0_1_0_4_1_0_1_0_0 - 0.7125*G0_1_0_4_1_0_2_0_1 + 0.7125*G0_1_0_4_1_0_3_1_0 + 0.7125*G0_1_0_4_1_0_3_1_1 - 0.7125*G0_1_0_4_1_0_4_1_0 - 0.7125*G0_1_0_4_1_0_5_1_1 + 0.7125*G0_1_0_5_1_1_0_0_0 + 0.7125*G0_1_0_5_1_1_0_0_1 - 0.7125*G0_1_0_5_1_1_1_0_0 - 0.7125*G0_1_0_5_1_1_2_0_1 + 0.7125*G0_1_0_5_1_1_3_1_0 + 0.7125*G0_1_0_5_1_1_3_1_1 - 0.7125*G0_1_0_5_1_1_4_1_0 - 0.7125*G0_1_0_5_1_1_5_1_1; + A[264] = 0.0; + A[7] = A[217]; + A[26] = A[235]; + A[108] = A[165]; + A[127] = A[165]; + A[99] = 0.0; + A[146] = A[165]; + A[118] = 0.0; + A[383] = 0.0; + A[162] = A[257]; + A[183] = A[393]; + A[282] = 0.0; + A[61] = A[271]; + A[333] = A[85]; + A[136] = 0.0; + A[388] = 0.0; + A[348] = 0.0; + A[375] = A[165]; + A[169] = A[379]; + A[184] = A[299]; + A[203] = 0.0; + A[285] = 0.0; + A[253] = -A[257] - 0.3*G0_1_0_0_0_0_0_0_0 - 0.3*G0_1_0_0_0_0_0_0_1 + 0.3*G0_1_0_0_0_0_1_0_0 + 0.3*G0_1_0_0_0_0_2_0_1 - 0.3*G0_1_0_0_0_0_3_1_0 - 0.3*G0_1_0_0_0_0_3_1_1 + 0.3*G0_1_0_0_0_0_4_1_0 + 0.3*G0_1_0_0_0_0_5_1_1 - 0.3*G0_1_0_0_0_1_0_0_0 - 0.3*G0_1_0_0_0_1_0_0_1 + 0.3*G0_1_0_0_0_1_1_0_0 + 0.3*G0_1_0_0_0_1_2_0_1 - 0.3*G0_1_0_0_0_1_3_1_0 - 0.3*G0_1_0_0_0_1_3_1_1 + 0.3*G0_1_0_0_0_1_4_1_0 + 0.3*G0_1_0_0_0_1_5_1_1 + 0.3*G0_1_0_1_0_0_0_0_0 + 0.3*G0_1_0_1_0_0_0_0_1 - 0.3*G0_1_0_1_0_0_1_0_0 - 0.3*G0_1_0_1_0_0_2_0_1 + 0.3*G0_1_0_1_0_0_3_1_0 + 0.3*G0_1_0_1_0_0_3_1_1 - 0.3*G0_1_0_1_0_0_4_1_0 - 0.3*G0_1_0_1_0_0_5_1_1 + 0.3*G0_1_0_2_0_1_0_0_0 + 0.3*G0_1_0_2_0_1_0_0_1 - 0.3*G0_1_0_2_0_1_1_0_0 - 0.3*G0_1_0_2_0_1_2_0_1 + 0.3*G0_1_0_2_0_1_3_1_0 + 0.3*G0_1_0_2_0_1_3_1_1 - 0.3*G0_1_0_2_0_1_4_1_0 - 0.3*G0_1_0_2_0_1_5_1_1 - 0.3*G0_1_0_3_1_0_0_0_0 - 0.3*G0_1_0_3_1_0_0_0_1 + 0.3*G0_1_0_3_1_0_1_0_0 + 0.3*G0_1_0_3_1_0_2_0_1 - 0.3*G0_1_0_3_1_0_3_1_0 - 0.3*G0_1_0_3_1_0_3_1_1 + 0.3*G0_1_0_3_1_0_4_1_0 + 0.3*G0_1_0_3_1_0_5_1_1 - 0.3*G0_1_0_3_1_1_0_0_0 - 0.3*G0_1_0_3_1_1_0_0_1 + 0.3*G0_1_0_3_1_1_1_0_0 + 0.3*G0_1_0_3_1_1_2_0_1 - 0.3*G0_1_0_3_1_1_3_1_0 - 0.3*G0_1_0_3_1_1_3_1_1 + 0.3*G0_1_0_3_1_1_4_1_0 + 0.3*G0_1_0_3_1_1_5_1_1 + 0.3*G0_1_0_4_1_0_0_0_0 + 0.3*G0_1_0_4_1_0_0_0_1 - 0.3*G0_1_0_4_1_0_1_0_0 - 0.3*G0_1_0_4_1_0_2_0_1 + 0.3*G0_1_0_4_1_0_3_1_0 + 0.3*G0_1_0_4_1_0_3_1_1 - 0.3*G0_1_0_4_1_0_4_1_0 - 0.3*G0_1_0_4_1_0_5_1_1 + 0.3*G0_1_0_5_1_1_0_0_0 + 0.3*G0_1_0_5_1_1_0_0_1 - 0.3*G0_1_0_5_1_1_1_0_0 - 0.3*G0_1_0_5_1_1_2_0_1 + 0.3*G0_1_0_5_1_1_3_1_0 + 0.3*G0_1_0_5_1_1_3_1_1 - 0.3*G0_1_0_5_1_1_4_1_0 - 0.3*G0_1_0_5_1_1_5_1_1; + A[45] = -A[253] + 0.375000000000002*G0_1_1_0_0_0_0_0_0 + 0.375000000000002*G0_1_1_0_0_0_0_0_1 - 0.375000000000002*G0_1_1_0_0_0_1_0_0 - 0.375000000000002*G0_1_1_0_0_0_2_0_1 + 0.375000000000002*G0_1_1_0_0_0_3_1_0 + 0.375000000000002*G0_1_1_0_0_0_3_1_1 - 0.375000000000002*G0_1_1_0_0_0_4_1_0 - 0.375000000000002*G0_1_1_0_0_0_5_1_1 + 0.375000000000002*G0_1_1_0_0_1_0_0_0 + 0.375000000000002*G0_1_1_0_0_1_0_0_1 - 0.375000000000002*G0_1_1_0_0_1_1_0_0 - 0.375000000000002*G0_1_1_0_0_1_2_0_1 + 0.375000000000002*G0_1_1_0_0_1_3_1_0 + 0.375000000000002*G0_1_1_0_0_1_3_1_1 - 0.375000000000002*G0_1_1_0_0_1_4_1_0 - 0.375000000000002*G0_1_1_0_0_1_5_1_1 - 0.375000000000002*G0_1_1_1_0_0_0_0_0 - 0.375000000000002*G0_1_1_1_0_0_0_0_1 + 0.375000000000002*G0_1_1_1_0_0_1_0_0 + 0.375000000000002*G0_1_1_1_0_0_2_0_1 - 0.375000000000002*G0_1_1_1_0_0_3_1_0 - 0.375000000000002*G0_1_1_1_0_0_3_1_1 + 0.375000000000002*G0_1_1_1_0_0_4_1_0 + 0.375000000000002*G0_1_1_1_0_0_5_1_1 - 0.375000000000002*G0_1_1_2_0_1_0_0_0 - 0.375000000000002*G0_1_1_2_0_1_0_0_1 + 0.375000000000002*G0_1_1_2_0_1_1_0_0 + 0.375000000000002*G0_1_1_2_0_1_2_0_1 - 0.375000000000002*G0_1_1_2_0_1_3_1_0 - 0.375000000000002*G0_1_1_2_0_1_3_1_1 + 0.375000000000002*G0_1_1_2_0_1_4_1_0 + 0.375000000000002*G0_1_1_2_0_1_5_1_1 + 0.375000000000002*G0_1_1_3_1_0_0_0_0 + 0.375000000000002*G0_1_1_3_1_0_0_0_1 - 0.375000000000002*G0_1_1_3_1_0_1_0_0 - 0.375000000000002*G0_1_1_3_1_0_2_0_1 + 0.375000000000002*G0_1_1_3_1_0_3_1_0 + 0.375000000000002*G0_1_1_3_1_0_3_1_1 - 0.375000000000002*G0_1_1_3_1_0_4_1_0 - 0.375000000000002*G0_1_1_3_1_0_5_1_1 + 0.375000000000002*G0_1_1_3_1_1_0_0_0 + 0.375000000000002*G0_1_1_3_1_1_0_0_1 - 0.375000000000002*G0_1_1_3_1_1_1_0_0 - 0.375000000000002*G0_1_1_3_1_1_2_0_1 + 0.375000000000002*G0_1_1_3_1_1_3_1_0 + 0.375000000000002*G0_1_1_3_1_1_3_1_1 - 0.375000000000002*G0_1_1_3_1_1_4_1_0 - 0.375000000000002*G0_1_1_3_1_1_5_1_1 - 0.375000000000002*G0_1_1_4_1_0_0_0_0 - 0.375000000000002*G0_1_1_4_1_0_0_0_1 + 0.375000000000002*G0_1_1_4_1_0_1_0_0 + 0.375000000000002*G0_1_1_4_1_0_2_0_1 - 0.375000000000002*G0_1_1_4_1_0_3_1_0 - 0.375000000000002*G0_1_1_4_1_0_3_1_1 + 0.375000000000002*G0_1_1_4_1_0_4_1_0 + 0.375000000000002*G0_1_1_4_1_0_5_1_1 - 0.375000000000002*G0_1_1_5_1_1_0_0_0 - 0.375000000000002*G0_1_1_5_1_1_0_0_1 + 0.375000000000002*G0_1_1_5_1_1_1_0_0 + 0.375000000000002*G0_1_1_5_1_1_2_0_1 - 0.375000000000002*G0_1_1_5_1_1_3_1_0 - 0.375000000000002*G0_1_1_5_1_1_3_1_1 + 0.375000000000002*G0_1_1_5_1_1_4_1_0 + 0.375000000000002*G0_1_1_5_1_1_5_1_1; + A[36] = 0.0; + A[300] = 0.0; + A[276] = A[85]; + A[11] = 0.0; + A[66] = A[85]; + A[30] = 0.0; + A[81] = -A[235] - 0.3*G0_1_0_0_0_0_0_0_0 - 0.3*G0_1_0_0_0_0_0_0_1 + 0.3*G0_1_0_0_0_0_1_0_0 + 0.3*G0_1_0_0_0_0_2_0_1 - 0.3*G0_1_0_0_0_0_3_1_0 - 0.3*G0_1_0_0_0_0_3_1_1 + 0.3*G0_1_0_0_0_0_4_1_0 + 0.3*G0_1_0_0_0_0_5_1_1 - 0.3*G0_1_0_0_0_1_0_0_0 - 0.3*G0_1_0_0_0_1_0_0_1 + 0.3*G0_1_0_0_0_1_1_0_0 + 0.3*G0_1_0_0_0_1_2_0_1 - 0.3*G0_1_0_0_0_1_3_1_0 - 0.3*G0_1_0_0_0_1_3_1_1 + 0.3*G0_1_0_0_0_1_4_1_0 + 0.3*G0_1_0_0_0_1_5_1_1 + 0.3*G0_1_0_1_0_0_0_0_0 + 0.3*G0_1_0_1_0_0_0_0_1 - 0.3*G0_1_0_1_0_0_1_0_0 - 0.3*G0_1_0_1_0_0_2_0_1 + 0.3*G0_1_0_1_0_0_3_1_0 + 0.3*G0_1_0_1_0_0_3_1_1 - 0.3*G0_1_0_1_0_0_4_1_0 - 0.3*G0_1_0_1_0_0_5_1_1 + 0.3*G0_1_0_2_0_1_0_0_0 + 0.3*G0_1_0_2_0_1_0_0_1 - 0.3*G0_1_0_2_0_1_1_0_0 - 0.3*G0_1_0_2_0_1_2_0_1 + 0.3*G0_1_0_2_0_1_3_1_0 + 0.3*G0_1_0_2_0_1_3_1_1 - 0.3*G0_1_0_2_0_1_4_1_0 - 0.3*G0_1_0_2_0_1_5_1_1 - 0.3*G0_1_0_3_1_0_0_0_0 - 0.3*G0_1_0_3_1_0_0_0_1 + 0.3*G0_1_0_3_1_0_1_0_0 + 0.3*G0_1_0_3_1_0_2_0_1 - 0.3*G0_1_0_3_1_0_3_1_0 - 0.3*G0_1_0_3_1_0_3_1_1 + 0.3*G0_1_0_3_1_0_4_1_0 + 0.3*G0_1_0_3_1_0_5_1_1 - 0.3*G0_1_0_3_1_1_0_0_0 - 0.3*G0_1_0_3_1_1_0_0_1 + 0.3*G0_1_0_3_1_1_1_0_0 + 0.3*G0_1_0_3_1_1_2_0_1 - 0.3*G0_1_0_3_1_1_3_1_0 - 0.3*G0_1_0_3_1_1_3_1_1 + 0.3*G0_1_0_3_1_1_4_1_0 + 0.3*G0_1_0_3_1_1_5_1_1 + 0.3*G0_1_0_4_1_0_0_0_0 + 0.3*G0_1_0_4_1_0_0_0_1 - 0.3*G0_1_0_4_1_0_1_0_0 - 0.3*G0_1_0_4_1_0_2_0_1 + 0.3*G0_1_0_4_1_0_3_1_0 + 0.3*G0_1_0_4_1_0_3_1_1 - 0.3*G0_1_0_4_1_0_4_1_0 - 0.3*G0_1_0_4_1_0_5_1_1 + 0.3*G0_1_0_5_1_1_0_0_0 + 0.3*G0_1_0_5_1_1_0_0_1 - 0.3*G0_1_0_5_1_1_1_0_0 - 0.3*G0_1_0_5_1_1_2_0_1 + 0.3*G0_1_0_5_1_1_3_1_0 + 0.3*G0_1_0_5_1_1_3_1_1 - 0.3*G0_1_0_5_1_1_4_1_0 - 0.3*G0_1_0_5_1_1_5_1_1; + A[104] = A[85]; + A[324] = 0.0; + A[131] = 0.0; + A[397] = A[299]; + A[341] = 0.0; + A[158] = 0.0; + A[366] = 0.0; + A[193] = 0.0; + A[210] = A[0]; + A[223] = 0.0; + A[292] = -A[257] + 0.712500000000005*G0_0_1_0_0_0_0_0_0 + 0.712500000000005*G0_0_1_0_0_0_0_0_1 - 0.712500000000005*G0_0_1_0_0_0_1_0_0 - 0.712500000000005*G0_0_1_0_0_0_2_0_1 + 0.712500000000005*G0_0_1_0_0_0_3_1_0 + 0.712500000000005*G0_0_1_0_0_0_3_1_1 - 0.712500000000005*G0_0_1_0_0_0_4_1_0 - 0.712500000000005*G0_0_1_0_0_0_5_1_1 + 0.712500000000005*G0_0_1_0_0_1_0_0_0 + 0.712500000000005*G0_0_1_0_0_1_0_0_1 - 0.712500000000005*G0_0_1_0_0_1_1_0_0 - 0.712500000000005*G0_0_1_0_0_1_2_0_1 + 0.712500000000005*G0_0_1_0_0_1_3_1_0 + 0.712500000000005*G0_0_1_0_0_1_3_1_1 - 0.712500000000005*G0_0_1_0_0_1_4_1_0 - 0.712500000000005*G0_0_1_0_0_1_5_1_1 - 0.712500000000005*G0_0_1_1_0_0_0_0_0 - 0.712500000000005*G0_0_1_1_0_0_0_0_1 + 0.712500000000005*G0_0_1_1_0_0_1_0_0 + 0.712500000000005*G0_0_1_1_0_0_2_0_1 - 0.712500000000005*G0_0_1_1_0_0_3_1_0 - 0.712500000000005*G0_0_1_1_0_0_3_1_1 + 0.712500000000005*G0_0_1_1_0_0_4_1_0 + 0.712500000000005*G0_0_1_1_0_0_5_1_1 - 0.712500000000005*G0_0_1_2_0_1_0_0_0 - 0.712500000000005*G0_0_1_2_0_1_0_0_1 + 0.712500000000005*G0_0_1_2_0_1_1_0_0 + 0.712500000000005*G0_0_1_2_0_1_2_0_1 - 0.712500000000005*G0_0_1_2_0_1_3_1_0 - 0.712500000000005*G0_0_1_2_0_1_3_1_1 + 0.712500000000005*G0_0_1_2_0_1_4_1_0 + 0.712500000000005*G0_0_1_2_0_1_5_1_1 + 0.712500000000005*G0_0_1_3_1_0_0_0_0 + 0.712500000000005*G0_0_1_3_1_0_0_0_1 - 0.712500000000005*G0_0_1_3_1_0_1_0_0 - 0.712500000000005*G0_0_1_3_1_0_2_0_1 + 0.712500000000005*G0_0_1_3_1_0_3_1_0 + 0.712500000000005*G0_0_1_3_1_0_3_1_1 - 0.712500000000005*G0_0_1_3_1_0_4_1_0 - 0.712500000000005*G0_0_1_3_1_0_5_1_1 + 0.712500000000005*G0_0_1_3_1_1_0_0_0 + 0.712500000000005*G0_0_1_3_1_1_0_0_1 - 0.712500000000005*G0_0_1_3_1_1_1_0_0 - 0.712500000000005*G0_0_1_3_1_1_2_0_1 + 0.712500000000005*G0_0_1_3_1_1_3_1_0 + 0.712500000000005*G0_0_1_3_1_1_3_1_1 - 0.712500000000005*G0_0_1_3_1_1_4_1_0 - 0.712500000000005*G0_0_1_3_1_1_5_1_1 - 0.712500000000005*G0_0_1_4_1_0_0_0_0 - 0.712500000000005*G0_0_1_4_1_0_0_0_1 + 0.712500000000005*G0_0_1_4_1_0_1_0_0 + 0.712500000000005*G0_0_1_4_1_0_2_0_1 - 0.712500000000005*G0_0_1_4_1_0_3_1_0 - 0.712500000000005*G0_0_1_4_1_0_3_1_1 + 0.712500000000005*G0_0_1_4_1_0_4_1_0 + 0.712500000000005*G0_0_1_4_1_0_5_1_1 - 0.712500000000005*G0_0_1_5_1_1_0_0_0 - 0.712500000000005*G0_0_1_5_1_1_0_0_1 + 0.712500000000005*G0_0_1_5_1_1_1_0_0 + 0.712500000000005*G0_0_1_5_1_1_2_0_1 - 0.712500000000005*G0_0_1_5_1_1_3_1_0 - 0.712500000000005*G0_0_1_5_1_1_3_1_1 + 0.712500000000005*G0_0_1_5_1_1_4_1_0 + 0.712500000000005*G0_0_1_5_1_1_5_1_1; + A[244] = 0.0; + A[309] = 0.0; + A[269] = 0.0; + A[75] = 0.0; + A[23] = -A[235] + 0.712500000000004*G0_0_1_0_0_0_0_0_0 + 0.712500000000004*G0_0_1_0_0_0_0_0_1 - 0.712500000000004*G0_0_1_0_0_0_1_0_0 - 0.712500000000004*G0_0_1_0_0_0_2_0_1 + 0.712500000000004*G0_0_1_0_0_0_3_1_0 + 0.712500000000004*G0_0_1_0_0_0_3_1_1 - 0.712500000000004*G0_0_1_0_0_0_4_1_0 - 0.712500000000004*G0_0_1_0_0_0_5_1_1 + 0.712500000000004*G0_0_1_0_0_1_0_0_0 + 0.712500000000004*G0_0_1_0_0_1_0_0_1 - 0.712500000000004*G0_0_1_0_0_1_1_0_0 - 0.712500000000004*G0_0_1_0_0_1_2_0_1 + 0.712500000000004*G0_0_1_0_0_1_3_1_0 + 0.712500000000004*G0_0_1_0_0_1_3_1_1 - 0.712500000000004*G0_0_1_0_0_1_4_1_0 - 0.712500000000004*G0_0_1_0_0_1_5_1_1 - 0.712500000000004*G0_0_1_1_0_0_0_0_0 - 0.712500000000004*G0_0_1_1_0_0_0_0_1 + 0.712500000000004*G0_0_1_1_0_0_1_0_0 + 0.712500000000004*G0_0_1_1_0_0_2_0_1 - 0.712500000000004*G0_0_1_1_0_0_3_1_0 - 0.712500000000004*G0_0_1_1_0_0_3_1_1 + 0.712500000000004*G0_0_1_1_0_0_4_1_0 + 0.712500000000004*G0_0_1_1_0_0_5_1_1 - 0.712500000000004*G0_0_1_2_0_1_0_0_0 - 0.712500000000004*G0_0_1_2_0_1_0_0_1 + 0.712500000000004*G0_0_1_2_0_1_1_0_0 + 0.712500000000004*G0_0_1_2_0_1_2_0_1 - 0.712500000000004*G0_0_1_2_0_1_3_1_0 - 0.712500000000004*G0_0_1_2_0_1_3_1_1 + 0.712500000000004*G0_0_1_2_0_1_4_1_0 + 0.712500000000004*G0_0_1_2_0_1_5_1_1 + 0.712500000000004*G0_0_1_3_1_0_0_0_0 + 0.712500000000004*G0_0_1_3_1_0_0_0_1 - 0.712500000000004*G0_0_1_3_1_0_1_0_0 - 0.712500000000004*G0_0_1_3_1_0_2_0_1 + 0.712500000000004*G0_0_1_3_1_0_3_1_0 + 0.712500000000004*G0_0_1_3_1_0_3_1_1 - 0.712500000000004*G0_0_1_3_1_0_4_1_0 - 0.712500000000004*G0_0_1_3_1_0_5_1_1 + 0.712500000000004*G0_0_1_3_1_1_0_0_0 + 0.712500000000004*G0_0_1_3_1_1_0_0_1 - 0.712500000000004*G0_0_1_3_1_1_1_0_0 - 0.712500000000004*G0_0_1_3_1_1_2_0_1 + 0.712500000000004*G0_0_1_3_1_1_3_1_0 + 0.712500000000004*G0_0_1_3_1_1_3_1_1 - 0.712500000000004*G0_0_1_3_1_1_4_1_0 - 0.712500000000004*G0_0_1_3_1_1_5_1_1 - 0.712500000000004*G0_0_1_4_1_0_0_0_0 - 0.712500000000004*G0_0_1_4_1_0_0_0_1 + 0.712500000000004*G0_0_1_4_1_0_1_0_0 + 0.712500000000004*G0_0_1_4_1_0_2_0_1 - 0.712500000000004*G0_0_1_4_1_0_3_1_0 - 0.712500000000004*G0_0_1_4_1_0_3_1_1 + 0.712500000000004*G0_0_1_4_1_0_4_1_0 + 0.712500000000004*G0_0_1_4_1_0_5_1_1 - 0.712500000000004*G0_0_1_5_1_1_0_0_0 - 0.712500000000004*G0_0_1_5_1_1_0_0_1 + 0.712500000000004*G0_0_1_5_1_1_1_0_0 + 0.712500000000004*G0_0_1_5_1_1_2_0_1 - 0.712500000000004*G0_0_1_5_1_1_3_1_0 - 0.712500000000004*G0_0_1_5_1_1_3_1_1 + 0.712500000000004*G0_0_1_5_1_1_4_1_0 + 0.712500000000004*G0_0_1_5_1_1_5_1_1; + A[88] = A[143]; + A[48] = A[257]; + A[113] = 0.0; + A[122] = -A[292] - 0.637500000000002*G0_1_1_0_0_0_0_0_0 - 0.637500000000002*G0_1_1_0_0_0_0_0_1 + 0.637500000000002*G0_1_1_0_0_0_1_0_0 + 0.637500000000002*G0_1_1_0_0_0_2_0_1 - 0.637500000000002*G0_1_1_0_0_0_3_1_0 - 0.637500000000002*G0_1_1_0_0_0_3_1_1 + 0.637500000000002*G0_1_1_0_0_0_4_1_0 + 0.637500000000002*G0_1_1_0_0_0_5_1_1 - 0.637500000000002*G0_1_1_0_0_1_0_0_0 - 0.637500000000002*G0_1_1_0_0_1_0_0_1 + 0.637500000000002*G0_1_1_0_0_1_1_0_0 + 0.637500000000002*G0_1_1_0_0_1_2_0_1 - 0.637500000000002*G0_1_1_0_0_1_3_1_0 - 0.637500000000002*G0_1_1_0_0_1_3_1_1 + 0.637500000000002*G0_1_1_0_0_1_4_1_0 + 0.637500000000002*G0_1_1_0_0_1_5_1_1 + 0.637500000000002*G0_1_1_1_0_0_0_0_0 + 0.637500000000002*G0_1_1_1_0_0_0_0_1 - 0.637500000000002*G0_1_1_1_0_0_1_0_0 - 0.637500000000002*G0_1_1_1_0_0_2_0_1 + 0.637500000000002*G0_1_1_1_0_0_3_1_0 + 0.637500000000002*G0_1_1_1_0_0_3_1_1 - 0.637500000000002*G0_1_1_1_0_0_4_1_0 - 0.637500000000002*G0_1_1_1_0_0_5_1_1 + 0.637500000000002*G0_1_1_2_0_1_0_0_0 + 0.637500000000002*G0_1_1_2_0_1_0_0_1 - 0.637500000000002*G0_1_1_2_0_1_1_0_0 - 0.637500000000002*G0_1_1_2_0_1_2_0_1 + 0.637500000000002*G0_1_1_2_0_1_3_1_0 + 0.637500000000002*G0_1_1_2_0_1_3_1_1 - 0.637500000000002*G0_1_1_2_0_1_4_1_0 - 0.637500000000002*G0_1_1_2_0_1_5_1_1 - 0.637500000000002*G0_1_1_3_1_0_0_0_0 - 0.637500000000002*G0_1_1_3_1_0_0_0_1 + 0.637500000000002*G0_1_1_3_1_0_1_0_0 + 0.637500000000002*G0_1_1_3_1_0_2_0_1 - 0.637500000000002*G0_1_1_3_1_0_3_1_0 - 0.637500000000002*G0_1_1_3_1_0_3_1_1 + 0.637500000000002*G0_1_1_3_1_0_4_1_0 + 0.637500000000002*G0_1_1_3_1_0_5_1_1 - 0.637500000000002*G0_1_1_3_1_1_0_0_0 - 0.637500000000002*G0_1_1_3_1_1_0_0_1 + 0.637500000000002*G0_1_1_3_1_1_1_0_0 + 0.637500000000002*G0_1_1_3_1_1_2_0_1 - 0.637500000000002*G0_1_1_3_1_1_3_1_0 - 0.637500000000002*G0_1_1_3_1_1_3_1_1 + 0.637500000000002*G0_1_1_3_1_1_4_1_0 + 0.637500000000002*G0_1_1_3_1_1_5_1_1 + 0.637500000000002*G0_1_1_4_1_0_0_0_0 + 0.637500000000002*G0_1_1_4_1_0_0_0_1 - 0.637500000000002*G0_1_1_4_1_0_1_0_0 - 0.637500000000002*G0_1_1_4_1_0_2_0_1 + 0.637500000000002*G0_1_1_4_1_0_3_1_0 + 0.637500000000002*G0_1_1_4_1_0_3_1_1 - 0.637500000000002*G0_1_1_4_1_0_4_1_0 - 0.637500000000002*G0_1_1_4_1_0_5_1_1 + 0.637500000000002*G0_1_1_5_1_1_0_0_0 + 0.637500000000002*G0_1_1_5_1_1_0_0_1 - 0.637500000000002*G0_1_1_5_1_1_1_0_0 - 0.637500000000002*G0_1_1_5_1_1_2_0_1 + 0.637500000000002*G0_1_1_5_1_1_3_1_0 + 0.637500000000002*G0_1_1_5_1_1_3_1_1 - 0.637500000000002*G0_1_1_5_1_1_4_1_0 - 0.637500000000002*G0_1_1_5_1_1_5_1_1; + A[151] = 0.0; + A[361] = 0.0; + A[337] = A[165]; + A[243] = 0.0; + A[262] = 0.0; + A[24] = -A[235] - 0.3*G0_0_1_0_0_0_0_0_0 - 0.3*G0_0_1_0_0_0_0_0_1 + 0.3*G0_0_1_0_0_0_1_0_0 + 0.3*G0_0_1_0_0_0_2_0_1 - 0.3*G0_0_1_0_0_0_3_1_0 - 0.3*G0_0_1_0_0_0_3_1_1 + 0.3*G0_0_1_0_0_0_4_1_0 + 0.3*G0_0_1_0_0_0_5_1_1 - 0.3*G0_0_1_0_0_1_0_0_0 - 0.3*G0_0_1_0_0_1_0_0_1 + 0.3*G0_0_1_0_0_1_1_0_0 + 0.3*G0_0_1_0_0_1_2_0_1 - 0.3*G0_0_1_0_0_1_3_1_0 - 0.3*G0_0_1_0_0_1_3_1_1 + 0.3*G0_0_1_0_0_1_4_1_0 + 0.3*G0_0_1_0_0_1_5_1_1 + 0.3*G0_0_1_1_0_0_0_0_0 + 0.3*G0_0_1_1_0_0_0_0_1 - 0.3*G0_0_1_1_0_0_1_0_0 - 0.3*G0_0_1_1_0_0_2_0_1 + 0.3*G0_0_1_1_0_0_3_1_0 + 0.3*G0_0_1_1_0_0_3_1_1 - 0.3*G0_0_1_1_0_0_4_1_0 - 0.3*G0_0_1_1_0_0_5_1_1 + 0.3*G0_0_1_2_0_1_0_0_0 + 0.3*G0_0_1_2_0_1_0_0_1 - 0.3*G0_0_1_2_0_1_1_0_0 - 0.3*G0_0_1_2_0_1_2_0_1 + 0.3*G0_0_1_2_0_1_3_1_0 + 0.3*G0_0_1_2_0_1_3_1_1 - 0.3*G0_0_1_2_0_1_4_1_0 - 0.3*G0_0_1_2_0_1_5_1_1 - 0.3*G0_0_1_3_1_0_0_0_0 - 0.3*G0_0_1_3_1_0_0_0_1 + 0.3*G0_0_1_3_1_0_1_0_0 + 0.3*G0_0_1_3_1_0_2_0_1 - 0.3*G0_0_1_3_1_0_3_1_0 - 0.3*G0_0_1_3_1_0_3_1_1 + 0.3*G0_0_1_3_1_0_4_1_0 + 0.3*G0_0_1_3_1_0_5_1_1 - 0.3*G0_0_1_3_1_1_0_0_0 - 0.3*G0_0_1_3_1_1_0_0_1 + 0.3*G0_0_1_3_1_1_1_0_0 + 0.3*G0_0_1_3_1_1_2_0_1 - 0.3*G0_0_1_3_1_1_3_1_0 - 0.3*G0_0_1_3_1_1_3_1_1 + 0.3*G0_0_1_3_1_1_4_1_0 + 0.3*G0_0_1_3_1_1_5_1_1 + 0.3*G0_0_1_4_1_0_0_0_0 + 0.3*G0_0_1_4_1_0_0_0_1 - 0.3*G0_0_1_4_1_0_1_0_0 - 0.3*G0_0_1_4_1_0_2_0_1 + 0.3*G0_0_1_4_1_0_3_1_0 + 0.3*G0_0_1_4_1_0_3_1_1 - 0.3*G0_0_1_4_1_0_4_1_0 - 0.3*G0_0_1_4_1_0_5_1_1 + 0.3*G0_0_1_5_1_1_0_0_0 + 0.3*G0_0_1_5_1_1_0_0_1 - 0.3*G0_0_1_5_1_1_1_0_0 - 0.3*G0_0_1_5_1_1_2_0_1 + 0.3*G0_0_1_5_1_1_3_1_0 + 0.3*G0_0_1_5_1_1_3_1_1 - 0.3*G0_0_1_5_1_1_4_1_0 - 0.3*G0_0_1_5_1_1_5_1_1; + A[43] = A[253]; + A[125] = -A[85] - 1.0125*G0_1_0_0_0_0_0_0_0 - 1.0125*G0_1_0_0_0_0_0_0_1 + 1.0125*G0_1_0_0_0_0_1_0_0 + 1.0125*G0_1_0_0_0_0_2_0_1 - 1.0125*G0_1_0_0_0_0_3_1_0 - 1.0125*G0_1_0_0_0_0_3_1_1 + 1.0125*G0_1_0_0_0_0_4_1_0 + 1.0125*G0_1_0_0_0_0_5_1_1 - 1.0125*G0_1_0_0_0_1_0_0_0 - 1.0125*G0_1_0_0_0_1_0_0_1 + 1.0125*G0_1_0_0_0_1_1_0_0 + 1.0125*G0_1_0_0_0_1_2_0_1 - 1.0125*G0_1_0_0_0_1_3_1_0 - 1.0125*G0_1_0_0_0_1_3_1_1 + 1.0125*G0_1_0_0_0_1_4_1_0 + 1.0125*G0_1_0_0_0_1_5_1_1 + 1.0125*G0_1_0_1_0_0_0_0_0 + 1.0125*G0_1_0_1_0_0_0_0_1 - 1.0125*G0_1_0_1_0_0_1_0_0 - 1.0125*G0_1_0_1_0_0_2_0_1 + 1.0125*G0_1_0_1_0_0_3_1_0 + 1.0125*G0_1_0_1_0_0_3_1_1 - 1.0125*G0_1_0_1_0_0_4_1_0 - 1.0125*G0_1_0_1_0_0_5_1_1 + 1.0125*G0_1_0_2_0_1_0_0_0 + 1.0125*G0_1_0_2_0_1_0_0_1 - 1.0125*G0_1_0_2_0_1_1_0_0 - 1.0125*G0_1_0_2_0_1_2_0_1 + 1.0125*G0_1_0_2_0_1_3_1_0 + 1.0125*G0_1_0_2_0_1_3_1_1 - 1.0125*G0_1_0_2_0_1_4_1_0 - 1.0125*G0_1_0_2_0_1_5_1_1 - 1.0125*G0_1_0_3_1_0_0_0_0 - 1.0125*G0_1_0_3_1_0_0_0_1 + 1.0125*G0_1_0_3_1_0_1_0_0 + 1.0125*G0_1_0_3_1_0_2_0_1 - 1.0125*G0_1_0_3_1_0_3_1_0 - 1.0125*G0_1_0_3_1_0_3_1_1 + 1.0125*G0_1_0_3_1_0_4_1_0 + 1.0125*G0_1_0_3_1_0_5_1_1 - 1.0125*G0_1_0_3_1_1_0_0_0 - 1.0125*G0_1_0_3_1_1_0_0_1 + 1.0125*G0_1_0_3_1_1_1_0_0 + 1.0125*G0_1_0_3_1_1_2_0_1 - 1.0125*G0_1_0_3_1_1_3_1_0 - 1.0125*G0_1_0_3_1_1_3_1_1 + 1.0125*G0_1_0_3_1_1_4_1_0 + 1.0125*G0_1_0_3_1_1_5_1_1 + 1.0125*G0_1_0_4_1_0_0_0_0 + 1.0125*G0_1_0_4_1_0_0_0_1 - 1.0125*G0_1_0_4_1_0_1_0_0 - 1.0125*G0_1_0_4_1_0_2_0_1 + 1.0125*G0_1_0_4_1_0_3_1_0 + 1.0125*G0_1_0_4_1_0_3_1_1 - 1.0125*G0_1_0_4_1_0_4_1_0 - 1.0125*G0_1_0_4_1_0_5_1_1 + 1.0125*G0_1_0_5_1_1_0_0_0 + 1.0125*G0_1_0_5_1_1_0_0_1 - 1.0125*G0_1_0_5_1_1_1_0_0 - 1.0125*G0_1_0_5_1_1_2_0_1 + 1.0125*G0_1_0_5_1_1_3_1_0 + 1.0125*G0_1_0_5_1_1_3_1_1 - 1.0125*G0_1_0_5_1_1_4_1_0 - 1.0125*G0_1_0_5_1_1_5_1_1 - 1.35*G0_1_1_0_0_0_0_0_0 - 1.35*G0_1_1_0_0_0_0_0_1 + 1.35*G0_1_1_0_0_0_1_0_0 + 1.35*G0_1_1_0_0_0_2_0_1 - 1.35*G0_1_1_0_0_0_3_1_0 - 1.35*G0_1_1_0_0_0_3_1_1 + 1.35*G0_1_1_0_0_0_4_1_0 + 1.35*G0_1_1_0_0_0_5_1_1 - 1.35*G0_1_1_0_0_1_0_0_0 - 1.35*G0_1_1_0_0_1_0_0_1 + 1.35*G0_1_1_0_0_1_1_0_0 + 1.35*G0_1_1_0_0_1_2_0_1 - 1.35*G0_1_1_0_0_1_3_1_0 - 1.35*G0_1_1_0_0_1_3_1_1 + 1.35*G0_1_1_0_0_1_4_1_0 + 1.35*G0_1_1_0_0_1_5_1_1 + 1.35*G0_1_1_1_0_0_0_0_0 + 1.35*G0_1_1_1_0_0_0_0_1 - 1.35*G0_1_1_1_0_0_1_0_0 - 1.35*G0_1_1_1_0_0_2_0_1 + 1.35*G0_1_1_1_0_0_3_1_0 + 1.35*G0_1_1_1_0_0_3_1_1 - 1.35*G0_1_1_1_0_0_4_1_0 - 1.35*G0_1_1_1_0_0_5_1_1 + 1.35*G0_1_1_2_0_1_0_0_0 + 1.35*G0_1_1_2_0_1_0_0_1 - 1.35*G0_1_1_2_0_1_1_0_0 - 1.35*G0_1_1_2_0_1_2_0_1 + 1.35*G0_1_1_2_0_1_3_1_0 + 1.35*G0_1_1_2_0_1_3_1_1 - 1.35*G0_1_1_2_0_1_4_1_0 - 1.35*G0_1_1_2_0_1_5_1_1 - 1.35*G0_1_1_3_1_0_0_0_0 - 1.35*G0_1_1_3_1_0_0_0_1 + 1.35*G0_1_1_3_1_0_1_0_0 + 1.35*G0_1_1_3_1_0_2_0_1 - 1.35*G0_1_1_3_1_0_3_1_0 - 1.35*G0_1_1_3_1_0_3_1_1 + 1.35*G0_1_1_3_1_0_4_1_0 + 1.35*G0_1_1_3_1_0_5_1_1 - 1.35*G0_1_1_3_1_1_0_0_0 - 1.35*G0_1_1_3_1_1_0_0_1 + 1.35*G0_1_1_3_1_1_1_0_0 + 1.35*G0_1_1_3_1_1_2_0_1 - 1.35*G0_1_1_3_1_1_3_1_0 - 1.35*G0_1_1_3_1_1_3_1_1 + 1.35*G0_1_1_3_1_1_4_1_0 + 1.35*G0_1_1_3_1_1_5_1_1 + 1.35*G0_1_1_4_1_0_0_0_0 + 1.35*G0_1_1_4_1_0_0_0_1 - 1.35*G0_1_1_4_1_0_1_0_0 - 1.35*G0_1_1_4_1_0_2_0_1 + 1.35*G0_1_1_4_1_0_3_1_0 + 1.35*G0_1_1_4_1_0_3_1_1 - 1.35*G0_1_1_4_1_0_4_1_0 - 1.35*G0_1_1_4_1_0_5_1_1 + 1.35*G0_1_1_5_1_1_0_0_0 + 1.35*G0_1_1_5_1_1_0_0_1 - 1.35*G0_1_1_5_1_1_1_0_0 - 1.35*G0_1_1_5_1_1_2_0_1 + 1.35*G0_1_1_5_1_1_3_1_0 + 1.35*G0_1_1_5_1_1_3_1_1 - 1.35*G0_1_1_5_1_1_4_1_0 - 1.35*G0_1_1_5_1_1_5_1_1; + A[140] = A[350]; + A[116] = 0.0; + A[328] = 0.0; + A[385] = 0.0; + A[378] = A[273]; + A[164] = A[143]; + A[181] = 0.0; + A[206] = 0.0; + A[16] = 0.0; + A[280] = 0.0; + A[305] = 0.0; + A[63] = A[273]; + A[84] = A[273]; + A[335] = A[125]; + A[390] = 0.0; + A[354] = A[143]; + A[373] = A[278]; + A[171] = 0.0; + A[190] = 0.0; + A[201] = 0.0; + A[177] = 0.0; + A[232] = 0.0874999999999997*G0_0_1_0_0_0_0_0_0 + 0.0874999999999997*G0_0_1_0_0_0_0_0_1 - 0.0874999999999997*G0_0_1_0_0_0_1_0_0 - 0.0874999999999997*G0_0_1_0_0_0_2_0_1 + 0.0874999999999997*G0_0_1_0_0_0_3_1_0 + 0.0874999999999997*G0_0_1_0_0_0_3_1_1 - 0.0874999999999997*G0_0_1_0_0_0_4_1_0 - 0.0874999999999997*G0_0_1_0_0_0_5_1_1 + 0.0874999999999997*G0_0_1_0_0_1_0_0_0 + 0.0874999999999997*G0_0_1_0_0_1_0_0_1 - 0.0874999999999997*G0_0_1_0_0_1_1_0_0 - 0.0874999999999997*G0_0_1_0_0_1_2_0_1 + 0.0874999999999997*G0_0_1_0_0_1_3_1_0 + 0.0874999999999997*G0_0_1_0_0_1_3_1_1 - 0.0874999999999997*G0_0_1_0_0_1_4_1_0 - 0.0874999999999997*G0_0_1_0_0_1_5_1_1 - 0.0874999999999997*G0_0_1_1_0_0_0_0_0 - 0.0874999999999997*G0_0_1_1_0_0_0_0_1 + 0.0874999999999997*G0_0_1_1_0_0_1_0_0 + 0.0874999999999997*G0_0_1_1_0_0_2_0_1 - 0.0874999999999997*G0_0_1_1_0_0_3_1_0 - 0.0874999999999997*G0_0_1_1_0_0_3_1_1 + 0.0874999999999997*G0_0_1_1_0_0_4_1_0 + 0.0874999999999997*G0_0_1_1_0_0_5_1_1 - 0.0874999999999997*G0_0_1_2_0_1_0_0_0 - 0.0874999999999997*G0_0_1_2_0_1_0_0_1 + 0.0874999999999997*G0_0_1_2_0_1_1_0_0 + 0.0874999999999997*G0_0_1_2_0_1_2_0_1 - 0.0874999999999997*G0_0_1_2_0_1_3_1_0 - 0.0874999999999997*G0_0_1_2_0_1_3_1_1 + 0.0874999999999997*G0_0_1_2_0_1_4_1_0 + 0.0874999999999997*G0_0_1_2_0_1_5_1_1 + 0.0874999999999997*G0_0_1_3_1_0_0_0_0 + 0.0874999999999997*G0_0_1_3_1_0_0_0_1 - 0.0874999999999997*G0_0_1_3_1_0_1_0_0 - 0.0874999999999997*G0_0_1_3_1_0_2_0_1 + 0.0874999999999997*G0_0_1_3_1_0_3_1_0 + 0.0874999999999997*G0_0_1_3_1_0_3_1_1 - 0.0874999999999997*G0_0_1_3_1_0_4_1_0 - 0.0874999999999997*G0_0_1_3_1_0_5_1_1 + 0.0874999999999997*G0_0_1_3_1_1_0_0_0 + 0.0874999999999997*G0_0_1_3_1_1_0_0_1 - 0.0874999999999997*G0_0_1_3_1_1_1_0_0 - 0.0874999999999997*G0_0_1_3_1_1_2_0_1 + 0.0874999999999997*G0_0_1_3_1_1_3_1_0 + 0.0874999999999997*G0_0_1_3_1_1_3_1_1 - 0.0874999999999997*G0_0_1_3_1_1_4_1_0 - 0.0874999999999997*G0_0_1_3_1_1_5_1_1 - 0.0874999999999997*G0_0_1_4_1_0_0_0_0 - 0.0874999999999997*G0_0_1_4_1_0_0_0_1 + 0.0874999999999997*G0_0_1_4_1_0_1_0_0 + 0.0874999999999997*G0_0_1_4_1_0_2_0_1 - 0.0874999999999997*G0_0_1_4_1_0_3_1_0 - 0.0874999999999997*G0_0_1_4_1_0_3_1_1 + 0.0874999999999997*G0_0_1_4_1_0_4_1_0 + 0.0874999999999997*G0_0_1_4_1_0_5_1_1 - 0.0874999999999997*G0_0_1_5_1_1_0_0_0 - 0.0874999999999997*G0_0_1_5_1_1_0_0_1 + 0.0874999999999997*G0_0_1_5_1_1_1_0_0 + 0.0874999999999997*G0_0_1_5_1_1_2_0_1 - 0.0874999999999997*G0_0_1_5_1_1_3_1_0 - 0.0874999999999997*G0_0_1_5_1_1_3_1_1 + 0.0874999999999997*G0_0_1_5_1_1_4_1_0 + 0.0874999999999997*G0_0_1_5_1_1_5_1_1; + A[20] = -A[232] - 0.0875000000000007*G0_0_0_0_0_0_0_0_0 - 0.0875000000000007*G0_0_0_0_0_0_0_0_1 + 0.0875000000000007*G0_0_0_0_0_0_1_0_0 + 0.0875000000000007*G0_0_0_0_0_0_2_0_1 - 0.0875000000000007*G0_0_0_0_0_0_3_1_0 - 0.0875000000000007*G0_0_0_0_0_0_3_1_1 + 0.0875000000000007*G0_0_0_0_0_0_4_1_0 + 0.0875000000000007*G0_0_0_0_0_0_5_1_1 - 0.0875000000000007*G0_0_0_0_0_1_0_0_0 - 0.0875000000000007*G0_0_0_0_0_1_0_0_1 + 0.0875000000000007*G0_0_0_0_0_1_1_0_0 + 0.0875000000000007*G0_0_0_0_0_1_2_0_1 - 0.0875000000000007*G0_0_0_0_0_1_3_1_0 - 0.0875000000000007*G0_0_0_0_0_1_3_1_1 + 0.0875000000000007*G0_0_0_0_0_1_4_1_0 + 0.0875000000000007*G0_0_0_0_0_1_5_1_1 + 0.0875000000000007*G0_0_0_1_0_0_0_0_0 + 0.0875000000000007*G0_0_0_1_0_0_0_0_1 - 0.0875000000000007*G0_0_0_1_0_0_1_0_0 - 0.0875000000000007*G0_0_0_1_0_0_2_0_1 + 0.0875000000000007*G0_0_0_1_0_0_3_1_0 + 0.0875000000000007*G0_0_0_1_0_0_3_1_1 - 0.0875000000000007*G0_0_0_1_0_0_4_1_0 - 0.0875000000000007*G0_0_0_1_0_0_5_1_1 + 0.0875000000000007*G0_0_0_2_0_1_0_0_0 + 0.0875000000000007*G0_0_0_2_0_1_0_0_1 - 0.0875000000000007*G0_0_0_2_0_1_1_0_0 - 0.0875000000000007*G0_0_0_2_0_1_2_0_1 + 0.0875000000000007*G0_0_0_2_0_1_3_1_0 + 0.0875000000000007*G0_0_0_2_0_1_3_1_1 - 0.0875000000000007*G0_0_0_2_0_1_4_1_0 - 0.0875000000000007*G0_0_0_2_0_1_5_1_1 - 0.0875000000000007*G0_0_0_3_1_0_0_0_0 - 0.0875000000000007*G0_0_0_3_1_0_0_0_1 + 0.0875000000000007*G0_0_0_3_1_0_1_0_0 + 0.0875000000000007*G0_0_0_3_1_0_2_0_1 - 0.0875000000000007*G0_0_0_3_1_0_3_1_0 - 0.0875000000000007*G0_0_0_3_1_0_3_1_1 + 0.0875000000000007*G0_0_0_3_1_0_4_1_0 + 0.0875000000000007*G0_0_0_3_1_0_5_1_1 - 0.0875000000000007*G0_0_0_3_1_1_0_0_0 - 0.0875000000000007*G0_0_0_3_1_1_0_0_1 + 0.0875000000000007*G0_0_0_3_1_1_1_0_0 + 0.0875000000000007*G0_0_0_3_1_1_2_0_1 - 0.0875000000000007*G0_0_0_3_1_1_3_1_0 - 0.0875000000000007*G0_0_0_3_1_1_3_1_1 + 0.0875000000000007*G0_0_0_3_1_1_4_1_0 + 0.0875000000000007*G0_0_0_3_1_1_5_1_1 + 0.0875000000000007*G0_0_0_4_1_0_0_0_0 + 0.0875000000000007*G0_0_0_4_1_0_0_0_1 - 0.0875000000000007*G0_0_0_4_1_0_1_0_0 - 0.0875000000000007*G0_0_0_4_1_0_2_0_1 + 0.0875000000000007*G0_0_0_4_1_0_3_1_0 + 0.0875000000000007*G0_0_0_4_1_0_3_1_1 - 0.0875000000000007*G0_0_0_4_1_0_4_1_0 - 0.0875000000000007*G0_0_0_4_1_0_5_1_1 + 0.0875000000000007*G0_0_0_5_1_1_0_0_0 + 0.0875000000000007*G0_0_0_5_1_1_0_0_1 - 0.0875000000000007*G0_0_0_5_1_1_1_0_0 - 0.0875000000000007*G0_0_0_5_1_1_2_0_1 + 0.0875000000000007*G0_0_0_5_1_1_3_1_0 + 0.0875000000000007*G0_0_0_5_1_1_3_1_1 - 0.0875000000000007*G0_0_0_5_1_1_4_1_0 - 0.0875000000000007*G0_0_0_5_1_1_5_1_1; + A[212] = -A[232] - 0.0875000000000007*G0_1_1_0_0_0_0_0_0 - 0.0875000000000007*G0_1_1_0_0_0_0_0_1 + 0.0875000000000007*G0_1_1_0_0_0_1_0_0 + 0.0875000000000007*G0_1_1_0_0_0_2_0_1 - 0.0875000000000007*G0_1_1_0_0_0_3_1_0 - 0.0875000000000007*G0_1_1_0_0_0_3_1_1 + 0.0875000000000007*G0_1_1_0_0_0_4_1_0 + 0.0875000000000007*G0_1_1_0_0_0_5_1_1 - 0.0875000000000007*G0_1_1_0_0_1_0_0_0 - 0.0875000000000007*G0_1_1_0_0_1_0_0_1 + 0.0875000000000007*G0_1_1_0_0_1_1_0_0 + 0.0875000000000007*G0_1_1_0_0_1_2_0_1 - 0.0875000000000007*G0_1_1_0_0_1_3_1_0 - 0.0875000000000007*G0_1_1_0_0_1_3_1_1 + 0.0875000000000007*G0_1_1_0_0_1_4_1_0 + 0.0875000000000007*G0_1_1_0_0_1_5_1_1 + 0.0875000000000007*G0_1_1_1_0_0_0_0_0 + 0.0875000000000007*G0_1_1_1_0_0_0_0_1 - 0.0875000000000007*G0_1_1_1_0_0_1_0_0 - 0.0875000000000007*G0_1_1_1_0_0_2_0_1 + 0.0875000000000007*G0_1_1_1_0_0_3_1_0 + 0.0875000000000007*G0_1_1_1_0_0_3_1_1 - 0.0875000000000007*G0_1_1_1_0_0_4_1_0 - 0.0875000000000007*G0_1_1_1_0_0_5_1_1 + 0.0875000000000007*G0_1_1_2_0_1_0_0_0 + 0.0875000000000007*G0_1_1_2_0_1_0_0_1 - 0.0875000000000007*G0_1_1_2_0_1_1_0_0 - 0.0875000000000007*G0_1_1_2_0_1_2_0_1 + 0.0875000000000007*G0_1_1_2_0_1_3_1_0 + 0.0875000000000007*G0_1_1_2_0_1_3_1_1 - 0.0875000000000007*G0_1_1_2_0_1_4_1_0 - 0.0875000000000007*G0_1_1_2_0_1_5_1_1 - 0.0875000000000007*G0_1_1_3_1_0_0_0_0 - 0.0875000000000007*G0_1_1_3_1_0_0_0_1 + 0.0875000000000007*G0_1_1_3_1_0_1_0_0 + 0.0875000000000007*G0_1_1_3_1_0_2_0_1 - 0.0875000000000007*G0_1_1_3_1_0_3_1_0 - 0.0875000000000007*G0_1_1_3_1_0_3_1_1 + 0.0875000000000007*G0_1_1_3_1_0_4_1_0 + 0.0875000000000007*G0_1_1_3_1_0_5_1_1 - 0.0875000000000007*G0_1_1_3_1_1_0_0_0 - 0.0875000000000007*G0_1_1_3_1_1_0_0_1 + 0.0875000000000007*G0_1_1_3_1_1_1_0_0 + 0.0875000000000007*G0_1_1_3_1_1_2_0_1 - 0.0875000000000007*G0_1_1_3_1_1_3_1_0 - 0.0875000000000007*G0_1_1_3_1_1_3_1_1 + 0.0875000000000007*G0_1_1_3_1_1_4_1_0 + 0.0875000000000007*G0_1_1_3_1_1_5_1_1 + 0.0875000000000007*G0_1_1_4_1_0_0_0_0 + 0.0875000000000007*G0_1_1_4_1_0_0_0_1 - 0.0875000000000007*G0_1_1_4_1_0_1_0_0 - 0.0875000000000007*G0_1_1_4_1_0_2_0_1 + 0.0875000000000007*G0_1_1_4_1_0_3_1_0 + 0.0875000000000007*G0_1_1_4_1_0_3_1_1 - 0.0875000000000007*G0_1_1_4_1_0_4_1_0 - 0.0875000000000007*G0_1_1_4_1_0_5_1_1 + 0.0875000000000007*G0_1_1_5_1_1_0_0_0 + 0.0875000000000007*G0_1_1_5_1_1_0_0_1 - 0.0875000000000007*G0_1_1_5_1_1_1_0_0 - 0.0875000000000007*G0_1_1_5_1_1_2_0_1 + 0.0875000000000007*G0_1_1_5_1_1_3_1_0 + 0.0875000000000007*G0_1_1_5_1_1_3_1_1 - 0.0875000000000007*G0_1_1_5_1_1_4_1_0 - 0.0875000000000007*G0_1_1_5_1_1_5_1_1; + A[230] = A[20]; + A[2] = A[212]; + A[291] = A[81]; + A[255] = A[45]; + A[302] = 0.0; + A[274] = A[64]; + A[13] = 0.0; + A[68] = A[278]; + A[28] = -A[23] - 0.637500000000002*G0_0_0_0_0_0_0_0_0 - 0.637500000000002*G0_0_0_0_0_0_0_0_1 + 0.637500000000002*G0_0_0_0_0_0_1_0_0 + 0.637500000000002*G0_0_0_0_0_0_2_0_1 - 0.637500000000002*G0_0_0_0_0_0_3_1_0 - 0.637500000000002*G0_0_0_0_0_0_3_1_1 + 0.637500000000002*G0_0_0_0_0_0_4_1_0 + 0.637500000000002*G0_0_0_0_0_0_5_1_1 - 0.637500000000002*G0_0_0_0_0_1_0_0_0 - 0.637500000000002*G0_0_0_0_0_1_0_0_1 + 0.637500000000002*G0_0_0_0_0_1_1_0_0 + 0.637500000000002*G0_0_0_0_0_1_2_0_1 - 0.637500000000002*G0_0_0_0_0_1_3_1_0 - 0.637500000000002*G0_0_0_0_0_1_3_1_1 + 0.637500000000002*G0_0_0_0_0_1_4_1_0 + 0.637500000000002*G0_0_0_0_0_1_5_1_1 + 0.637500000000002*G0_0_0_1_0_0_0_0_0 + 0.637500000000002*G0_0_0_1_0_0_0_0_1 - 0.637500000000002*G0_0_0_1_0_0_1_0_0 - 0.637500000000002*G0_0_0_1_0_0_2_0_1 + 0.637500000000002*G0_0_0_1_0_0_3_1_0 + 0.637500000000002*G0_0_0_1_0_0_3_1_1 - 0.637500000000002*G0_0_0_1_0_0_4_1_0 - 0.637500000000002*G0_0_0_1_0_0_5_1_1 + 0.637500000000002*G0_0_0_2_0_1_0_0_0 + 0.637500000000002*G0_0_0_2_0_1_0_0_1 - 0.637500000000002*G0_0_0_2_0_1_1_0_0 - 0.637500000000002*G0_0_0_2_0_1_2_0_1 + 0.637500000000002*G0_0_0_2_0_1_3_1_0 + 0.637500000000002*G0_0_0_2_0_1_3_1_1 - 0.637500000000002*G0_0_0_2_0_1_4_1_0 - 0.637500000000002*G0_0_0_2_0_1_5_1_1 - 0.637500000000002*G0_0_0_3_1_0_0_0_0 - 0.637500000000002*G0_0_0_3_1_0_0_0_1 + 0.637500000000002*G0_0_0_3_1_0_1_0_0 + 0.637500000000002*G0_0_0_3_1_0_2_0_1 - 0.637500000000002*G0_0_0_3_1_0_3_1_0 - 0.637500000000002*G0_0_0_3_1_0_3_1_1 + 0.637500000000002*G0_0_0_3_1_0_4_1_0 + 0.637500000000002*G0_0_0_3_1_0_5_1_1 - 0.637500000000002*G0_0_0_3_1_1_0_0_0 - 0.637500000000002*G0_0_0_3_1_1_0_0_1 + 0.637500000000002*G0_0_0_3_1_1_1_0_0 + 0.637500000000002*G0_0_0_3_1_1_2_0_1 - 0.637500000000002*G0_0_0_3_1_1_3_1_0 - 0.637500000000002*G0_0_0_3_1_1_3_1_1 + 0.637500000000002*G0_0_0_3_1_1_4_1_0 + 0.637500000000002*G0_0_0_3_1_1_5_1_1 + 0.637500000000002*G0_0_0_4_1_0_0_0_0 + 0.637500000000002*G0_0_0_4_1_0_0_0_1 - 0.637500000000002*G0_0_0_4_1_0_1_0_0 - 0.637500000000002*G0_0_0_4_1_0_2_0_1 + 0.637500000000002*G0_0_0_4_1_0_3_1_0 + 0.637500000000002*G0_0_0_4_1_0_3_1_1 - 0.637500000000002*G0_0_0_4_1_0_4_1_0 - 0.637500000000002*G0_0_0_4_1_0_5_1_1 + 0.637500000000002*G0_0_0_5_1_1_0_0_0 + 0.637500000000002*G0_0_0_5_1_1_0_0_1 - 0.637500000000002*G0_0_0_5_1_1_1_0_0 - 0.637500000000002*G0_0_0_5_1_1_2_0_1 + 0.637500000000002*G0_0_0_5_1_1_3_1_0 + 0.637500000000002*G0_0_0_5_1_1_3_1_1 - 0.637500000000002*G0_0_0_5_1_1_4_1_0 - 0.637500000000002*G0_0_0_5_1_1_5_1_1; + A[83] = -A[143] - 0.337499999999997*G0_0_0_0_0_0_0_0_0 - 0.337499999999997*G0_0_0_0_0_0_0_0_1 + 0.337499999999997*G0_0_0_0_0_0_1_0_0 + 0.337499999999997*G0_0_0_0_0_0_2_0_1 - 0.337499999999997*G0_0_0_0_0_0_3_1_0 - 0.337499999999997*G0_0_0_0_0_0_3_1_1 + 0.337499999999997*G0_0_0_0_0_0_4_1_0 + 0.337499999999997*G0_0_0_0_0_0_5_1_1 - 0.337499999999997*G0_0_0_0_0_1_0_0_0 - 0.337499999999997*G0_0_0_0_0_1_0_0_1 + 0.337499999999997*G0_0_0_0_0_1_1_0_0 + 0.337499999999997*G0_0_0_0_0_1_2_0_1 - 0.337499999999997*G0_0_0_0_0_1_3_1_0 - 0.337499999999997*G0_0_0_0_0_1_3_1_1 + 0.337499999999997*G0_0_0_0_0_1_4_1_0 + 0.337499999999997*G0_0_0_0_0_1_5_1_1 + 0.337499999999997*G0_0_0_1_0_0_0_0_0 + 0.337499999999997*G0_0_0_1_0_0_0_0_1 - 0.337499999999997*G0_0_0_1_0_0_1_0_0 - 0.337499999999997*G0_0_0_1_0_0_2_0_1 + 0.337499999999997*G0_0_0_1_0_0_3_1_0 + 0.337499999999997*G0_0_0_1_0_0_3_1_1 - 0.337499999999997*G0_0_0_1_0_0_4_1_0 - 0.337499999999997*G0_0_0_1_0_0_5_1_1 + 0.337499999999997*G0_0_0_2_0_1_0_0_0 + 0.337499999999997*G0_0_0_2_0_1_0_0_1 - 0.337499999999997*G0_0_0_2_0_1_1_0_0 - 0.337499999999997*G0_0_0_2_0_1_2_0_1 + 0.337499999999997*G0_0_0_2_0_1_3_1_0 + 0.337499999999997*G0_0_0_2_0_1_3_1_1 - 0.337499999999997*G0_0_0_2_0_1_4_1_0 - 0.337499999999997*G0_0_0_2_0_1_5_1_1 - 0.337499999999997*G0_0_0_3_1_0_0_0_0 - 0.337499999999997*G0_0_0_3_1_0_0_0_1 + 0.337499999999997*G0_0_0_3_1_0_1_0_0 + 0.337499999999997*G0_0_0_3_1_0_2_0_1 - 0.337499999999997*G0_0_0_3_1_0_3_1_0 - 0.337499999999997*G0_0_0_3_1_0_3_1_1 + 0.337499999999997*G0_0_0_3_1_0_4_1_0 + 0.337499999999997*G0_0_0_3_1_0_5_1_1 - 0.337499999999997*G0_0_0_3_1_1_0_0_0 - 0.337499999999997*G0_0_0_3_1_1_0_0_1 + 0.337499999999997*G0_0_0_3_1_1_1_0_0 + 0.337499999999997*G0_0_0_3_1_1_2_0_1 - 0.337499999999997*G0_0_0_3_1_1_3_1_0 - 0.337499999999997*G0_0_0_3_1_1_3_1_1 + 0.337499999999997*G0_0_0_3_1_1_4_1_0 + 0.337499999999997*G0_0_0_3_1_1_5_1_1 + 0.337499999999997*G0_0_0_4_1_0_0_0_0 + 0.337499999999997*G0_0_0_4_1_0_0_0_1 - 0.337499999999997*G0_0_0_4_1_0_1_0_0 - 0.337499999999997*G0_0_0_4_1_0_2_0_1 + 0.337499999999997*G0_0_0_4_1_0_3_1_0 + 0.337499999999997*G0_0_0_4_1_0_3_1_1 - 0.337499999999997*G0_0_0_4_1_0_4_1_0 - 0.337499999999997*G0_0_0_4_1_0_5_1_1 + 0.337499999999997*G0_0_0_5_1_1_0_0_0 + 0.337499999999997*G0_0_0_5_1_1_0_0_1 - 0.337499999999997*G0_0_0_5_1_1_1_0_0 - 0.337499999999997*G0_0_0_5_1_1_2_0_1 + 0.337499999999997*G0_0_0_5_1_1_3_1_0 + 0.337499999999997*G0_0_0_5_1_1_3_1_1 - 0.337499999999997*G0_0_0_5_1_1_4_1_0 - 0.337499999999997*G0_0_0_5_1_1_5_1_1 + 1.0125*G0_1_0_0_0_0_0_0_0 + 1.0125*G0_1_0_0_0_0_0_0_1 - 1.0125*G0_1_0_0_0_0_1_0_0 - 1.0125*G0_1_0_0_0_0_2_0_1 + 1.0125*G0_1_0_0_0_0_3_1_0 + 1.0125*G0_1_0_0_0_0_3_1_1 - 1.0125*G0_1_0_0_0_0_4_1_0 - 1.0125*G0_1_0_0_0_0_5_1_1 + 1.0125*G0_1_0_0_0_1_0_0_0 + 1.0125*G0_1_0_0_0_1_0_0_1 - 1.0125*G0_1_0_0_0_1_1_0_0 - 1.0125*G0_1_0_0_0_1_2_0_1 + 1.0125*G0_1_0_0_0_1_3_1_0 + 1.0125*G0_1_0_0_0_1_3_1_1 - 1.0125*G0_1_0_0_0_1_4_1_0 - 1.0125*G0_1_0_0_0_1_5_1_1 - 1.0125*G0_1_0_1_0_0_0_0_0 - 1.0125*G0_1_0_1_0_0_0_0_1 + 1.0125*G0_1_0_1_0_0_1_0_0 + 1.0125*G0_1_0_1_0_0_2_0_1 - 1.0125*G0_1_0_1_0_0_3_1_0 - 1.0125*G0_1_0_1_0_0_3_1_1 + 1.0125*G0_1_0_1_0_0_4_1_0 + 1.0125*G0_1_0_1_0_0_5_1_1 - 1.0125*G0_1_0_2_0_1_0_0_0 - 1.0125*G0_1_0_2_0_1_0_0_1 + 1.0125*G0_1_0_2_0_1_1_0_0 + 1.0125*G0_1_0_2_0_1_2_0_1 - 1.0125*G0_1_0_2_0_1_3_1_0 - 1.0125*G0_1_0_2_0_1_3_1_1 + 1.0125*G0_1_0_2_0_1_4_1_0 + 1.0125*G0_1_0_2_0_1_5_1_1 + 1.0125*G0_1_0_3_1_0_0_0_0 + 1.0125*G0_1_0_3_1_0_0_0_1 - 1.0125*G0_1_0_3_1_0_1_0_0 - 1.0125*G0_1_0_3_1_0_2_0_1 + 1.0125*G0_1_0_3_1_0_3_1_0 + 1.0125*G0_1_0_3_1_0_3_1_1 - 1.0125*G0_1_0_3_1_0_4_1_0 - 1.0125*G0_1_0_3_1_0_5_1_1 + 1.0125*G0_1_0_3_1_1_0_0_0 + 1.0125*G0_1_0_3_1_1_0_0_1 - 1.0125*G0_1_0_3_1_1_1_0_0 - 1.0125*G0_1_0_3_1_1_2_0_1 + 1.0125*G0_1_0_3_1_1_3_1_0 + 1.0125*G0_1_0_3_1_1_3_1_1 - 1.0125*G0_1_0_3_1_1_4_1_0 - 1.0125*G0_1_0_3_1_1_5_1_1 - 1.0125*G0_1_0_4_1_0_0_0_0 - 1.0125*G0_1_0_4_1_0_0_0_1 + 1.0125*G0_1_0_4_1_0_1_0_0 + 1.0125*G0_1_0_4_1_0_2_0_1 - 1.0125*G0_1_0_4_1_0_3_1_0 - 1.0125*G0_1_0_4_1_0_3_1_1 + 1.0125*G0_1_0_4_1_0_4_1_0 + 1.0125*G0_1_0_4_1_0_5_1_1 - 1.0125*G0_1_0_5_1_1_0_0_0 - 1.0125*G0_1_0_5_1_1_0_0_1 + 1.0125*G0_1_0_5_1_1_1_0_0 + 1.0125*G0_1_0_5_1_1_2_0_1 - 1.0125*G0_1_0_5_1_1_3_1_0 - 1.0125*G0_1_0_5_1_1_3_1_1 + 1.0125*G0_1_0_5_1_1_4_1_0 + 1.0125*G0_1_0_5_1_1_5_1_1; + A[55] = 0.0; + A[102] = -A[62] + 0.375000000000002*G0_1_1_0_0_0_0_0_0 + 0.375000000000002*G0_1_1_0_0_0_0_0_1 - 0.375000000000002*G0_1_1_0_0_0_1_0_0 - 0.375000000000002*G0_1_1_0_0_0_2_0_1 + 0.375000000000002*G0_1_1_0_0_0_3_1_0 + 0.375000000000002*G0_1_1_0_0_0_3_1_1 - 0.375000000000002*G0_1_1_0_0_0_4_1_0 - 0.375000000000002*G0_1_1_0_0_0_5_1_1 + 0.375000000000002*G0_1_1_0_0_1_0_0_0 + 0.375000000000002*G0_1_1_0_0_1_0_0_1 - 0.375000000000002*G0_1_1_0_0_1_1_0_0 - 0.375000000000002*G0_1_1_0_0_1_2_0_1 + 0.375000000000002*G0_1_1_0_0_1_3_1_0 + 0.375000000000002*G0_1_1_0_0_1_3_1_1 - 0.375000000000002*G0_1_1_0_0_1_4_1_0 - 0.375000000000002*G0_1_1_0_0_1_5_1_1 - 0.375000000000002*G0_1_1_1_0_0_0_0_0 - 0.375000000000002*G0_1_1_1_0_0_0_0_1 + 0.375000000000002*G0_1_1_1_0_0_1_0_0 + 0.375000000000002*G0_1_1_1_0_0_2_0_1 - 0.375000000000002*G0_1_1_1_0_0_3_1_0 - 0.375000000000002*G0_1_1_1_0_0_3_1_1 + 0.375000000000002*G0_1_1_1_0_0_4_1_0 + 0.375000000000002*G0_1_1_1_0_0_5_1_1 - 0.375000000000002*G0_1_1_2_0_1_0_0_0 - 0.375000000000002*G0_1_1_2_0_1_0_0_1 + 0.375000000000002*G0_1_1_2_0_1_1_0_0 + 0.375000000000002*G0_1_1_2_0_1_2_0_1 - 0.375000000000002*G0_1_1_2_0_1_3_1_0 - 0.375000000000002*G0_1_1_2_0_1_3_1_1 + 0.375000000000002*G0_1_1_2_0_1_4_1_0 + 0.375000000000002*G0_1_1_2_0_1_5_1_1 + 0.375000000000002*G0_1_1_3_1_0_0_0_0 + 0.375000000000002*G0_1_1_3_1_0_0_0_1 - 0.375000000000002*G0_1_1_3_1_0_1_0_0 - 0.375000000000002*G0_1_1_3_1_0_2_0_1 + 0.375000000000002*G0_1_1_3_1_0_3_1_0 + 0.375000000000002*G0_1_1_3_1_0_3_1_1 - 0.375000000000002*G0_1_1_3_1_0_4_1_0 - 0.375000000000002*G0_1_1_3_1_0_5_1_1 + 0.375000000000002*G0_1_1_3_1_1_0_0_0 + 0.375000000000002*G0_1_1_3_1_1_0_0_1 - 0.375000000000002*G0_1_1_3_1_1_1_0_0 - 0.375000000000002*G0_1_1_3_1_1_2_0_1 + 0.375000000000002*G0_1_1_3_1_1_3_1_0 + 0.375000000000002*G0_1_1_3_1_1_3_1_1 - 0.375000000000002*G0_1_1_3_1_1_4_1_0 - 0.375000000000002*G0_1_1_3_1_1_5_1_1 - 0.375000000000002*G0_1_1_4_1_0_0_0_0 - 0.375000000000002*G0_1_1_4_1_0_0_0_1 + 0.375000000000002*G0_1_1_4_1_0_1_0_0 + 0.375000000000002*G0_1_1_4_1_0_2_0_1 - 0.375000000000002*G0_1_1_4_1_0_3_1_0 - 0.375000000000002*G0_1_1_4_1_0_3_1_1 + 0.375000000000002*G0_1_1_4_1_0_4_1_0 + 0.375000000000002*G0_1_1_4_1_0_5_1_1 - 0.375000000000002*G0_1_1_5_1_1_0_0_0 - 0.375000000000002*G0_1_1_5_1_1_0_0_1 + 0.375000000000002*G0_1_1_5_1_1_1_0_0 + 0.375000000000002*G0_1_1_5_1_1_2_0_1 - 0.375000000000002*G0_1_1_5_1_1_3_1_0 - 0.375000000000002*G0_1_1_5_1_1_3_1_1 + 0.375000000000002*G0_1_1_5_1_1_4_1_0 + 0.375000000000002*G0_1_1_5_1_1_5_1_1; + A[326] = 0.0; + A[129] = A[379]; + A[399] = A[189]; + A[347] = 0.0; + A[152] = 0.0; + A[364] = 0.0; + A[208] = 0.0; + A[225] = 0.0; + A[298] = A[143]; + A[246] = 0.0; + A[218] = A[370] - 0.299999999999997*G0_0_1_0_0_0_0_0_0 - 0.299999999999997*G0_0_1_0_0_0_0_0_1 + 0.299999999999997*G0_0_1_0_0_0_1_0_0 + 0.299999999999997*G0_0_1_0_0_0_2_0_1 - 0.299999999999997*G0_0_1_0_0_0_3_1_0 - 0.299999999999997*G0_0_1_0_0_0_3_1_1 + 0.299999999999997*G0_0_1_0_0_0_4_1_0 + 0.299999999999997*G0_0_1_0_0_0_5_1_1 - 0.299999999999997*G0_0_1_0_0_1_0_0_0 - 0.299999999999997*G0_0_1_0_0_1_0_0_1 + 0.299999999999997*G0_0_1_0_0_1_1_0_0 + 0.299999999999997*G0_0_1_0_0_1_2_0_1 - 0.299999999999997*G0_0_1_0_0_1_3_1_0 - 0.299999999999997*G0_0_1_0_0_1_3_1_1 + 0.299999999999997*G0_0_1_0_0_1_4_1_0 + 0.299999999999997*G0_0_1_0_0_1_5_1_1 + 0.299999999999997*G0_0_1_1_0_0_0_0_0 + 0.299999999999997*G0_0_1_1_0_0_0_0_1 - 0.299999999999997*G0_0_1_1_0_0_1_0_0 - 0.299999999999997*G0_0_1_1_0_0_2_0_1 + 0.299999999999997*G0_0_1_1_0_0_3_1_0 + 0.299999999999997*G0_0_1_1_0_0_3_1_1 - 0.299999999999997*G0_0_1_1_0_0_4_1_0 - 0.299999999999997*G0_0_1_1_0_0_5_1_1 + 0.299999999999997*G0_0_1_2_0_1_0_0_0 + 0.299999999999997*G0_0_1_2_0_1_0_0_1 - 0.299999999999997*G0_0_1_2_0_1_1_0_0 - 0.299999999999997*G0_0_1_2_0_1_2_0_1 + 0.299999999999997*G0_0_1_2_0_1_3_1_0 + 0.299999999999997*G0_0_1_2_0_1_3_1_1 - 0.299999999999997*G0_0_1_2_0_1_4_1_0 - 0.299999999999997*G0_0_1_2_0_1_5_1_1 - 0.299999999999997*G0_0_1_3_1_0_0_0_0 - 0.299999999999997*G0_0_1_3_1_0_0_0_1 + 0.299999999999997*G0_0_1_3_1_0_1_0_0 + 0.299999999999997*G0_0_1_3_1_0_2_0_1 - 0.299999999999997*G0_0_1_3_1_0_3_1_0 - 0.299999999999997*G0_0_1_3_1_0_3_1_1 + 0.299999999999997*G0_0_1_3_1_0_4_1_0 + 0.299999999999997*G0_0_1_3_1_0_5_1_1 - 0.299999999999997*G0_0_1_3_1_1_0_0_0 - 0.299999999999997*G0_0_1_3_1_1_0_0_1 + 0.299999999999997*G0_0_1_3_1_1_1_0_0 + 0.299999999999997*G0_0_1_3_1_1_2_0_1 - 0.299999999999997*G0_0_1_3_1_1_3_1_0 - 0.299999999999997*G0_0_1_3_1_1_3_1_1 + 0.299999999999997*G0_0_1_3_1_1_4_1_0 + 0.299999999999997*G0_0_1_3_1_1_5_1_1 + 0.299999999999997*G0_0_1_4_1_0_0_0_0 + 0.299999999999997*G0_0_1_4_1_0_0_0_1 - 0.299999999999997*G0_0_1_4_1_0_1_0_0 - 0.299999999999997*G0_0_1_4_1_0_2_0_1 + 0.299999999999997*G0_0_1_4_1_0_3_1_0 + 0.299999999999997*G0_0_1_4_1_0_3_1_1 - 0.299999999999997*G0_0_1_4_1_0_4_1_0 - 0.299999999999997*G0_0_1_4_1_0_5_1_1 + 0.299999999999997*G0_0_1_5_1_1_0_0_0 + 0.299999999999997*G0_0_1_5_1_1_0_0_1 - 0.299999999999997*G0_0_1_5_1_1_1_0_0 - 0.299999999999997*G0_0_1_5_1_1_2_0_1 + 0.299999999999997*G0_0_1_5_1_1_3_1_0 + 0.299999999999997*G0_0_1_5_1_1_3_1_1 - 0.299999999999997*G0_0_1_5_1_1_4_1_0 - 0.299999999999997*G0_0_1_5_1_1_5_1_1 + 0.299999999999997*G0_1_0_0_0_0_0_0_0 + 0.299999999999997*G0_1_0_0_0_0_0_0_1 - 0.299999999999997*G0_1_0_0_0_0_1_0_0 - 0.299999999999997*G0_1_0_0_0_0_2_0_1 + 0.299999999999997*G0_1_0_0_0_0_3_1_0 + 0.299999999999997*G0_1_0_0_0_0_3_1_1 - 0.299999999999997*G0_1_0_0_0_0_4_1_0 - 0.299999999999997*G0_1_0_0_0_0_5_1_1 + 0.299999999999997*G0_1_0_0_0_1_0_0_0 + 0.299999999999997*G0_1_0_0_0_1_0_0_1 - 0.299999999999997*G0_1_0_0_0_1_1_0_0 - 0.299999999999997*G0_1_0_0_0_1_2_0_1 + 0.299999999999997*G0_1_0_0_0_1_3_1_0 + 0.299999999999997*G0_1_0_0_0_1_3_1_1 - 0.299999999999997*G0_1_0_0_0_1_4_1_0 - 0.299999999999997*G0_1_0_0_0_1_5_1_1 - 0.299999999999997*G0_1_0_1_0_0_0_0_0 - 0.299999999999997*G0_1_0_1_0_0_0_0_1 + 0.299999999999997*G0_1_0_1_0_0_1_0_0 + 0.299999999999997*G0_1_0_1_0_0_2_0_1 - 0.299999999999997*G0_1_0_1_0_0_3_1_0 - 0.299999999999997*G0_1_0_1_0_0_3_1_1 + 0.299999999999997*G0_1_0_1_0_0_4_1_0 + 0.299999999999997*G0_1_0_1_0_0_5_1_1 - 0.299999999999997*G0_1_0_2_0_1_0_0_0 - 0.299999999999997*G0_1_0_2_0_1_0_0_1 + 0.299999999999997*G0_1_0_2_0_1_1_0_0 + 0.299999999999997*G0_1_0_2_0_1_2_0_1 - 0.299999999999997*G0_1_0_2_0_1_3_1_0 - 0.299999999999997*G0_1_0_2_0_1_3_1_1 + 0.299999999999997*G0_1_0_2_0_1_4_1_0 + 0.299999999999997*G0_1_0_2_0_1_5_1_1 + 0.299999999999997*G0_1_0_3_1_0_0_0_0 + 0.299999999999997*G0_1_0_3_1_0_0_0_1 - 0.299999999999997*G0_1_0_3_1_0_1_0_0 - 0.299999999999997*G0_1_0_3_1_0_2_0_1 + 0.299999999999997*G0_1_0_3_1_0_3_1_0 + 0.299999999999997*G0_1_0_3_1_0_3_1_1 - 0.299999999999997*G0_1_0_3_1_0_4_1_0 - 0.299999999999997*G0_1_0_3_1_0_5_1_1 + 0.299999999999997*G0_1_0_3_1_1_0_0_0 + 0.299999999999997*G0_1_0_3_1_1_0_0_1 - 0.299999999999997*G0_1_0_3_1_1_1_0_0 - 0.299999999999997*G0_1_0_3_1_1_2_0_1 + 0.299999999999997*G0_1_0_3_1_1_3_1_0 + 0.299999999999997*G0_1_0_3_1_1_3_1_1 - 0.299999999999997*G0_1_0_3_1_1_4_1_0 - 0.299999999999997*G0_1_0_3_1_1_5_1_1 - 0.299999999999997*G0_1_0_4_1_0_0_0_0 - 0.299999999999997*G0_1_0_4_1_0_0_0_1 + 0.299999999999997*G0_1_0_4_1_0_1_0_0 + 0.299999999999997*G0_1_0_4_1_0_2_0_1 - 0.299999999999997*G0_1_0_4_1_0_3_1_0 - 0.299999999999997*G0_1_0_4_1_0_3_1_1 + 0.299999999999997*G0_1_0_4_1_0_4_1_0 + 0.299999999999997*G0_1_0_4_1_0_5_1_1 - 0.299999999999997*G0_1_0_5_1_1_0_0_0 - 0.299999999999997*G0_1_0_5_1_1_0_0_1 + 0.299999999999997*G0_1_0_5_1_1_1_0_0 + 0.299999999999997*G0_1_0_5_1_1_2_0_1 - 0.299999999999997*G0_1_0_5_1_1_3_1_0 - 0.299999999999997*G0_1_0_5_1_1_3_1_1 + 0.299999999999997*G0_1_0_5_1_1_4_1_0 + 0.299999999999997*G0_1_0_5_1_1_5_1_1; + A[311] = A[235]; + A[267] = 0.0; + A[4] = A[214]; + A[21] = -11.3333333333334*A[235]; + A[90] = 0.0; + A[111] = 0.0; + A[120] = -A[214] + 0.299999999999998*G0_1_0_0_0_0_0_0_0 + 0.299999999999998*G0_1_0_0_0_0_0_0_1 - 0.299999999999998*G0_1_0_0_0_0_1_0_0 - 0.299999999999998*G0_1_0_0_0_0_2_0_1 + 0.299999999999998*G0_1_0_0_0_0_3_1_0 + 0.299999999999998*G0_1_0_0_0_0_3_1_1 - 0.299999999999998*G0_1_0_0_0_0_4_1_0 - 0.299999999999998*G0_1_0_0_0_0_5_1_1 + 0.299999999999998*G0_1_0_0_0_1_0_0_0 + 0.299999999999998*G0_1_0_0_0_1_0_0_1 - 0.299999999999998*G0_1_0_0_0_1_1_0_0 - 0.299999999999998*G0_1_0_0_0_1_2_0_1 + 0.299999999999998*G0_1_0_0_0_1_3_1_0 + 0.299999999999998*G0_1_0_0_0_1_3_1_1 - 0.299999999999998*G0_1_0_0_0_1_4_1_0 - 0.299999999999998*G0_1_0_0_0_1_5_1_1 - 0.299999999999998*G0_1_0_1_0_0_0_0_0 - 0.299999999999998*G0_1_0_1_0_0_0_0_1 + 0.299999999999998*G0_1_0_1_0_0_1_0_0 + 0.299999999999998*G0_1_0_1_0_0_2_0_1 - 0.299999999999998*G0_1_0_1_0_0_3_1_0 - 0.299999999999998*G0_1_0_1_0_0_3_1_1 + 0.299999999999998*G0_1_0_1_0_0_4_1_0 + 0.299999999999998*G0_1_0_1_0_0_5_1_1 - 0.299999999999998*G0_1_0_2_0_1_0_0_0 - 0.299999999999998*G0_1_0_2_0_1_0_0_1 + 0.299999999999998*G0_1_0_2_0_1_1_0_0 + 0.299999999999998*G0_1_0_2_0_1_2_0_1 - 0.299999999999998*G0_1_0_2_0_1_3_1_0 - 0.299999999999998*G0_1_0_2_0_1_3_1_1 + 0.299999999999998*G0_1_0_2_0_1_4_1_0 + 0.299999999999998*G0_1_0_2_0_1_5_1_1 + 0.299999999999998*G0_1_0_3_1_0_0_0_0 + 0.299999999999998*G0_1_0_3_1_0_0_0_1 - 0.299999999999998*G0_1_0_3_1_0_1_0_0 - 0.299999999999998*G0_1_0_3_1_0_2_0_1 + 0.299999999999998*G0_1_0_3_1_0_3_1_0 + 0.299999999999998*G0_1_0_3_1_0_3_1_1 - 0.299999999999998*G0_1_0_3_1_0_4_1_0 - 0.299999999999998*G0_1_0_3_1_0_5_1_1 + 0.299999999999998*G0_1_0_3_1_1_0_0_0 + 0.299999999999998*G0_1_0_3_1_1_0_0_1 - 0.299999999999998*G0_1_0_3_1_1_1_0_0 - 0.299999999999998*G0_1_0_3_1_1_2_0_1 + 0.299999999999998*G0_1_0_3_1_1_3_1_0 + 0.299999999999998*G0_1_0_3_1_1_3_1_1 - 0.299999999999998*G0_1_0_3_1_1_4_1_0 - 0.299999999999998*G0_1_0_3_1_1_5_1_1 - 0.299999999999998*G0_1_0_4_1_0_0_0_0 - 0.299999999999998*G0_1_0_4_1_0_0_0_1 + 0.299999999999998*G0_1_0_4_1_0_1_0_0 + 0.299999999999998*G0_1_0_4_1_0_2_0_1 - 0.299999999999998*G0_1_0_4_1_0_3_1_0 - 0.299999999999998*G0_1_0_4_1_0_3_1_1 + 0.299999999999998*G0_1_0_4_1_0_4_1_0 + 0.299999999999998*G0_1_0_4_1_0_5_1_1 - 0.299999999999998*G0_1_0_5_1_1_0_0_0 - 0.299999999999998*G0_1_0_5_1_1_0_0_1 + 0.299999999999998*G0_1_0_5_1_1_1_0_0 + 0.299999999999998*G0_1_0_5_1_1_2_0_1 - 0.299999999999998*G0_1_0_5_1_1_3_1_0 - 0.299999999999998*G0_1_0_5_1_1_3_1_1 + 0.299999999999998*G0_1_0_5_1_1_4_1_0 + 0.299999999999998*G0_1_0_5_1_1_5_1_1 + 0.3*G0_1_1_0_0_0_0_0_0 + 0.3*G0_1_1_0_0_0_0_0_1 - 0.3*G0_1_1_0_0_0_1_0_0 - 0.3*G0_1_1_0_0_0_2_0_1 + 0.3*G0_1_1_0_0_0_3_1_0 + 0.3*G0_1_1_0_0_0_3_1_1 - 0.3*G0_1_1_0_0_0_4_1_0 - 0.3*G0_1_1_0_0_0_5_1_1 + 0.3*G0_1_1_0_0_1_0_0_0 + 0.3*G0_1_1_0_0_1_0_0_1 - 0.3*G0_1_1_0_0_1_1_0_0 - 0.3*G0_1_1_0_0_1_2_0_1 + 0.3*G0_1_1_0_0_1_3_1_0 + 0.3*G0_1_1_0_0_1_3_1_1 - 0.3*G0_1_1_0_0_1_4_1_0 - 0.3*G0_1_1_0_0_1_5_1_1 - 0.3*G0_1_1_1_0_0_0_0_0 - 0.3*G0_1_1_1_0_0_0_0_1 + 0.3*G0_1_1_1_0_0_1_0_0 + 0.3*G0_1_1_1_0_0_2_0_1 - 0.3*G0_1_1_1_0_0_3_1_0 - 0.3*G0_1_1_1_0_0_3_1_1 + 0.3*G0_1_1_1_0_0_4_1_0 + 0.3*G0_1_1_1_0_0_5_1_1 - 0.3*G0_1_1_2_0_1_0_0_0 - 0.3*G0_1_1_2_0_1_0_0_1 + 0.3*G0_1_1_2_0_1_1_0_0 + 0.3*G0_1_1_2_0_1_2_0_1 - 0.3*G0_1_1_2_0_1_3_1_0 - 0.3*G0_1_1_2_0_1_3_1_1 + 0.3*G0_1_1_2_0_1_4_1_0 + 0.3*G0_1_1_2_0_1_5_1_1 + 0.3*G0_1_1_3_1_0_0_0_0 + 0.3*G0_1_1_3_1_0_0_0_1 - 0.3*G0_1_1_3_1_0_1_0_0 - 0.3*G0_1_1_3_1_0_2_0_1 + 0.3*G0_1_1_3_1_0_3_1_0 + 0.3*G0_1_1_3_1_0_3_1_1 - 0.3*G0_1_1_3_1_0_4_1_0 - 0.3*G0_1_1_3_1_0_5_1_1 + 0.3*G0_1_1_3_1_1_0_0_0 + 0.3*G0_1_1_3_1_1_0_0_1 - 0.3*G0_1_1_3_1_1_1_0_0 - 0.3*G0_1_1_3_1_1_2_0_1 + 0.3*G0_1_1_3_1_1_3_1_0 + 0.3*G0_1_1_3_1_1_3_1_1 - 0.3*G0_1_1_3_1_1_4_1_0 - 0.3*G0_1_1_3_1_1_5_1_1 - 0.3*G0_1_1_4_1_0_0_0_0 - 0.3*G0_1_1_4_1_0_0_0_1 + 0.3*G0_1_1_4_1_0_1_0_0 + 0.3*G0_1_1_4_1_0_2_0_1 - 0.3*G0_1_1_4_1_0_3_1_0 - 0.3*G0_1_1_4_1_0_3_1_1 + 0.3*G0_1_1_4_1_0_4_1_0 + 0.3*G0_1_1_4_1_0_5_1_1 - 0.3*G0_1_1_5_1_1_0_0_0 - 0.3*G0_1_1_5_1_1_0_0_1 + 0.3*G0_1_1_5_1_1_1_0_0 + 0.3*G0_1_1_5_1_1_2_0_1 - 0.3*G0_1_1_5_1_1_3_1_0 - 0.3*G0_1_1_5_1_1_3_1_1 + 0.3*G0_1_1_5_1_1_4_1_0 + 0.3*G0_1_1_5_1_1_5_1_1; + A[96] = 0.0; + A[145] = 0.833333333333323*A[379]; + A[339] = A[379]; + A[358] = -A[143] - 1.35*G0_0_0_0_0_0_0_0_0 - 1.35*G0_0_0_0_0_0_0_0_1 + 1.35*G0_0_0_0_0_0_1_0_0 + 1.35*G0_0_0_0_0_0_2_0_1 - 1.35*G0_0_0_0_0_0_3_1_0 - 1.35*G0_0_0_0_0_0_3_1_1 + 1.35*G0_0_0_0_0_0_4_1_0 + 1.35*G0_0_0_0_0_0_5_1_1 - 1.35*G0_0_0_0_0_1_0_0_0 - 1.35*G0_0_0_0_0_1_0_0_1 + 1.35*G0_0_0_0_0_1_1_0_0 + 1.35*G0_0_0_0_0_1_2_0_1 - 1.35*G0_0_0_0_0_1_3_1_0 - 1.35*G0_0_0_0_0_1_3_1_1 + 1.35*G0_0_0_0_0_1_4_1_0 + 1.35*G0_0_0_0_0_1_5_1_1 + 1.35*G0_0_0_1_0_0_0_0_0 + 1.35*G0_0_0_1_0_0_0_0_1 - 1.35*G0_0_0_1_0_0_1_0_0 - 1.35*G0_0_0_1_0_0_2_0_1 + 1.35*G0_0_0_1_0_0_3_1_0 + 1.35*G0_0_0_1_0_0_3_1_1 - 1.35*G0_0_0_1_0_0_4_1_0 - 1.35*G0_0_0_1_0_0_5_1_1 + 1.35*G0_0_0_2_0_1_0_0_0 + 1.35*G0_0_0_2_0_1_0_0_1 - 1.35*G0_0_0_2_0_1_1_0_0 - 1.35*G0_0_0_2_0_1_2_0_1 + 1.35*G0_0_0_2_0_1_3_1_0 + 1.35*G0_0_0_2_0_1_3_1_1 - 1.35*G0_0_0_2_0_1_4_1_0 - 1.35*G0_0_0_2_0_1_5_1_1 - 1.35*G0_0_0_3_1_0_0_0_0 - 1.35*G0_0_0_3_1_0_0_0_1 + 1.35*G0_0_0_3_1_0_1_0_0 + 1.35*G0_0_0_3_1_0_2_0_1 - 1.35*G0_0_0_3_1_0_3_1_0 - 1.35*G0_0_0_3_1_0_3_1_1 + 1.35*G0_0_0_3_1_0_4_1_0 + 1.35*G0_0_0_3_1_0_5_1_1 - 1.35*G0_0_0_3_1_1_0_0_0 - 1.35*G0_0_0_3_1_1_0_0_1 + 1.35*G0_0_0_3_1_1_1_0_0 + 1.35*G0_0_0_3_1_1_2_0_1 - 1.35*G0_0_0_3_1_1_3_1_0 - 1.35*G0_0_0_3_1_1_3_1_1 + 1.35*G0_0_0_3_1_1_4_1_0 + 1.35*G0_0_0_3_1_1_5_1_1 + 1.35*G0_0_0_4_1_0_0_0_0 + 1.35*G0_0_0_4_1_0_0_0_1 - 1.35*G0_0_0_4_1_0_1_0_0 - 1.35*G0_0_0_4_1_0_2_0_1 + 1.35*G0_0_0_4_1_0_3_1_0 + 1.35*G0_0_0_4_1_0_3_1_1 - 1.35*G0_0_0_4_1_0_4_1_0 - 1.35*G0_0_0_4_1_0_5_1_1 + 1.35*G0_0_0_5_1_1_0_0_0 + 1.35*G0_0_0_5_1_1_0_0_1 - 1.35*G0_0_0_5_1_1_1_0_0 - 1.35*G0_0_0_5_1_1_2_0_1 + 1.35*G0_0_0_5_1_1_3_1_0 + 1.35*G0_0_0_5_1_1_3_1_1 - 1.35*G0_0_0_5_1_1_4_1_0 - 1.35*G0_0_0_5_1_1_5_1_1 - 1.0125*G0_1_0_0_0_0_0_0_0 - 1.0125*G0_1_0_0_0_0_0_0_1 + 1.0125*G0_1_0_0_0_0_1_0_0 + 1.0125*G0_1_0_0_0_0_2_0_1 - 1.0125*G0_1_0_0_0_0_3_1_0 - 1.0125*G0_1_0_0_0_0_3_1_1 + 1.0125*G0_1_0_0_0_0_4_1_0 + 1.0125*G0_1_0_0_0_0_5_1_1 - 1.0125*G0_1_0_0_0_1_0_0_0 - 1.0125*G0_1_0_0_0_1_0_0_1 + 1.0125*G0_1_0_0_0_1_1_0_0 + 1.0125*G0_1_0_0_0_1_2_0_1 - 1.0125*G0_1_0_0_0_1_3_1_0 - 1.0125*G0_1_0_0_0_1_3_1_1 + 1.0125*G0_1_0_0_0_1_4_1_0 + 1.0125*G0_1_0_0_0_1_5_1_1 + 1.0125*G0_1_0_1_0_0_0_0_0 + 1.0125*G0_1_0_1_0_0_0_0_1 - 1.0125*G0_1_0_1_0_0_1_0_0 - 1.0125*G0_1_0_1_0_0_2_0_1 + 1.0125*G0_1_0_1_0_0_3_1_0 + 1.0125*G0_1_0_1_0_0_3_1_1 - 1.0125*G0_1_0_1_0_0_4_1_0 - 1.0125*G0_1_0_1_0_0_5_1_1 + 1.0125*G0_1_0_2_0_1_0_0_0 + 1.0125*G0_1_0_2_0_1_0_0_1 - 1.0125*G0_1_0_2_0_1_1_0_0 - 1.0125*G0_1_0_2_0_1_2_0_1 + 1.0125*G0_1_0_2_0_1_3_1_0 + 1.0125*G0_1_0_2_0_1_3_1_1 - 1.0125*G0_1_0_2_0_1_4_1_0 - 1.0125*G0_1_0_2_0_1_5_1_1 - 1.0125*G0_1_0_3_1_0_0_0_0 - 1.0125*G0_1_0_3_1_0_0_0_1 + 1.0125*G0_1_0_3_1_0_1_0_0 + 1.0125*G0_1_0_3_1_0_2_0_1 - 1.0125*G0_1_0_3_1_0_3_1_0 - 1.0125*G0_1_0_3_1_0_3_1_1 + 1.0125*G0_1_0_3_1_0_4_1_0 + 1.0125*G0_1_0_3_1_0_5_1_1 - 1.0125*G0_1_0_3_1_1_0_0_0 - 1.0125*G0_1_0_3_1_1_0_0_1 + 1.0125*G0_1_0_3_1_1_1_0_0 + 1.0125*G0_1_0_3_1_1_2_0_1 - 1.0125*G0_1_0_3_1_1_3_1_0 - 1.0125*G0_1_0_3_1_1_3_1_1 + 1.0125*G0_1_0_3_1_1_4_1_0 + 1.0125*G0_1_0_3_1_1_5_1_1 + 1.0125*G0_1_0_4_1_0_0_0_0 + 1.0125*G0_1_0_4_1_0_0_0_1 - 1.0125*G0_1_0_4_1_0_1_0_0 - 1.0125*G0_1_0_4_1_0_2_0_1 + 1.0125*G0_1_0_4_1_0_3_1_0 + 1.0125*G0_1_0_4_1_0_3_1_1 - 1.0125*G0_1_0_4_1_0_4_1_0 - 1.0125*G0_1_0_4_1_0_5_1_1 + 1.0125*G0_1_0_5_1_1_0_0_0 + 1.0125*G0_1_0_5_1_1_0_0_1 - 1.0125*G0_1_0_5_1_1_1_0_0 - 1.0125*G0_1_0_5_1_1_2_0_1 + 1.0125*G0_1_0_5_1_1_3_1_0 + 1.0125*G0_1_0_5_1_1_3_1_1 - 1.0125*G0_1_0_5_1_1_4_1_0 - 1.0125*G0_1_0_5_1_1_5_1_1; + A[316] = A[106]; + A[260] = 0.0; + A[236] = A[235]; + A[41] = 0.0874999999999997*G0_1_0_0_0_0_0_0_0 + 0.0874999999999997*G0_1_0_0_0_0_0_0_1 - 0.0874999999999997*G0_1_0_0_0_0_1_0_0 - 0.0874999999999997*G0_1_0_0_0_0_2_0_1 + 0.0874999999999997*G0_1_0_0_0_0_3_1_0 + 0.0874999999999997*G0_1_0_0_0_0_3_1_1 - 0.0874999999999997*G0_1_0_0_0_0_4_1_0 - 0.0874999999999997*G0_1_0_0_0_0_5_1_1 + 0.0874999999999997*G0_1_0_0_0_1_0_0_0 + 0.0874999999999997*G0_1_0_0_0_1_0_0_1 - 0.0874999999999997*G0_1_0_0_0_1_1_0_0 - 0.0874999999999997*G0_1_0_0_0_1_2_0_1 + 0.0874999999999997*G0_1_0_0_0_1_3_1_0 + 0.0874999999999997*G0_1_0_0_0_1_3_1_1 - 0.0874999999999997*G0_1_0_0_0_1_4_1_0 - 0.0874999999999997*G0_1_0_0_0_1_5_1_1 - 0.0874999999999997*G0_1_0_1_0_0_0_0_0 - 0.0874999999999997*G0_1_0_1_0_0_0_0_1 + 0.0874999999999997*G0_1_0_1_0_0_1_0_0 + 0.0874999999999997*G0_1_0_1_0_0_2_0_1 - 0.0874999999999997*G0_1_0_1_0_0_3_1_0 - 0.0874999999999997*G0_1_0_1_0_0_3_1_1 + 0.0874999999999997*G0_1_0_1_0_0_4_1_0 + 0.0874999999999997*G0_1_0_1_0_0_5_1_1 - 0.0874999999999997*G0_1_0_2_0_1_0_0_0 - 0.0874999999999997*G0_1_0_2_0_1_0_0_1 + 0.0874999999999997*G0_1_0_2_0_1_1_0_0 + 0.0874999999999997*G0_1_0_2_0_1_2_0_1 - 0.0874999999999997*G0_1_0_2_0_1_3_1_0 - 0.0874999999999997*G0_1_0_2_0_1_3_1_1 + 0.0874999999999997*G0_1_0_2_0_1_4_1_0 + 0.0874999999999997*G0_1_0_2_0_1_5_1_1 + 0.0874999999999997*G0_1_0_3_1_0_0_0_0 + 0.0874999999999997*G0_1_0_3_1_0_0_0_1 - 0.0874999999999997*G0_1_0_3_1_0_1_0_0 - 0.0874999999999997*G0_1_0_3_1_0_2_0_1 + 0.0874999999999997*G0_1_0_3_1_0_3_1_0 + 0.0874999999999997*G0_1_0_3_1_0_3_1_1 - 0.0874999999999997*G0_1_0_3_1_0_4_1_0 - 0.0874999999999997*G0_1_0_3_1_0_5_1_1 + 0.0874999999999997*G0_1_0_3_1_1_0_0_0 + 0.0874999999999997*G0_1_0_3_1_1_0_0_1 - 0.0874999999999997*G0_1_0_3_1_1_1_0_0 - 0.0874999999999997*G0_1_0_3_1_1_2_0_1 + 0.0874999999999997*G0_1_0_3_1_1_3_1_0 + 0.0874999999999997*G0_1_0_3_1_1_3_1_1 - 0.0874999999999997*G0_1_0_3_1_1_4_1_0 - 0.0874999999999997*G0_1_0_3_1_1_5_1_1 - 0.0874999999999997*G0_1_0_4_1_0_0_0_0 - 0.0874999999999997*G0_1_0_4_1_0_0_0_1 + 0.0874999999999997*G0_1_0_4_1_0_1_0_0 + 0.0874999999999997*G0_1_0_4_1_0_2_0_1 - 0.0874999999999997*G0_1_0_4_1_0_3_1_0 - 0.0874999999999997*G0_1_0_4_1_0_3_1_1 + 0.0874999999999997*G0_1_0_4_1_0_4_1_0 + 0.0874999999999997*G0_1_0_4_1_0_5_1_1 - 0.0874999999999997*G0_1_0_5_1_1_0_0_0 - 0.0874999999999997*G0_1_0_5_1_1_0_0_1 + 0.0874999999999997*G0_1_0_5_1_1_1_0_0 + 0.0874999999999997*G0_1_0_5_1_1_2_0_1 - 0.0874999999999997*G0_1_0_5_1_1_3_1_0 - 0.0874999999999997*G0_1_0_5_1_1_3_1_1 + 0.0874999999999997*G0_1_0_5_1_1_4_1_0 + 0.0874999999999997*G0_1_0_5_1_1_5_1_1; + A[250] = -A[41] - 0.0875000000000007*G0_1_1_0_0_0_0_0_0 - 0.0875000000000007*G0_1_1_0_0_0_0_0_1 + 0.0875000000000007*G0_1_1_0_0_0_1_0_0 + 0.0875000000000007*G0_1_1_0_0_0_2_0_1 - 0.0875000000000007*G0_1_1_0_0_0_3_1_0 - 0.0875000000000007*G0_1_1_0_0_0_3_1_1 + 0.0875000000000007*G0_1_1_0_0_0_4_1_0 + 0.0875000000000007*G0_1_1_0_0_0_5_1_1 - 0.0875000000000007*G0_1_1_0_0_1_0_0_0 - 0.0875000000000007*G0_1_1_0_0_1_0_0_1 + 0.0875000000000007*G0_1_1_0_0_1_1_0_0 + 0.0875000000000007*G0_1_1_0_0_1_2_0_1 - 0.0875000000000007*G0_1_1_0_0_1_3_1_0 - 0.0875000000000007*G0_1_1_0_0_1_3_1_1 + 0.0875000000000007*G0_1_1_0_0_1_4_1_0 + 0.0875000000000007*G0_1_1_0_0_1_5_1_1 + 0.0875000000000007*G0_1_1_1_0_0_0_0_0 + 0.0875000000000007*G0_1_1_1_0_0_0_0_1 - 0.0875000000000007*G0_1_1_1_0_0_1_0_0 - 0.0875000000000007*G0_1_1_1_0_0_2_0_1 + 0.0875000000000007*G0_1_1_1_0_0_3_1_0 + 0.0875000000000007*G0_1_1_1_0_0_3_1_1 - 0.0875000000000007*G0_1_1_1_0_0_4_1_0 - 0.0875000000000007*G0_1_1_1_0_0_5_1_1 + 0.0875000000000007*G0_1_1_2_0_1_0_0_0 + 0.0875000000000007*G0_1_1_2_0_1_0_0_1 - 0.0875000000000007*G0_1_1_2_0_1_1_0_0 - 0.0875000000000007*G0_1_1_2_0_1_2_0_1 + 0.0875000000000007*G0_1_1_2_0_1_3_1_0 + 0.0875000000000007*G0_1_1_2_0_1_3_1_1 - 0.0875000000000007*G0_1_1_2_0_1_4_1_0 - 0.0875000000000007*G0_1_1_2_0_1_5_1_1 - 0.0875000000000007*G0_1_1_3_1_0_0_0_0 - 0.0875000000000007*G0_1_1_3_1_0_0_0_1 + 0.0875000000000007*G0_1_1_3_1_0_1_0_0 + 0.0875000000000007*G0_1_1_3_1_0_2_0_1 - 0.0875000000000007*G0_1_1_3_1_0_3_1_0 - 0.0875000000000007*G0_1_1_3_1_0_3_1_1 + 0.0875000000000007*G0_1_1_3_1_0_4_1_0 + 0.0875000000000007*G0_1_1_3_1_0_5_1_1 - 0.0875000000000007*G0_1_1_3_1_1_0_0_0 - 0.0875000000000007*G0_1_1_3_1_1_0_0_1 + 0.0875000000000007*G0_1_1_3_1_1_1_0_0 + 0.0875000000000007*G0_1_1_3_1_1_2_0_1 - 0.0875000000000007*G0_1_1_3_1_1_3_1_0 - 0.0875000000000007*G0_1_1_3_1_1_3_1_1 + 0.0875000000000007*G0_1_1_3_1_1_4_1_0 + 0.0875000000000007*G0_1_1_3_1_1_5_1_1 + 0.0875000000000007*G0_1_1_4_1_0_0_0_0 + 0.0875000000000007*G0_1_1_4_1_0_0_0_1 - 0.0875000000000007*G0_1_1_4_1_0_1_0_0 - 0.0875000000000007*G0_1_1_4_1_0_2_0_1 + 0.0875000000000007*G0_1_1_4_1_0_3_1_0 + 0.0875000000000007*G0_1_1_4_1_0_3_1_1 - 0.0875000000000007*G0_1_1_4_1_0_4_1_0 - 0.0875000000000007*G0_1_1_4_1_0_5_1_1 + 0.0875000000000007*G0_1_1_5_1_1_0_0_0 + 0.0875000000000007*G0_1_1_5_1_1_0_0_1 - 0.0875000000000007*G0_1_1_5_1_1_1_0_0 - 0.0875000000000007*G0_1_1_5_1_1_2_0_1 + 0.0875000000000007*G0_1_1_5_1_1_3_1_0 + 0.0875000000000007*G0_1_1_5_1_1_3_1_1 - 0.0875000000000007*G0_1_1_5_1_1_4_1_0 - 0.0875000000000007*G0_1_1_5_1_1_5_1_1; + A[142] = A[257]; + A[330] = A[120]; + A[387] = 0.0; + A[351] = -A[81] + 0.375000000000003*G0_0_0_0_0_0_0_0_0 + 0.375000000000003*G0_0_0_0_0_0_0_0_1 - 0.375000000000003*G0_0_0_0_0_0_1_0_0 - 0.375000000000003*G0_0_0_0_0_0_2_0_1 + 0.375000000000003*G0_0_0_0_0_0_3_1_0 + 0.375000000000003*G0_0_0_0_0_0_3_1_1 - 0.375000000000003*G0_0_0_0_0_0_4_1_0 - 0.375000000000003*G0_0_0_0_0_0_5_1_1 + 0.375000000000003*G0_0_0_0_0_1_0_0_0 + 0.375000000000003*G0_0_0_0_0_1_0_0_1 - 0.375000000000003*G0_0_0_0_0_1_1_0_0 - 0.375000000000003*G0_0_0_0_0_1_2_0_1 + 0.375000000000003*G0_0_0_0_0_1_3_1_0 + 0.375000000000003*G0_0_0_0_0_1_3_1_1 - 0.375000000000003*G0_0_0_0_0_1_4_1_0 - 0.375000000000003*G0_0_0_0_0_1_5_1_1 - 0.375000000000003*G0_0_0_1_0_0_0_0_0 - 0.375000000000003*G0_0_0_1_0_0_0_0_1 + 0.375000000000003*G0_0_0_1_0_0_1_0_0 + 0.375000000000003*G0_0_0_1_0_0_2_0_1 - 0.375000000000003*G0_0_0_1_0_0_3_1_0 - 0.375000000000003*G0_0_0_1_0_0_3_1_1 + 0.375000000000003*G0_0_0_1_0_0_4_1_0 + 0.375000000000003*G0_0_0_1_0_0_5_1_1 - 0.375000000000003*G0_0_0_2_0_1_0_0_0 - 0.375000000000003*G0_0_0_2_0_1_0_0_1 + 0.375000000000003*G0_0_0_2_0_1_1_0_0 + 0.375000000000003*G0_0_0_2_0_1_2_0_1 - 0.375000000000003*G0_0_0_2_0_1_3_1_0 - 0.375000000000003*G0_0_0_2_0_1_3_1_1 + 0.375000000000003*G0_0_0_2_0_1_4_1_0 + 0.375000000000003*G0_0_0_2_0_1_5_1_1 + 0.375000000000003*G0_0_0_3_1_0_0_0_0 + 0.375000000000003*G0_0_0_3_1_0_0_0_1 - 0.375000000000003*G0_0_0_3_1_0_1_0_0 - 0.375000000000003*G0_0_0_3_1_0_2_0_1 + 0.375000000000003*G0_0_0_3_1_0_3_1_0 + 0.375000000000003*G0_0_0_3_1_0_3_1_1 - 0.375000000000003*G0_0_0_3_1_0_4_1_0 - 0.375000000000003*G0_0_0_3_1_0_5_1_1 + 0.375000000000003*G0_0_0_3_1_1_0_0_0 + 0.375000000000003*G0_0_0_3_1_1_0_0_1 - 0.375000000000003*G0_0_0_3_1_1_1_0_0 - 0.375000000000003*G0_0_0_3_1_1_2_0_1 + 0.375000000000003*G0_0_0_3_1_1_3_1_0 + 0.375000000000003*G0_0_0_3_1_1_3_1_1 - 0.375000000000003*G0_0_0_3_1_1_4_1_0 - 0.375000000000003*G0_0_0_3_1_1_5_1_1 - 0.375000000000003*G0_0_0_4_1_0_0_0_0 - 0.375000000000003*G0_0_0_4_1_0_0_0_1 + 0.375000000000003*G0_0_0_4_1_0_1_0_0 + 0.375000000000003*G0_0_0_4_1_0_2_0_1 - 0.375000000000003*G0_0_0_4_1_0_3_1_0 - 0.375000000000003*G0_0_0_4_1_0_3_1_1 + 0.375000000000003*G0_0_0_4_1_0_4_1_0 + 0.375000000000003*G0_0_0_4_1_0_5_1_1 - 0.375000000000003*G0_0_0_5_1_1_0_0_0 - 0.375000000000003*G0_0_0_5_1_1_0_0_1 + 0.375000000000003*G0_0_0_5_1_1_1_0_0 + 0.375000000000003*G0_0_0_5_1_1_2_0_1 - 0.375000000000003*G0_0_0_5_1_1_3_1_0 - 0.375000000000003*G0_0_0_5_1_1_3_1_1 + 0.375000000000003*G0_0_0_5_1_1_4_1_0 + 0.375000000000003*G0_0_0_5_1_1_5_1_1; + A[376] = A[165]; + A[166] = A[165]; + A[187] = A[299]; + A[204] = 0.0; + A[229] = 0.0; + A[18] = 0.0; + A[286] = 0.0; + A[258] = A[257]; + A[39] = 0.0; + A[307] = 0.0; + A[279] = A[393]; + A[8] = A[218]; + A[65] = A[85]; + A[86] = -4.99999999999992*A[85]; + A[107] = A[145]; + A[321] = 0.0; + A[392] = 0.0; + A[352] = A[257]; + A[157] = 0.0; + A[371] = -A[271] - 0.637500000000002*G0_0_0_0_0_0_0_0_0 - 0.637500000000002*G0_0_0_0_0_0_0_0_1 + 0.637500000000002*G0_0_0_0_0_0_1_0_0 + 0.637500000000002*G0_0_0_0_0_0_2_0_1 - 0.637500000000002*G0_0_0_0_0_0_3_1_0 - 0.637500000000002*G0_0_0_0_0_0_3_1_1 + 0.637500000000002*G0_0_0_0_0_0_4_1_0 + 0.637500000000002*G0_0_0_0_0_0_5_1_1 - 0.637500000000002*G0_0_0_0_0_1_0_0_0 - 0.637500000000002*G0_0_0_0_0_1_0_0_1 + 0.637500000000002*G0_0_0_0_0_1_1_0_0 + 0.637500000000002*G0_0_0_0_0_1_2_0_1 - 0.637500000000002*G0_0_0_0_0_1_3_1_0 - 0.637500000000002*G0_0_0_0_0_1_3_1_1 + 0.637500000000002*G0_0_0_0_0_1_4_1_0 + 0.637500000000002*G0_0_0_0_0_1_5_1_1 + 0.637500000000002*G0_0_0_1_0_0_0_0_0 + 0.637500000000002*G0_0_0_1_0_0_0_0_1 - 0.637500000000002*G0_0_0_1_0_0_1_0_0 - 0.637500000000002*G0_0_0_1_0_0_2_0_1 + 0.637500000000002*G0_0_0_1_0_0_3_1_0 + 0.637500000000002*G0_0_0_1_0_0_3_1_1 - 0.637500000000002*G0_0_0_1_0_0_4_1_0 - 0.637500000000002*G0_0_0_1_0_0_5_1_1 + 0.637500000000002*G0_0_0_2_0_1_0_0_0 + 0.637500000000002*G0_0_0_2_0_1_0_0_1 - 0.637500000000002*G0_0_0_2_0_1_1_0_0 - 0.637500000000002*G0_0_0_2_0_1_2_0_1 + 0.637500000000002*G0_0_0_2_0_1_3_1_0 + 0.637500000000002*G0_0_0_2_0_1_3_1_1 - 0.637500000000002*G0_0_0_2_0_1_4_1_0 - 0.637500000000002*G0_0_0_2_0_1_5_1_1 - 0.637500000000002*G0_0_0_3_1_0_0_0_0 - 0.637500000000002*G0_0_0_3_1_0_0_0_1 + 0.637500000000002*G0_0_0_3_1_0_1_0_0 + 0.637500000000002*G0_0_0_3_1_0_2_0_1 - 0.637500000000002*G0_0_0_3_1_0_3_1_0 - 0.637500000000002*G0_0_0_3_1_0_3_1_1 + 0.637500000000002*G0_0_0_3_1_0_4_1_0 + 0.637500000000002*G0_0_0_3_1_0_5_1_1 - 0.637500000000002*G0_0_0_3_1_1_0_0_0 - 0.637500000000002*G0_0_0_3_1_1_0_0_1 + 0.637500000000002*G0_0_0_3_1_1_1_0_0 + 0.637500000000002*G0_0_0_3_1_1_2_0_1 - 0.637500000000002*G0_0_0_3_1_1_3_1_0 - 0.637500000000002*G0_0_0_3_1_1_3_1_1 + 0.637500000000002*G0_0_0_3_1_1_4_1_0 + 0.637500000000002*G0_0_0_3_1_1_5_1_1 + 0.637500000000002*G0_0_0_4_1_0_0_0_0 + 0.637500000000002*G0_0_0_4_1_0_0_0_1 - 0.637500000000002*G0_0_0_4_1_0_1_0_0 - 0.637500000000002*G0_0_0_4_1_0_2_0_1 + 0.637500000000002*G0_0_0_4_1_0_3_1_0 + 0.637500000000002*G0_0_0_4_1_0_3_1_1 - 0.637500000000002*G0_0_0_4_1_0_4_1_0 - 0.637500000000002*G0_0_0_4_1_0_5_1_1 + 0.637500000000002*G0_0_0_5_1_1_0_0_0 + 0.637500000000002*G0_0_0_5_1_1_0_0_1 - 0.637500000000002*G0_0_0_5_1_1_1_0_0 - 0.637500000000002*G0_0_0_5_1_1_2_0_1 + 0.637500000000002*G0_0_0_5_1_1_3_1_0 + 0.637500000000002*G0_0_0_5_1_1_3_1_1 - 0.637500000000002*G0_0_0_5_1_1_4_1_0 - 0.637500000000002*G0_0_0_5_1_1_5_1_1; + A[173] = 0.0; + A[188] = A[379]; + A[215] = A[5]; + A[179] = 0.0; + A[234] = A[24]; + A[198] = 0.0; + A[289] = 0.0; + A[249] = 0.0; + A[312] = A[102]; + A[272] = A[62]; + A[59] = 0.0; + A[15] = 0.0; + A[70] = 0.0; + A[34] = 0.0; + A[93] = 0.0; + A[53] = 0.0; + A[100] = A[310]; + A[76] = 0.0; + A[135] = 0.0; + A[345] = 0.0; + A[154] = 0.0; + A[362] = 0.0; + A[227] = 0.0; + A[296] = A[86]; + A[240] = 0.0; + A[216] = A[370] - 0.299999999999998*G0_0_0_0_0_0_0_0_0 - 0.299999999999998*G0_0_0_0_0_0_0_0_1 + 0.299999999999998*G0_0_0_0_0_0_1_0_0 + 0.299999999999998*G0_0_0_0_0_0_2_0_1 - 0.299999999999998*G0_0_0_0_0_0_3_1_0 - 0.299999999999998*G0_0_0_0_0_0_3_1_1 + 0.299999999999998*G0_0_0_0_0_0_4_1_0 + 0.299999999999998*G0_0_0_0_0_0_5_1_1 - 0.299999999999998*G0_0_0_0_0_1_0_0_0 - 0.299999999999998*G0_0_0_0_0_1_0_0_1 + 0.299999999999998*G0_0_0_0_0_1_1_0_0 + 0.299999999999998*G0_0_0_0_0_1_2_0_1 - 0.299999999999998*G0_0_0_0_0_1_3_1_0 - 0.299999999999998*G0_0_0_0_0_1_3_1_1 + 0.299999999999998*G0_0_0_0_0_1_4_1_0 + 0.299999999999998*G0_0_0_0_0_1_5_1_1 + 0.299999999999998*G0_0_0_1_0_0_0_0_0 + 0.299999999999998*G0_0_0_1_0_0_0_0_1 - 0.299999999999998*G0_0_0_1_0_0_1_0_0 - 0.299999999999998*G0_0_0_1_0_0_2_0_1 + 0.299999999999998*G0_0_0_1_0_0_3_1_0 + 0.299999999999998*G0_0_0_1_0_0_3_1_1 - 0.299999999999998*G0_0_0_1_0_0_4_1_0 - 0.299999999999998*G0_0_0_1_0_0_5_1_1 + 0.299999999999998*G0_0_0_2_0_1_0_0_0 + 0.299999999999998*G0_0_0_2_0_1_0_0_1 - 0.299999999999998*G0_0_0_2_0_1_1_0_0 - 0.299999999999998*G0_0_0_2_0_1_2_0_1 + 0.299999999999998*G0_0_0_2_0_1_3_1_0 + 0.299999999999998*G0_0_0_2_0_1_3_1_1 - 0.299999999999998*G0_0_0_2_0_1_4_1_0 - 0.299999999999998*G0_0_0_2_0_1_5_1_1 - 0.299999999999998*G0_0_0_3_1_0_0_0_0 - 0.299999999999998*G0_0_0_3_1_0_0_0_1 + 0.299999999999998*G0_0_0_3_1_0_1_0_0 + 0.299999999999998*G0_0_0_3_1_0_2_0_1 - 0.299999999999998*G0_0_0_3_1_0_3_1_0 - 0.299999999999998*G0_0_0_3_1_0_3_1_1 + 0.299999999999998*G0_0_0_3_1_0_4_1_0 + 0.299999999999998*G0_0_0_3_1_0_5_1_1 - 0.299999999999998*G0_0_0_3_1_1_0_0_0 - 0.299999999999998*G0_0_0_3_1_1_0_0_1 + 0.299999999999998*G0_0_0_3_1_1_1_0_0 + 0.299999999999998*G0_0_0_3_1_1_2_0_1 - 0.299999999999998*G0_0_0_3_1_1_3_1_0 - 0.299999999999998*G0_0_0_3_1_1_3_1_1 + 0.299999999999998*G0_0_0_3_1_1_4_1_0 + 0.299999999999998*G0_0_0_3_1_1_5_1_1 + 0.299999999999998*G0_0_0_4_1_0_0_0_0 + 0.299999999999998*G0_0_0_4_1_0_0_0_1 - 0.299999999999998*G0_0_0_4_1_0_1_0_0 - 0.299999999999998*G0_0_0_4_1_0_2_0_1 + 0.299999999999998*G0_0_0_4_1_0_3_1_0 + 0.299999999999998*G0_0_0_4_1_0_3_1_1 - 0.299999999999998*G0_0_0_4_1_0_4_1_0 - 0.299999999999998*G0_0_0_4_1_0_5_1_1 + 0.299999999999998*G0_0_0_5_1_1_0_0_0 + 0.299999999999998*G0_0_0_5_1_1_0_0_1 - 0.299999999999998*G0_0_0_5_1_1_1_0_0 - 0.299999999999998*G0_0_0_5_1_1_2_0_1 + 0.299999999999998*G0_0_0_5_1_1_3_1_0 + 0.299999999999998*G0_0_0_5_1_1_3_1_1 - 0.299999999999998*G0_0_0_5_1_1_4_1_0 - 0.299999999999998*G0_0_0_5_1_1_5_1_1 + 0.299999999999998*G0_1_1_0_0_0_0_0_0 + 0.299999999999998*G0_1_1_0_0_0_0_0_1 - 0.299999999999998*G0_1_1_0_0_0_1_0_0 - 0.299999999999998*G0_1_1_0_0_0_2_0_1 + 0.299999999999998*G0_1_1_0_0_0_3_1_0 + 0.299999999999998*G0_1_1_0_0_0_3_1_1 - 0.299999999999998*G0_1_1_0_0_0_4_1_0 - 0.299999999999998*G0_1_1_0_0_0_5_1_1 + 0.299999999999998*G0_1_1_0_0_1_0_0_0 + 0.299999999999998*G0_1_1_0_0_1_0_0_1 - 0.299999999999998*G0_1_1_0_0_1_1_0_0 - 0.299999999999998*G0_1_1_0_0_1_2_0_1 + 0.299999999999998*G0_1_1_0_0_1_3_1_0 + 0.299999999999998*G0_1_1_0_0_1_3_1_1 - 0.299999999999998*G0_1_1_0_0_1_4_1_0 - 0.299999999999998*G0_1_1_0_0_1_5_1_1 - 0.299999999999998*G0_1_1_1_0_0_0_0_0 - 0.299999999999998*G0_1_1_1_0_0_0_0_1 + 0.299999999999998*G0_1_1_1_0_0_1_0_0 + 0.299999999999998*G0_1_1_1_0_0_2_0_1 - 0.299999999999998*G0_1_1_1_0_0_3_1_0 - 0.299999999999998*G0_1_1_1_0_0_3_1_1 + 0.299999999999998*G0_1_1_1_0_0_4_1_0 + 0.299999999999998*G0_1_1_1_0_0_5_1_1 - 0.299999999999998*G0_1_1_2_0_1_0_0_0 - 0.299999999999998*G0_1_1_2_0_1_0_0_1 + 0.299999999999998*G0_1_1_2_0_1_1_0_0 + 0.299999999999998*G0_1_1_2_0_1_2_0_1 - 0.299999999999998*G0_1_1_2_0_1_3_1_0 - 0.299999999999998*G0_1_1_2_0_1_3_1_1 + 0.299999999999998*G0_1_1_2_0_1_4_1_0 + 0.299999999999998*G0_1_1_2_0_1_5_1_1 + 0.299999999999998*G0_1_1_3_1_0_0_0_0 + 0.299999999999998*G0_1_1_3_1_0_0_0_1 - 0.299999999999998*G0_1_1_3_1_0_1_0_0 - 0.299999999999998*G0_1_1_3_1_0_2_0_1 + 0.299999999999998*G0_1_1_3_1_0_3_1_0 + 0.299999999999998*G0_1_1_3_1_0_3_1_1 - 0.299999999999998*G0_1_1_3_1_0_4_1_0 - 0.299999999999998*G0_1_1_3_1_0_5_1_1 + 0.299999999999998*G0_1_1_3_1_1_0_0_0 + 0.299999999999998*G0_1_1_3_1_1_0_0_1 - 0.299999999999998*G0_1_1_3_1_1_1_0_0 - 0.299999999999998*G0_1_1_3_1_1_2_0_1 + 0.299999999999998*G0_1_1_3_1_1_3_1_0 + 0.299999999999998*G0_1_1_3_1_1_3_1_1 - 0.299999999999998*G0_1_1_3_1_1_4_1_0 - 0.299999999999998*G0_1_1_3_1_1_5_1_1 - 0.299999999999998*G0_1_1_4_1_0_0_0_0 - 0.299999999999998*G0_1_1_4_1_0_0_0_1 + 0.299999999999998*G0_1_1_4_1_0_1_0_0 + 0.299999999999998*G0_1_1_4_1_0_2_0_1 - 0.299999999999998*G0_1_1_4_1_0_3_1_0 - 0.299999999999998*G0_1_1_4_1_0_3_1_1 + 0.299999999999998*G0_1_1_4_1_0_4_1_0 + 0.299999999999998*G0_1_1_4_1_0_5_1_1 - 0.299999999999998*G0_1_1_5_1_1_0_0_0 - 0.299999999999998*G0_1_1_5_1_1_0_0_1 + 0.299999999999998*G0_1_1_5_1_1_1_0_0 + 0.299999999999998*G0_1_1_5_1_1_2_0_1 - 0.299999999999998*G0_1_1_5_1_1_3_1_0 - 0.299999999999998*G0_1_1_5_1_1_3_1_1 + 0.299999999999998*G0_1_1_5_1_1_4_1_0 + 0.299999999999998*G0_1_1_5_1_1_5_1_1; + A[265] = 0.0; + A[6] = A[216]; + A[27] = -A[24] + 0.375000000000003*G0_0_0_0_0_0_0_0_0 + 0.375000000000003*G0_0_0_0_0_0_0_0_1 - 0.375000000000003*G0_0_0_0_0_0_1_0_0 - 0.375000000000003*G0_0_0_0_0_0_2_0_1 + 0.375000000000003*G0_0_0_0_0_0_3_1_0 + 0.375000000000003*G0_0_0_0_0_0_3_1_1 - 0.375000000000003*G0_0_0_0_0_0_4_1_0 - 0.375000000000003*G0_0_0_0_0_0_5_1_1 + 0.375000000000003*G0_0_0_0_0_1_0_0_0 + 0.375000000000003*G0_0_0_0_0_1_0_0_1 - 0.375000000000003*G0_0_0_0_0_1_1_0_0 - 0.375000000000003*G0_0_0_0_0_1_2_0_1 + 0.375000000000003*G0_0_0_0_0_1_3_1_0 + 0.375000000000003*G0_0_0_0_0_1_3_1_1 - 0.375000000000003*G0_0_0_0_0_1_4_1_0 - 0.375000000000003*G0_0_0_0_0_1_5_1_1 - 0.375000000000003*G0_0_0_1_0_0_0_0_0 - 0.375000000000003*G0_0_0_1_0_0_0_0_1 + 0.375000000000003*G0_0_0_1_0_0_1_0_0 + 0.375000000000003*G0_0_0_1_0_0_2_0_1 - 0.375000000000003*G0_0_0_1_0_0_3_1_0 - 0.375000000000003*G0_0_0_1_0_0_3_1_1 + 0.375000000000003*G0_0_0_1_0_0_4_1_0 + 0.375000000000003*G0_0_0_1_0_0_5_1_1 - 0.375000000000003*G0_0_0_2_0_1_0_0_0 - 0.375000000000003*G0_0_0_2_0_1_0_0_1 + 0.375000000000003*G0_0_0_2_0_1_1_0_0 + 0.375000000000003*G0_0_0_2_0_1_2_0_1 - 0.375000000000003*G0_0_0_2_0_1_3_1_0 - 0.375000000000003*G0_0_0_2_0_1_3_1_1 + 0.375000000000003*G0_0_0_2_0_1_4_1_0 + 0.375000000000003*G0_0_0_2_0_1_5_1_1 + 0.375000000000003*G0_0_0_3_1_0_0_0_0 + 0.375000000000003*G0_0_0_3_1_0_0_0_1 - 0.375000000000003*G0_0_0_3_1_0_1_0_0 - 0.375000000000003*G0_0_0_3_1_0_2_0_1 + 0.375000000000003*G0_0_0_3_1_0_3_1_0 + 0.375000000000003*G0_0_0_3_1_0_3_1_1 - 0.375000000000003*G0_0_0_3_1_0_4_1_0 - 0.375000000000003*G0_0_0_3_1_0_5_1_1 + 0.375000000000003*G0_0_0_3_1_1_0_0_0 + 0.375000000000003*G0_0_0_3_1_1_0_0_1 - 0.375000000000003*G0_0_0_3_1_1_1_0_0 - 0.375000000000003*G0_0_0_3_1_1_2_0_1 + 0.375000000000003*G0_0_0_3_1_1_3_1_0 + 0.375000000000003*G0_0_0_3_1_1_3_1_1 - 0.375000000000003*G0_0_0_3_1_1_4_1_0 - 0.375000000000003*G0_0_0_3_1_1_5_1_1 - 0.375000000000003*G0_0_0_4_1_0_0_0_0 - 0.375000000000003*G0_0_0_4_1_0_0_0_1 + 0.375000000000003*G0_0_0_4_1_0_1_0_0 + 0.375000000000003*G0_0_0_4_1_0_2_0_1 - 0.375000000000003*G0_0_0_4_1_0_3_1_0 - 0.375000000000003*G0_0_0_4_1_0_3_1_1 + 0.375000000000003*G0_0_0_4_1_0_4_1_0 + 0.375000000000003*G0_0_0_4_1_0_5_1_1 - 0.375000000000003*G0_0_0_5_1_1_0_0_0 - 0.375000000000003*G0_0_0_5_1_1_0_0_1 + 0.375000000000003*G0_0_0_5_1_1_1_0_0 + 0.375000000000003*G0_0_0_5_1_1_2_0_1 - 0.375000000000003*G0_0_0_5_1_1_3_1_0 - 0.375000000000003*G0_0_0_5_1_1_3_1_1 + 0.375000000000003*G0_0_0_5_1_1_4_1_0 + 0.375000000000003*G0_0_0_5_1_1_5_1_1; + A[44] = -A[257] + 0.712500000000004*G0_1_0_0_0_0_0_0_0 + 0.712500000000004*G0_1_0_0_0_0_0_0_1 - 0.712500000000004*G0_1_0_0_0_0_1_0_0 - 0.712500000000004*G0_1_0_0_0_0_2_0_1 + 0.712500000000004*G0_1_0_0_0_0_3_1_0 + 0.712500000000004*G0_1_0_0_0_0_3_1_1 - 0.712500000000004*G0_1_0_0_0_0_4_1_0 - 0.712500000000004*G0_1_0_0_0_0_5_1_1 + 0.712500000000004*G0_1_0_0_0_1_0_0_0 + 0.712500000000004*G0_1_0_0_0_1_0_0_1 - 0.712500000000004*G0_1_0_0_0_1_1_0_0 - 0.712500000000004*G0_1_0_0_0_1_2_0_1 + 0.712500000000004*G0_1_0_0_0_1_3_1_0 + 0.712500000000004*G0_1_0_0_0_1_3_1_1 - 0.712500000000004*G0_1_0_0_0_1_4_1_0 - 0.712500000000004*G0_1_0_0_0_1_5_1_1 - 0.712500000000004*G0_1_0_1_0_0_0_0_0 - 0.712500000000004*G0_1_0_1_0_0_0_0_1 + 0.712500000000004*G0_1_0_1_0_0_1_0_0 + 0.712500000000004*G0_1_0_1_0_0_2_0_1 - 0.712500000000004*G0_1_0_1_0_0_3_1_0 - 0.712500000000004*G0_1_0_1_0_0_3_1_1 + 0.712500000000004*G0_1_0_1_0_0_4_1_0 + 0.712500000000004*G0_1_0_1_0_0_5_1_1 - 0.712500000000004*G0_1_0_2_0_1_0_0_0 - 0.712500000000004*G0_1_0_2_0_1_0_0_1 + 0.712500000000004*G0_1_0_2_0_1_1_0_0 + 0.712500000000004*G0_1_0_2_0_1_2_0_1 - 0.712500000000004*G0_1_0_2_0_1_3_1_0 - 0.712500000000004*G0_1_0_2_0_1_3_1_1 + 0.712500000000004*G0_1_0_2_0_1_4_1_0 + 0.712500000000004*G0_1_0_2_0_1_5_1_1 + 0.712500000000004*G0_1_0_3_1_0_0_0_0 + 0.712500000000004*G0_1_0_3_1_0_0_0_1 - 0.712500000000004*G0_1_0_3_1_0_1_0_0 - 0.712500000000004*G0_1_0_3_1_0_2_0_1 + 0.712500000000004*G0_1_0_3_1_0_3_1_0 + 0.712500000000004*G0_1_0_3_1_0_3_1_1 - 0.712500000000004*G0_1_0_3_1_0_4_1_0 - 0.712500000000004*G0_1_0_3_1_0_5_1_1 + 0.712500000000004*G0_1_0_3_1_1_0_0_0 + 0.712500000000004*G0_1_0_3_1_1_0_0_1 - 0.712500000000004*G0_1_0_3_1_1_1_0_0 - 0.712500000000004*G0_1_0_3_1_1_2_0_1 + 0.712500000000004*G0_1_0_3_1_1_3_1_0 + 0.712500000000004*G0_1_0_3_1_1_3_1_1 - 0.712500000000004*G0_1_0_3_1_1_4_1_0 - 0.712500000000004*G0_1_0_3_1_1_5_1_1 - 0.712500000000004*G0_1_0_4_1_0_0_0_0 - 0.712500000000004*G0_1_0_4_1_0_0_0_1 + 0.712500000000004*G0_1_0_4_1_0_1_0_0 + 0.712500000000004*G0_1_0_4_1_0_2_0_1 - 0.712500000000004*G0_1_0_4_1_0_3_1_0 - 0.712500000000004*G0_1_0_4_1_0_3_1_1 + 0.712500000000004*G0_1_0_4_1_0_4_1_0 + 0.712500000000004*G0_1_0_4_1_0_5_1_1 - 0.712500000000004*G0_1_0_5_1_1_0_0_0 - 0.712500000000004*G0_1_0_5_1_1_0_0_1 + 0.712500000000004*G0_1_0_5_1_1_1_0_0 + 0.712500000000004*G0_1_0_5_1_1_2_0_1 - 0.712500000000004*G0_1_0_5_1_1_3_1_0 - 0.712500000000004*G0_1_0_5_1_1_3_1_1 + 0.712500000000004*G0_1_0_5_1_1_4_1_0 + 0.712500000000004*G0_1_0_5_1_1_5_1_1; + A[256] = -A[44] - 0.637500000000002*G0_1_1_0_0_0_0_0_0 - 0.637500000000002*G0_1_1_0_0_0_0_0_1 + 0.637500000000002*G0_1_1_0_0_0_1_0_0 + 0.637500000000002*G0_1_1_0_0_0_2_0_1 - 0.637500000000002*G0_1_1_0_0_0_3_1_0 - 0.637500000000002*G0_1_1_0_0_0_3_1_1 + 0.637500000000002*G0_1_1_0_0_0_4_1_0 + 0.637500000000002*G0_1_1_0_0_0_5_1_1 - 0.637500000000002*G0_1_1_0_0_1_0_0_0 - 0.637500000000002*G0_1_1_0_0_1_0_0_1 + 0.637500000000002*G0_1_1_0_0_1_1_0_0 + 0.637500000000002*G0_1_1_0_0_1_2_0_1 - 0.637500000000002*G0_1_1_0_0_1_3_1_0 - 0.637500000000002*G0_1_1_0_0_1_3_1_1 + 0.637500000000002*G0_1_1_0_0_1_4_1_0 + 0.637500000000002*G0_1_1_0_0_1_5_1_1 + 0.637500000000002*G0_1_1_1_0_0_0_0_0 + 0.637500000000002*G0_1_1_1_0_0_0_0_1 - 0.637500000000002*G0_1_1_1_0_0_1_0_0 - 0.637500000000002*G0_1_1_1_0_0_2_0_1 + 0.637500000000002*G0_1_1_1_0_0_3_1_0 + 0.637500000000002*G0_1_1_1_0_0_3_1_1 - 0.637500000000002*G0_1_1_1_0_0_4_1_0 - 0.637500000000002*G0_1_1_1_0_0_5_1_1 + 0.637500000000002*G0_1_1_2_0_1_0_0_0 + 0.637500000000002*G0_1_1_2_0_1_0_0_1 - 0.637500000000002*G0_1_1_2_0_1_1_0_0 - 0.637500000000002*G0_1_1_2_0_1_2_0_1 + 0.637500000000002*G0_1_1_2_0_1_3_1_0 + 0.637500000000002*G0_1_1_2_0_1_3_1_1 - 0.637500000000002*G0_1_1_2_0_1_4_1_0 - 0.637500000000002*G0_1_1_2_0_1_5_1_1 - 0.637500000000002*G0_1_1_3_1_0_0_0_0 - 0.637500000000002*G0_1_1_3_1_0_0_0_1 + 0.637500000000002*G0_1_1_3_1_0_1_0_0 + 0.637500000000002*G0_1_1_3_1_0_2_0_1 - 0.637500000000002*G0_1_1_3_1_0_3_1_0 - 0.637500000000002*G0_1_1_3_1_0_3_1_1 + 0.637500000000002*G0_1_1_3_1_0_4_1_0 + 0.637500000000002*G0_1_1_3_1_0_5_1_1 - 0.637500000000002*G0_1_1_3_1_1_0_0_0 - 0.637500000000002*G0_1_1_3_1_1_0_0_1 + 0.637500000000002*G0_1_1_3_1_1_1_0_0 + 0.637500000000002*G0_1_1_3_1_1_2_0_1 - 0.637500000000002*G0_1_1_3_1_1_3_1_0 - 0.637500000000002*G0_1_1_3_1_1_3_1_1 + 0.637500000000002*G0_1_1_3_1_1_4_1_0 + 0.637500000000002*G0_1_1_3_1_1_5_1_1 + 0.637500000000002*G0_1_1_4_1_0_0_0_0 + 0.637500000000002*G0_1_1_4_1_0_0_0_1 - 0.637500000000002*G0_1_1_4_1_0_1_0_0 - 0.637500000000002*G0_1_1_4_1_0_2_0_1 + 0.637500000000002*G0_1_1_4_1_0_3_1_0 + 0.637500000000002*G0_1_1_4_1_0_3_1_1 - 0.637500000000002*G0_1_1_4_1_0_4_1_0 - 0.637500000000002*G0_1_1_4_1_0_5_1_1 + 0.637500000000002*G0_1_1_5_1_1_0_0_0 + 0.637500000000002*G0_1_1_5_1_1_0_0_1 - 0.637500000000002*G0_1_1_5_1_1_1_0_0 - 0.637500000000002*G0_1_1_5_1_1_2_0_1 + 0.637500000000002*G0_1_1_5_1_1_3_1_0 + 0.637500000000002*G0_1_1_5_1_1_3_1_1 - 0.637500000000002*G0_1_1_5_1_1_4_1_0 - 0.637500000000002*G0_1_1_5_1_1_5_1_1; + A[46] = A[256]; + A[109] = A[393]; + A[126] = A[273]; + A[98] = 0.0; + A[147] = A[273]; + A[119] = 0.0; + A[380] = 0.0; + A[356] = A[165]; + A[161] = A[371]; + A[318] = A[165]; + A[238] = A[28]; + A[332] = A[122]; + A[139] = 0.0; + A[389] = 0.0; + A[349] = 0.0; + A[374] = A[143]; + A[168] = A[273]; + A[185] = A[393]; + A[202] = 0.0; + A[231] = A[21]; + A[284] = 0.0; + A[252] = -11.3333333333335*A[257]; + A[37] = 0.0; + A[301] = 0.0; + A[277] = A[143]; + A[10] = 0.0; + A[67] = A[143]; + A[31] = 0.0; + A[80] = A[214]; + A[105] = A[273]; + A[323] = 0.0; + A[130] = 0.0; + A[394] = A[299]; + A[342] = 0.0; + A[159] = 0.0; + A[369] = 0.0; + A[175] = 0.0; + A[194] = 0.0; + A[213] = A[214]; + A[220] = 0.0; + A[196] = 0.0; + A[295] = A[85]; + A[251] = A[41]; + A[314] = A[85]; + A[270] = A[214]; + A[57] = 0.0; + A[1] = -A[41] - 0.0875000000000007*G0_0_0_0_0_0_0_0_0 - 0.0875000000000007*G0_0_0_0_0_0_0_0_1 + 0.0875000000000007*G0_0_0_0_0_0_1_0_0 + 0.0875000000000007*G0_0_0_0_0_0_2_0_1 - 0.0875000000000007*G0_0_0_0_0_0_3_1_0 - 0.0875000000000007*G0_0_0_0_0_0_3_1_1 + 0.0875000000000007*G0_0_0_0_0_0_4_1_0 + 0.0875000000000007*G0_0_0_0_0_0_5_1_1 - 0.0875000000000007*G0_0_0_0_0_1_0_0_0 - 0.0875000000000007*G0_0_0_0_0_1_0_0_1 + 0.0875000000000007*G0_0_0_0_0_1_1_0_0 + 0.0875000000000007*G0_0_0_0_0_1_2_0_1 - 0.0875000000000007*G0_0_0_0_0_1_3_1_0 - 0.0875000000000007*G0_0_0_0_0_1_3_1_1 + 0.0875000000000007*G0_0_0_0_0_1_4_1_0 + 0.0875000000000007*G0_0_0_0_0_1_5_1_1 + 0.0875000000000007*G0_0_0_1_0_0_0_0_0 + 0.0875000000000007*G0_0_0_1_0_0_0_0_1 - 0.0875000000000007*G0_0_0_1_0_0_1_0_0 - 0.0875000000000007*G0_0_0_1_0_0_2_0_1 + 0.0875000000000007*G0_0_0_1_0_0_3_1_0 + 0.0875000000000007*G0_0_0_1_0_0_3_1_1 - 0.0875000000000007*G0_0_0_1_0_0_4_1_0 - 0.0875000000000007*G0_0_0_1_0_0_5_1_1 + 0.0875000000000007*G0_0_0_2_0_1_0_0_0 + 0.0875000000000007*G0_0_0_2_0_1_0_0_1 - 0.0875000000000007*G0_0_0_2_0_1_1_0_0 - 0.0875000000000007*G0_0_0_2_0_1_2_0_1 + 0.0875000000000007*G0_0_0_2_0_1_3_1_0 + 0.0875000000000007*G0_0_0_2_0_1_3_1_1 - 0.0875000000000007*G0_0_0_2_0_1_4_1_0 - 0.0875000000000007*G0_0_0_2_0_1_5_1_1 - 0.0875000000000007*G0_0_0_3_1_0_0_0_0 - 0.0875000000000007*G0_0_0_3_1_0_0_0_1 + 0.0875000000000007*G0_0_0_3_1_0_1_0_0 + 0.0875000000000007*G0_0_0_3_1_0_2_0_1 - 0.0875000000000007*G0_0_0_3_1_0_3_1_0 - 0.0875000000000007*G0_0_0_3_1_0_3_1_1 + 0.0875000000000007*G0_0_0_3_1_0_4_1_0 + 0.0875000000000007*G0_0_0_3_1_0_5_1_1 - 0.0875000000000007*G0_0_0_3_1_1_0_0_0 - 0.0875000000000007*G0_0_0_3_1_1_0_0_1 + 0.0875000000000007*G0_0_0_3_1_1_1_0_0 + 0.0875000000000007*G0_0_0_3_1_1_2_0_1 - 0.0875000000000007*G0_0_0_3_1_1_3_1_0 - 0.0875000000000007*G0_0_0_3_1_1_3_1_1 + 0.0875000000000007*G0_0_0_3_1_1_4_1_0 + 0.0875000000000007*G0_0_0_3_1_1_5_1_1 + 0.0875000000000007*G0_0_0_4_1_0_0_0_0 + 0.0875000000000007*G0_0_0_4_1_0_0_0_1 - 0.0875000000000007*G0_0_0_4_1_0_1_0_0 - 0.0875000000000007*G0_0_0_4_1_0_2_0_1 + 0.0875000000000007*G0_0_0_4_1_0_3_1_0 + 0.0875000000000007*G0_0_0_4_1_0_3_1_1 - 0.0875000000000007*G0_0_0_4_1_0_4_1_0 - 0.0875000000000007*G0_0_0_4_1_0_5_1_1 + 0.0875000000000007*G0_0_0_5_1_1_0_0_0 + 0.0875000000000007*G0_0_0_5_1_1_0_0_1 - 0.0875000000000007*G0_0_0_5_1_1_1_0_0 - 0.0875000000000007*G0_0_0_5_1_1_2_0_1 + 0.0875000000000007*G0_0_0_5_1_1_3_1_0 + 0.0875000000000007*G0_0_0_5_1_1_3_1_1 - 0.0875000000000007*G0_0_0_5_1_1_4_1_0 - 0.0875000000000007*G0_0_0_5_1_1_5_1_1; + A[72] = 0.0; + A[32] = 0.0; + A[95] = 0.0; + A[51] = 0.0; + A[114] = 0.0; + A[78] = 0.0; + A[133] = 0.0; + A[148] = A[358]; + A[360] = 0.0; + A[336] = A[273]; + A[242] = 0.0; + A[263] = 0.0; + A[25] = A[235]; + A[42] = A[252]; + A[124] = A[86]; + A[141] = A[351]; + A[117] = 0.0; + A[382] = 0.0; + A[163] = A[278]; + A[182] = 0.0; + A[283] = 0.0; + A[60] = A[214]; + A[334] = A[86]; + A[137] = 0.0; + A[391] = 0.0; + A[355] = A[145]; + A[372] = A[257]; + A[170] = 0.0; + A[191] = 0.0; + A[200] = 0.0; + A[176] = 0.0; + A[233] = A[23]; + A[290] = A[214]; + A[254] = A[44]; + A[303] = 0.0; + A[275] = A[85]; + A[12] = 0.0; + A[69] = A[393]; + A[29] = 0.0; + A[82] = A[292]; + A[54] = 0.0; + A[103] = A[85]; + A[325] = 0.0; + A[128] = A[165]; + A[396] = A[379]; + A[340] = 0.0; + A[153] = 0.0; + A[367] = 0.0; + A[192] = 0.0; + A[211] = A[1]; + A[222] = 0.0; + A[293] = A[83]; + A[245] = 0.0; + A[308] = 0.0; + A[268] = 0.0; + A[3] = A[214]; + A[74] = 0.0; + A[22] = A[232]; + A[89] = A[299]; + A[49] = 0.0; + A[112] = 0.0; + A[123] = A[85]; + A[150] = 0.0; + A[338] = A[165]; + A[359] = A[299]; + A[317] = A[145]; + A[261] = 0.0; + A[237] = A[27]; + A[40] = A[250]; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f2_p1_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 3, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), Product(IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 2; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q3_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q3_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q3_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q4_excafe.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q4_excafe.h new file mode 100644 index 0000000..b03395f --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q4_excafe.h @@ -0,0 +1,1226 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 12 minutes and 37.29 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + A[819] = 0.0000000000000000000000000; + A[442] = 0.0000000000000000000000000; + const double var_0 = -x[0][0]; + const double var_1 = x[2][0] + var_0; + const double var_2 = -x[0][1]; + const double var_3 = x[2][1] + var_2; + const double var_4 = x[1][0] + var_0; + const double var_5 = x[1][1] + var_2; + const double var_6 = -var_1*var_5 + var_3*var_4; + const double var_7 = var_6; + const double var_8 = std::abs(var_7); + const double var_9 = var_6; + const double var_10 = var_4*var_4*var_4*var_4*w[0][3]*w[1][3] + var_5*var_5*var_5*var_5*w[0][0]*w[1][0]; + const double var_11 = var_1*var_1; + const double var_12 = var_4*var_4; + const double var_13 = var_11 + var_12; + const double var_14 = var_5*w[0][2] + var_1*w[0][4]; + const double var_15 = var_3*w[0][1] + var_4*w[0][5]; + const double var_16 = -var_14 + var_15; + const double var_17 = var_3*w[1][1] + var_4*w[1][5]; + const double var_18 = var_5*w[1][2] + var_1*w[1][4]; + const double var_19 = var_17 + -var_18; + const double var_20 = var_19*w[0][3] + var_16*w[1][3]; + const double var_21 = var_14 + -var_15; + const double var_22 = -var_17 + var_18; + const double var_23 = var_22*w[0][3] + var_21*w[1][3]; + const double var_24 = var_17*var_21 + var_16*var_18; + const double var_25 = var_1*var_23 + -var_13*w[0][3]*w[1][3] + var_20*var_4 + var_24; + const double var_26 = 2.0000000000000000000000000*var_1*var_4*w[0][3]*w[1][3] + var_25; + const double var_27 = w[0][3]*w[1][0] + w[0][0]*w[1][3]; + const double var_28 = var_21*w[1][0] + var_22*w[0][0]; + const double var_29 = -var_1 + var_4; + const double var_30 = var_28 + var_27*var_29; + const double var_31 = var_30*var_5 + var_26; + const double var_32 = var_19*w[0][0] + var_16*w[1][0]; + const double var_33 = var_3*var_3; + const double var_34 = var_5*var_5; + const double var_35 = var_33 + var_34; + const double var_36 = -var_35*w[0][0]*w[1][0]; + const double var_37 = var_36 + var_3*var_32 + var_28*var_5 + var_24; + const double var_38 = 2.0000000000000000000000000*var_3*var_5*w[0][0]*w[1][0]; + const double var_39 = var_37 + var_38; + const double var_40 = var_5 + -var_3; + const double var_41 = var_20 + var_27*var_40; + const double var_42 = var_39 + var_4*var_41; + const double var_43 = var_31*var_5*var_5 + var_4*var_4*var_42 + -var_10; + const double var_44 = var_3*var_3*var_3*var_5*w[0][0]*w[1][0] + var_1*var_1*var_1*var_4*w[0][3]*w[1][3]; + const double var_45 = var_1*var_4*var_4*var_4*w[0][3]*w[1][3] + var_3*var_5*var_5*var_5*w[0][0]*w[1][0]; + const double var_46 = var_3*var_3*var_30*var_5; + const double var_47 = var_1*var_1*var_4*var_41 + var_46; + const double var_48 = -var_4 + var_1; + const double var_49 = var_32 + var_27*var_48; + const double var_50 = var_3 + -var_5; + const double var_51 = var_23 + var_27*var_50; + const double var_52 = var_3*var_49*var_5*var_5 + var_1*var_4*var_4*var_51; + const double var_53 = var_16*var_17 + var_18*var_21; + const double var_54 = var_23*var_4 + var_53 + var_1*var_20; + const double var_55 = var_54 + var_13*w[0][3]*w[1][3]; + const double var_56 = -2.0000000000000000000000000*var_1*var_4*w[0][3]*w[1][3] + var_55; + const double var_57 = var_35*w[0][0]*w[1][0]; + const double var_58 = var_53 + var_32*var_5 + var_28*var_3 + var_57; + const double var_59 = -2.0000000000000000000000000*var_3*var_5*w[0][0]*w[1][0]; + const double var_60 = var_58 + var_59; + const double var_61 = var_1*var_1*var_1*var_41; + const double var_62 = var_1*var_1*var_1*var_1*w[0][3]*w[1][3] + var_3*var_3*var_3*var_3*w[0][0]*w[1][0]; + const double var_63 = var_3*var_3*var_3*var_30 + var_62; + const double var_64 = var_61 + var_3*var_3*var_56 + var_63 + var_1*var_1*var_60; + const double var_65 = 0.0158730158730158721347436*var_64; + const double var_66 = var_1*var_1*var_4*var_4*w[0][3]*w[1][3] + var_3*var_3*var_5*var_5*w[0][0]*w[1][0]; + const double var_67 = -var_66; + const double var_68 = var_3*var_5*var_56 + var_1*var_4*var_60; + const double var_69 = 0.3333333333333333148296163*var_68; + const double var_70 = var_67 + var_69; + const double var_71 = 0.1968253968253968200219362*var_70; + const double var_72 = var_65 + 0.0497354497354497368521997*var_47 + 0.0338624338624338647174561*var_44 + 0.2285714285714285642914234*var_45 + 0.1470899470899471039864181*var_52 + var_71 + 0.0814814814814814880605809*var_43; + A[6] = 8.0000000000000000000000000*var_72*var_8/(var_9*var_9*var_9*var_9); + A[471] = A[6]; + const double var_73 = var_26*var_3*var_5 + var_1*var_39*var_4; + const double var_74 = var_3*var_30*var_5*var_5; + const double var_75 = var_1*var_4*var_4*var_41 + var_74; + const double var_76 = var_3*var_3*var_49*var_5; + const double var_77 = var_1*var_1*var_4*var_51 + var_76; + const double var_78 = var_75 + var_77; + const double var_79 = 2.0000000000000000000000000*var_66 + var_78; + const double var_80 = var_45 + var_44; + const double var_81 = var_3*var_49; + const double var_82 = var_26 + var_81; + const double var_83 = var_1*var_51 + var_39; + const double var_84 = var_3*var_3*var_82 + -var_62 + var_1*var_1*var_83; + const double var_85 = var_84 + var_43; + const double var_86 = -0.1703703703703703664640301*var_80 + 0.2000000000000000111022302*var_73 + 0.1851851851851851749053424*var_79 + 0.0148148148148148153802062*var_85; + A[189] = 9.1428571428571423496123316*var_8*var_86/(var_9*var_9*var_9*var_9); + A[276] = A[189]; + const double var_87 = -var_1*var_4*w[0][3]*w[1][3] + 0.5000000000000000000000000*var_55; + const double var_88 = var_3*var_3*var_87 + 0.5000000000000000000000000*var_63; + const double var_89 = -var_3*var_5*w[0][0]*w[1][0]; + const double var_90 = var_49*var_5; + const double var_91 = var_57 + var_3*var_30 + var_90; + const double var_92 = var_91 + var_54; + const double var_93 = var_89 + 0.5000000000000000000000000*var_92; + const double var_94 = -var_44; + const double var_95 = 0.5000000000000000000000000*var_66; + const double var_96 = 0.5000000000000000000000000*var_76 + var_1*var_1*var_93 + var_88 + var_94 + var_95; + A[31] = 0.7460317460317460458441019*var_8*var_96/(var_9*var_9*var_9*var_9); + const double var_97 = var_4*var_4*var_4*var_51; + const double var_98 = var_56 + var_90; + const double var_99 = var_97 + var_4*var_4*var_60 + var_10 + var_5*var_5*var_98; + const double var_100 = var_77 + var_94; + const double var_101 = var_73 + var_100; + const double var_102 = 0.3333333333333333148296163*var_101; + const double var_103 = 1.0666666666666666518636930*var_66; + const double var_104 = 0.7333333333333332815229255*var_75 + var_102 + -1.1333333333333333037273860*var_45 + 0.4000000000000000222044605*var_99 + var_103; + A[162] = 2.0317460317460316332471848*var_104*var_8/(var_9*var_9*var_9*var_9); + A[628] = A[162]; + const double var_105 = 0.2952380952380952439106920*var_73 + 0.6190476190476190687661529*var_66; + A[23] = 0.0000000000000000000000000; + const double var_106 = 0.0095238095238095246686250*var_84; + const double var_107 = -0.1523809523809523946979994*var_66; + const double var_108 = 0.3333333333333333148296163*var_43; + const double var_109 = 0.6666666666666666296592325*var_52 + var_45 + var_108; + const double var_110 = var_109 + var_69; + const double var_111 = 0.1428571428571428492126927*var_110; + const double var_112 = 0.3333333333333333148296163*var_44; + const double var_113 = 0.2000000000000000111022302*var_112; + const double var_114 = var_111 + var_106 + 0.0571428571428571410728559*var_47 + var_107 + var_113; + A[374] = 85.3333333333333285963817616*var_114*var_8/(var_9*var_9*var_9*var_9); + A[839] = A[374]; + A[731] = 0.0000000000000000000000000; + const double var_115 = -var_45; + const double var_116 = 0.6666666666666666296592325*var_75 + var_115 + 0.3333333333333333148296163*var_99; + const double var_117 = 0.3333333333333333148296163*var_73; + const double var_118 = var_116 + var_117; + const double var_119 = 1.1111111111111111604543567*var_66; + const double var_120 = 0.5555555555555555802271783*var_94 + var_118 + 0.1111111111111111049432054*var_64 + 0.4444444444444444197728217*var_77 + var_119; + const double var_121 = var_99 + var_64; + const double var_122 = 1.4444444444444444197728217*var_79 + 0.4444444444444444197728217*var_121 + -1.8888888888888888395456433*var_80 + var_73; + A[132] = 0.9142857142857142571656937*var_122*var_8/(var_9*var_9*var_9*var_9); + A[829] = A[132]; + const double var_123 = 0.3333333333333333148296163*var_84; + const double var_124 = var_44 + 0.6666666666666666296592325*var_47 + var_123; + const double var_125 = var_124 + var_69; + const double var_126 = 0.1428571428571428492126927*var_125; + A[581] = 0.0000000000000000000000000; + A[47] = 0.0000000000000000000000000; + A[760] = 0.0000000000000000000000000; + const double var_127 = var_45 + var_68 + var_52; + const double var_128 = 3.9047619047619046561692357*var_44; + const double var_129 = -3.6666666666666665186369300*var_66; + const double var_130 = var_128 + 1.3809523809523809312338471*var_84 + 1.1428571428571427937015414*var_127 + 2.5238095238095237249353886*var_47 + var_129; + A[39] = 0.1777777777777777845624740*var_130*var_8/(var_9*var_9*var_9*var_9); + A[271] = A[39]; + A[202] = 0.0000000000000000000000000; + const double var_131 = var_47 + var_68 + var_44; + const double var_132 = -0.7333333333333332815229255*var_66; + const double var_133 = var_108 + 0.8666666666666666962726140*var_45 + 0.2000000000000000111022302*var_131 + 0.5333333333333333259318465*var_52 + var_132; + A[161] = 1.0158730158730158166235924*var_133*var_8/(var_9*var_9*var_9*var_9); + A[335] = A[161]; + A[578] = 0.0000000000000000000000000; + const double var_134 = var_75 + var_115; + const double var_135 = var_73 + var_134; + const double var_136 = 0.3714285714285714412596917*var_66; + const double var_137 = 0.2000000000000000111022302*var_94 + 0.1809523809523809756427681*var_135 + 0.1904761904761904656169236*var_77 + 0.0095238095238095246686250*var_64 + var_136; + A[484] = 0.0000000000000000000000000; + const double var_138 = 0.3333333333333333148296163*var_45; + const double var_139 = 0.0571428571428571410728559*var_84; + const double var_140 = 0.1619047619047619124277304*var_70; + const double var_141 = var_139 + 0.0507936507936507936067372*var_52 + 0.0031746031746031746004211*var_99 + 0.1111111111111111049432054*var_47 + 0.1682539682539682668327430*var_44 + 0.1428571428571428492126927*var_138 + var_140; + A[192] = 42.6666666666666642981908808*var_141*var_8/(var_9*var_9*var_9*var_9); + A[453] = 0.0000000000000000000000000; + const double var_142 = 0.0095238095238095246686250*var_99 + 0.2000000000000000111022302*var_115 + 0.1809523809523809756427681*var_101 + 0.1904761904761904656169236*var_75 + var_136; + A[254] = 14.2222222222222214327302936*var_142*var_8/(var_9*var_9*var_9*var_9); + A[428] = A[254]; + A[136] = 0.0000000000000000000000000; + A[487] = 0.0000000000000000000000000; + A[841] = 0.0000000000000000000000000; + A[147] = 0.0000000000000000000000000; + const double var_143 = 0.2000000000000000111022302*var_138; + const double var_144 = 0.2000000000000000111022302*var_67; + const double var_145 = var_143 + 0.1111111111111111049432054*var_131 + 0.0888888888888888922812370*var_52 + var_144 + 0.0222222222222222230703093*var_99; + A[252] = 6.0952380952380948997415544*var_145*var_8/(var_9*var_9*var_9*var_9); + const double var_146 = var_47 + var_52; + const double var_147 = 0.3333333333333333148296163*var_85; + const double var_148 = var_146 + 1.3333333333333332593184650*var_80 + 2.0000000000000000000000000*var_70 + var_147; + A[12] = 0.2539682539682539541558981*var_148*var_8/(var_9*var_9*var_9*var_9); + A[390] = A[12]; + A[437] = 0.0000000000000000000000000; + const double var_149 = 0.1746031746031745934821799*var_73 + 0.5111111111111111826588171*var_66; + const double var_150 = 0.1936507936507936566972177*var_75 + 0.3174603174603174426948726*var_77 + -0.4603174603174602919075653*var_44 + -0.2126984126984126921566798*var_45 + 0.0190476190476190493372499*var_99 + 0.1428571428571428492126927*var_64 + var_149; + A[157] = 5.3333333333333330372738601*var_150*var_8/(var_9*var_9*var_9*var_9); + A[680] = A[157]; + const double var_151 = 297.3333333333333143855270464*var_66; + const double var_152 = 142.0000000000000000000000000*var_77 + 233.0000000000000000000000000*var_118 + 64.3333333333333285963817616*var_64 + -206.3333333333333143855270464*var_44 + var_151; + A[217] = 0.0380952380952380986744998*var_152*var_8/(var_9*var_9*var_9*var_9); + A[584] = 0.0000000000000000000000000; + A[87] = 0.0000000000000000000000000; + const double var_153 = -0.9047619047619047671915382*var_66; + const double var_154 = 0.8857142857142856762209249*var_110 + var_153 + 0.0190476190476190493372499*var_84 + 0.3142857142857142793701541*var_47 + var_112; + A[101] = 7.1111111111111107163651468*var_154*var_8/(var_9*var_9*var_9*var_9); + A[333] = A[101]; + A[264] = 0.0000000000000000000000000; + A[638] = 0.0000000000000000000000000; + const double var_155 = 0.3238095238095238248554608*var_70; + const double var_156 = 0.0476190476190476164042309*var_108; + const double var_157 = var_155 + 0.2000000000000000111022302*var_47 + 0.1396825396825396858879742*var_45 + 0.2920634920634920805859736*var_44 + 0.1238095238095238276310184*var_52 + 0.0920634920634920694837433*var_84 + var_156; + A[346] = 0.0000000000000000000000000; + A[17] = 0.0000000000000000000000000; + const double var_158 = 0.0095238095238095246686250*var_43; + const double var_159 = var_126 + var_143 + var_158 + 0.0571428571428571410728559*var_52 + var_107; + A[373] = 85.3333333333333285963817616*var_159*var_8/(var_9*var_9*var_9*var_9); + const double var_160 = 1.3333333333333332593184650*var_66; + const double var_161 = 0.3333333333333333148296163*var_77; + const double var_162 = 0.6666666666666666296592325*var_84 + var_160 + var_135 + var_161 + var_112; + A[191] = 0.2031746031746031744269487*var_162*var_8/(var_9*var_9*var_9*var_9); + A[656] = A[191]; + A[45] = 0.0000000000000000000000000; + A[867] = A[373]; + A[853] = 0.0000000000000000000000000; + const double var_163 = -var_80; + const double var_164 = var_121 + var_163 + var_68; + A[95] = 0.3386243386243386055411975*var_164*var_8/(var_9*var_9*var_9*var_9); + const double var_165 = 0.6190476190476190687661529*var_70; + const double var_166 = 0.8962962962962963686663898*var_68 + -2.9777777777777778567269706*var_66; + const double var_167 = 1.7481481481481482287421159*var_52 + var_123 + 0.8518518518518518600757261*var_43 + 2.6000000000000000888178420*var_45 + 1.5629629629629631093479247*var_44 + var_166 + 1.2296296296296296279848548*var_47; + A[218] = 2.2857142857142855874030829*var_167*var_8/(var_9*var_9*var_9*var_9); + const double var_168 = 0.4095238095238095676897672*var_66; + const double var_169 = 0.1428571428571428492126927*var_108 + 0.2285714285714285642914234*var_101 + 0.1809523809523809756427681*var_75 + -0.1333333333333333314829616*var_45 + var_168; + A[63] = 0.8888888888888888395456433*var_169*var_8/(var_9*var_9*var_9*var_9); + A[528] = A[63]; + A[496] = A[31]; + A[15] = 0.0000000000000000000000000; + A[695] = 0.0000000000000000000000000; + A[50] = 0.0000000000000000000000000; + const double var_170 = -0.0698412698412698429439871*var_66 + 0.0984126984126984100109681*var_73; + const double var_171 = 0.0444444444444444461406185*var_52; + const double var_172 = 0.1428571428571428492126927*var_43; + const double var_173 = var_171 + 0.1238095238095238276310184*var_84 + 0.1492063492063492036177053*var_44 + 0.1873015873015873022922051*var_45 + 0.0253968253968253968033686*var_47 + var_170 + var_172; + A[94] = 5.3333333333333330372738601*var_173*var_8/(var_9*var_9*var_9*var_9); + A[209] = 0.0000000000000000000000000; + const double var_174 = 0.0666666666666666657414808*var_70; + A[458] = 0.0000000000000000000000000; + const double var_175 = var_94 + 0.6666666666666666296592325*var_77 + 0.3333333333333333148296163*var_64 + var_117; + const double var_176 = 0.5555555555555555802271783*var_115 + 0.4444444444444444197728217*var_75 + 0.1111111111111111049432054*var_99 + var_175 + var_119; + const double var_177 = 0.8888888888888888395456433*var_66; + const double var_178 = 0.4296296296296296390870850*var_77 + 0.2000000000000000111022302*var_64 + -0.6296296296296296501893153*var_44 + 0.6888888888888888839545643*var_118 + var_177; + A[93] = 9.1428571428571423496123316*var_178*var_8/(var_9*var_9*var_9*var_9); + A[341] = A[93]; + const double var_179 = 0.3333333333333333148296163*var_75; + const double var_180 = var_160 + var_179 + var_101 + 0.6666666666666666296592325*var_43 + var_138; + A[249] = 0.2031746031746031744269487*var_180*var_8/(var_9*var_9*var_9*var_9); + A[226] = 0.0000000000000000000000000; + const double var_181 = -0.1777777777777777845624740*var_66; + const double var_182 = 0.1174603174603174593482180*var_47 + var_181 + 0.1746031746031745934821799*var_44 + var_139 + 0.0603174603174603182753621*var_127; + A[103] = 42.6666666666666642981908808*var_182*var_8/(var_9*var_9*var_9*var_9); + A[393] = A[103]; + A[671] = 0.0000000000000000000000000; + const double var_183 = 1.7481481481481482287421159*var_47 + var_166 + 1.2296296296296296279848548*var_52 + 0.8518518518518518600757261*var_84 + 2.6000000000000000888178420*var_44 + 1.5629629629629631093479247*var_45 + var_108; + A[311] = 2.2857142857142855874030829*var_183*var_8/(var_9*var_9*var_9*var_9); + A[340] = A[311]; + A[201] = 0.0000000000000000000000000; + A[858] = A[103]; + A[237] = 0.0000000000000000000000000; + A[788] = 0.0000000000000000000000000; + A[360] = A[12]; + const double var_184 = var_116 + var_175 + var_160; + A[372] = 17.0666666666666664298190881*var_184*var_8/(var_9*var_9*var_9*var_9); + A[899] = A[372]; + const double var_185 = 0.2666666666666666629659233*var_43; + const double var_186 = 0.3142857142857142793701541*var_68 + var_153; + const double var_187 = var_112 + 0.5809523809523809978472286*var_52 + 0.3238095238095238248554608*var_47 + var_185 + 0.8476190476190477163243031*var_45 + var_106 + var_186; + A[313] = 10.6666666666666660745477202*var_187*var_8/(var_9*var_9*var_9*var_9); + A[865] = A[313]; + A[343] = 14.2222222222222214327302936*var_137*var_8/(var_9*var_9*var_9*var_9); + A[808] = A[343]; + const double var_188 = 0.1428571428571428492126927*var_99 + 0.3174603174603174426948726*var_75 + 0.0190476190476190493372499*var_64 + -0.2126984126984126921566798*var_44 + -0.4603174603174602919075653*var_45 + 0.1936507936507936566972177*var_77 + var_149; + A[100] = 5.3333333333333330372738601*var_188*var_8/(var_9*var_9*var_9*var_9); + A[768] = A[100]; + A[741] = A[189]; + const double var_189 = var_36 + var_38 + var_81 + var_31; + const double var_190 = var_11 + var_33; + A[42] = 0.0846560846560846513852994*var_189*var_190*var_8/(var_9*var_9*var_9*var_9); + const double var_191 = 0.4000000000000000222044605*var_66; + const double var_192 = var_45 + var_179; + const double var_193 = var_102 + var_185 + var_191 + 0.2000000000000000111022302*var_192; + const double var_194 = var_87 + 0.5000000000000000000000000*var_49*var_5; + const double var_195 = 0.5000000000000000000000000*var_10 + var_194*var_5*var_5; + const double var_196 = var_66 + var_117; + const double var_197 = 0.3333333333333333148296163*var_196; + const double var_198 = var_65 + 0.1269841269841269770779490*var_77 + 0.2063492063492063377516672*var_75 + 0.0952380952380952328084618*var_99 + -0.3015873015873015705601290*var_45 + 0.1428571428571428492126927*var_94 + var_197; + A[145] = 0.0000000000000000000000000; + A[118] = 0.0000000000000000000000000; + A[872] = 0.0000000000000000000000000; + A[229] = 0.0000000000000000000000000; + A[568] = A[103]; + const double var_199 = 0.0380952380952380986744998*var_64; + const double var_200 = var_161 + -0.3714285714285714412596917*var_44 + var_199; + const double var_201 = var_105 + 0.2857142857142856984253854*var_75 + var_200 + -0.2761904761904762084512299*var_45 + var_158; + A[880] = 0.0000000000000000000000000; + A[611] = 0.0000000000000000000000000; + A[349] = 0.0000000000000000000000000; + A[383] = 0.0000000000000000000000000; + A[693] = 0.0000000000000000000000000; + A[414] = 0.0000000000000000000000000; + A[146] = 0.0000000000000000000000000; + A[633] = 0.0000000000000000000000000; + A[356] = 0.0000000000000000000000000; + const double var_202 = var_56 + var_91 + var_59; + A[36] = 0.0423280423280423256926497*var_190*var_202*var_8/(var_9*var_9*var_9*var_9); + A[37] = A[36]; + A[642] = 0.0000000000000000000000000; + const double var_203 = 13.2666666666666657192763523*var_66; + const double var_204 = var_99 + -8.1333333333333328596381762*var_45 + 7.1333333333333328596381762*var_75 + 6.1333333333333328596381762*var_101 + var_203; + A[65] = 0.1269841269841269770779490*var_204*var_8/(var_9*var_9*var_9*var_9); + A[530] = A[65]; + const double var_205 = 0.0476190476190476164042309*var_66; + const double var_206 = 0.1904761904761904656169236*var_64; + const double var_207 = var_205 + 0.3333333333333333148296163*var_94 + 0.1428571428571428492126927*var_77 + var_111 + var_206; + A[696] = 0.0000000000000000000000000; + A[830] = A[162]; + A[328] = 0.0000000000000000000000000; + A[22] = 0.0000000000000000000000000; + const double var_208 = 0.5000000000000000000000000*var_58 + var_89; + const double var_209 = 0.3333333333333333148296163*var_195 + 0.1666666666666666574148081*var_97; + const double var_210 = 0.1666666666666666574148081*var_61 + 0.3333333333333333148296163*var_88; + const double var_211 = var_210 + var_196 + -0.6666666666666666296592325*var_80 + 0.5000000000000000000000000*var_78 + var_209 + 0.3333333333333333148296163*var_13*var_208; + A[0] = 2.2380952380952381375323057*var_211*var_8/(var_9*var_9*var_9*var_9); + const double var_212 = var_12 + var_34; + A[69] = 0.0423280423280423256926497*var_202*var_212*var_8/(var_9*var_9*var_9*var_9); + A[302] = A[69]; + const double var_213 = 2.0476190476190474498707772*var_68 + 4.0000000000000000000000000*var_67; + const double var_214 = 4.0000000000000000000000000*var_43 + 31.0000000000000000000000000*var_44; + const double var_215 = 2.2380952380952381375323057*var_52 + var_213 + 1.7619047619047618624676943*var_47 + 0.0476190476190476164042309*var_214 + 2.4285714285714283811046243*var_45 + 0.2857142857142856984253854*var_64; + A[190] = 0.3555555555555555691249481*var_215*var_8/(var_9*var_9*var_9*var_9); + A[655] = A[190]; + A[868] = A[372]; + A[13] = A[12]; + const double var_216 = var_174 + 0.0349206349206349214719936*var_44 + 0.0539682539682539708092435*var_45 + 0.0190476190476190493372499*var_123 + 0.0380952380952380986744998*var_52 + 0.0285714285714285705364279*var_47 + var_156; + A[99] = 21.3333333333333321490954404*var_216*var_8/(var_9*var_9*var_9*var_9); + A[738] = A[99]; + const double var_217 = 3.9047619047619046561692357*var_45; + const double var_218 = var_217 + 1.1428571428571427937015414*var_131 + 1.3809523809523809312338471*var_43 + 2.5238095238095237249353886*var_52 + var_129; + A[66] = 0.1777777777777777845624740*var_218*var_8/(var_9*var_9*var_9*var_9); + A[182] = A[66]; + A[413] = 0.0000000000000000000000000; + const double var_219 = -4.1428571428571423496123316*var_66; + const double var_220 = var_128 + 1.2222222222222220988641084*var_84 + 1.4603174603174602363964141*var_127 + 2.6825396825396823352605224*var_47 + var_219; + A[41] = 0.5333333333333333259318465*var_220*var_8/(var_9*var_9*var_9*var_9); + A[331] = A[41]; + A[854] = 0.0000000000000000000000000; + const double var_221 = 2.6825396825396823352605224*var_52 + var_217 + 1.2222222222222220988641084*var_43 + 1.4603174603174602363964141*var_131 + var_219; + A[68] = 0.5333333333333333259318465*var_221*var_8/(var_9*var_9*var_9*var_9); + A[707] = A[68]; + A[531] = A[66]; + A[897] = A[374]; + const double var_222 = w[0][3]*w[1][3] + w[0][0]*w[1][0]; + const double var_223 = 0.5000000000000000000000000*var_37 + var_222*var_3*var_5; + const double var_224 = 0.1666666666666666574148081*var_25*var_3*var_5 + 0.3333333333333333148296163*var_1*var_223*var_4 + var_95; + const double var_225 = var_161 + 0.5000000000000000000000000*var_94 + 0.3333333333333333148296163*var_1*var_1*var_208 + var_210 + var_224 + 0.1666666666666666574148081*var_134; + A[1] = 0.3396825396825396969902044*var_225*var_8/(var_9*var_9*var_9*var_9); + A[823] = 0.0000000000000000000000000; + A[816] = 0.0000000000000000000000000; + A[173] = 0.0000000000000000000000000; + A[814] = 0.0000000000000000000000000; + A[391] = A[42]; + const double var_226 = 0.0158730158730158721347436*var_99; + const double var_227 = 0.1269841269841269770779490*var_75 + var_226 + 0.0952380952380952328084618*var_64 + 0.1428571428571428492126927*var_115 + -0.3015873015873015705601290*var_44 + 0.2063492063492063377516672*var_77 + var_197; + A[193] = 8.5333333333333332149095440*var_227*var_8/(var_9*var_9*var_9*var_9); + A[426] = A[193]; + A[815] = 0.0000000000000000000000000; + A[481] = 0.0000000000000000000000000; + A[223] = 2.1333333333333333037273860*var_207*var_8/(var_9*var_9*var_9*var_9); + A[862] = A[223]; + const double var_228 = 0.0380952380952380986744998*var_99; + const double var_229 = var_179 + -0.3714285714285714412596917*var_45 + var_228; + const double var_230 = 0.9238095238095238581621516*var_66; + const double var_231 = var_229 + 0.8857142857142856762209249*var_175 + var_230; + A[127] = 1.3333333333333332593184650*var_231*var_8/(var_9*var_9*var_9*var_9); + A[592] = A[127]; + const double var_232 = var_200 + 0.8857142857142856762209249*var_118 + var_230; + A[130] = 1.3333333333333332593184650*var_232*var_8/(var_9*var_9*var_9*var_9); + A[595] = A[130]; + A[849] = 0.0000000000000000000000000; + A[188] = 3.0476190476190474498707772*var_120*var_8/(var_9*var_9*var_9*var_9); + A[653] = A[188]; + A[317] = 0.0000000000000000000000000; + A[840] = 0.0000000000000000000000000; + A[261] = 0.0000000000000000000000000; + A[287] = 0.0000000000000000000000000; + A[822] = 0.0000000000000000000000000; + A[548] = 0.0000000000000000000000000; + A[295] = 0.0000000000000000000000000; + A[231] = 0.0000000000000000000000000; + const double var_233 = var_1*var_4 + var_3*var_5; + A[251] = 0.2031746031746031744269487*var_189*var_233*var_8/(var_9*var_9*var_9*var_9); + A[375] = 0.0000000000000000000000000; + A[524] = 0.0000000000000000000000000; + A[266] = 0.0000000000000000000000000; + const double var_234 = 0.5000000000000000000000000*var_74 + var_195 + var_95 + var_115 + var_4*var_4*var_93; + A[62] = 0.7460317460317460458441019*var_234*var_8/(var_9*var_9*var_9*var_9); + A[527] = A[62]; + A[111] = 0.0000000000000000000000000; + A[85] = 0.0000000000000000000000000; + A[260] = 0.0000000000000000000000000; + const double var_235 = -2.5333333333333332149095440*var_66 + 0.2666666666666666629659233*var_121 + 1.5333333333333332149095440*var_68 + var_80 + 1.2666666666666666074547720*var_146; + A[220] = 0.1904761904761904656169236*var_235*var_8/(var_9*var_9*var_9*var_9); + A[307] = A[220]; + const double var_236 = var_67 + var_124 + 0.3333333333333333148296163*var_127; + A[96] = 0.6095238095238095787919974*var_236*var_8/(var_9*var_9*var_9*var_9); + A[706] = A[36]; + A[211] = A[36]; + A[877] = 0.0000000000000000000000000; + A[588] = A[94]; + A[730] = 0.0000000000000000000000000; + A[171] = 0.0000000000000000000000000; + A[674] = 0.0000000000000000000000000; + A[664] = 0.0000000000000000000000000; + A[283] = 8.5333333333333332149095440*var_198*var_8/(var_9*var_9*var_9*var_9); + A[399] = A[283]; + const double var_237 = 0.3333333333333333148296163*var_121 + var_79 + 0.6666666666666666296592325*var_73 + -1.3333333333333332593184650*var_80; + A[3] = 0.1269841269841269770779490*var_237*var_8/(var_9*var_9*var_9*var_9); + A[469] = A[3]; + const double var_238 = 0.2190476190476190743172680*var_68 + 0.6666666666666666296592325*var_67; + const double var_239 = 0.2666666666666666629659233*var_84; + const double var_240 = 0.1809523809523809756427681*var_52 + var_239 + 0.7523809523809524835158413*var_44 + 0.1428571428571428492126927*var_45 + 0.4857142857142857095276156*var_47 + var_238 + var_228; + A[134] = 10.6666666666666660745477202*var_240*var_8/(var_9*var_9*var_9*var_9); + const double var_241 = 0.1174603174603174593482180*var_66 + 0.1111111111111111049432054*var_117; + const double var_242 = -3.5428571428571427048836995*var_66 + 1.0380952380952381819412267*var_68; + const double var_243 = 1.4095238095238096232009184*var_47 + 2.1333333333333333037273860*var_52 + 0.3714285714285714412596917*var_84 + 1.7809523809523810644606101*var_44 + 3.2285714285714286475581503*var_45 + 1.0952380952380951217861593*var_43 + var_242; + A[169] = 0.0000000000000000000000000; + A[250] = 0.2539682539682539541558981*var_193*var_8/(var_9*var_9*var_9*var_9); + A[773] = A[250]; + A[234] = 0.0000000000000000000000000; + A[488] = 0.0000000000000000000000000; + const double var_244 = 4.0000000000000000000000000*var_84 + 31.0000000000000000000000000*var_45; + const double var_245 = 0.2857142857142856984253854*var_99 + 2.2380952380952381375323057*var_47 + var_213 + 0.0476190476190476164042309*var_244 + 2.4285714285714283811046243*var_44 + 1.7619047619047618624676943*var_52; + A[219] = 0.3555555555555555691249481*var_245*var_8/(var_9*var_9*var_9*var_9); + A[659] = A[193]; + const double var_246 = 0.3333333333333333148296163*var_135; + const double var_247 = var_44 + var_161; + const double var_248 = var_246 + var_239 + var_191 + 0.2000000000000000111022302*var_247; + A[221] = 0.2539682539682539541558981*var_248*var_8/(var_9*var_9*var_9*var_9); + const double var_249 = -3.6380952380952384928036736*var_66; + const double var_250 = 0.1904761904761904656169236*var_99; + const double var_251 = var_249 + 1.9142857142857141461433912*var_131 + 1.5333333333333332149095440*var_45 + 1.7238095238095239025710725*var_52 + var_250; + A[64] = 0.2222222222222222098864108*var_251*var_8/(var_9*var_9*var_9*var_9); + A[529] = A[64]; + A[402] = A[373]; + const double var_252 = 0.0571428571428571410728559*var_43; + const double var_253 = var_252 + 0.1746031746031745934821799*var_45 + 0.0603174603174603182753621*var_131 + 0.1174603174603174593482180*var_52 + var_181; + const double var_254 = 29.6666666666666642981908808*var_66; + const double var_255 = 20.0952380952380948997415544*var_77 + 10.5238095238095237249353886*var_64 + -30.6190476190476168483201036*var_44 + 9.5714285714285711748061658*var_135 + var_254; + const double var_256 = 0.3333333333333333148296163*var_163 + 0.6666666666666666296592325*var_79 + var_147 + var_73; + A[408] = 0.0000000000000000000000000; + A[417] = 0.0000000000000000000000000; + A[762] = 0.0000000000000000000000000; + A[388] = 0.0000000000000000000000000; + A[796] = A[41]; + A[494] = 0.0000000000000000000000000; + A[143] = 0.0000000000000000000000000; + A[72] = 0.0846560846560846513852994*var_189*var_212*var_8/(var_9*var_9*var_9*var_9); + A[392] = A[72]; + A[258] = 0.0000000000000000000000000; + A[780] = 0.0000000000000000000000000; + A[576] = 0.0000000000000000000000000; + A[380] = 0.0000000000000000000000000; + A[20] = 0.0000000000000000000000000; + const double var_257 = var_172 + 0.2698412698412698262906417*var_47 + 0.0158730158730158721347436*var_244 + var_112 + 0.3492063492063491869643599*var_52 + var_165; + A[129] = 1.0666666666666666518636930*var_257*var_8/(var_9*var_9*var_9*var_9); + const double var_258 = 0.0444444444444444461406185*var_47; + const double var_259 = -0.0603174603174603182753621*var_66; + const double var_260 = var_258 + 0.0730158730158730201464934*var_44 + 0.0285714285714285705364279*var_84 + 0.0158730158730158721347436*var_127 + var_259; + A[97] = 5.3333333333333330372738601*var_260*var_8/(var_9*var_9*var_9*var_9); + A[562] = A[97]; + A[622] = A[157]; + A[564] = A[99]; + A[612] = 0.0000000000000000000000000; + A[284] = A[283]; + A[518] = 0.0000000000000000000000000; + A[303] = A[100]; + const double var_261 = 0.1428571428571428492126927*var_84; + const double var_262 = var_258 + var_261 + 0.1238095238095238276310184*var_43 + 0.1492063492063492036177053*var_45 + 0.1873015873015873022922051*var_44 + 0.0253968253968253968033686*var_52 + var_170; + A[125] = 5.3333333333333330372738601*var_262*var_8/(var_9*var_9*var_9*var_9); + A[590] = A[125]; + A[727] = 0.0000000000000000000000000; + const double var_263 = 2.2952380952380955214664482*var_196; + const double var_264 = var_263 + 0.8285714285714285143313873*var_75 + 0.3333333333333333148296163*var_250 + -0.8920634920634921138926643*var_45 + -2.1682539682539681002992893*var_44 + 0.7015873015873015372534383*var_64 + 1.4666666666666665630458510*var_77; + A[10] = 0.6666666666666666296592325*var_264*var_8/(var_9*var_9*var_9*var_9); + A[300] = A[10]; + A[404] = 2.4380952380952383151679896*var_256*var_8/(var_9*var_9*var_9*var_9); + A[869] = A[404]; + A[810] = 0.0000000000000000000000000; + A[138] = 0.0000000000000000000000000; + A[850] = 0.0000000000000000000000000; + const double var_265 = var_123 + 0.5333333333333333259318465*var_47 + 0.8666666666666666962726140*var_44 + 0.2000000000000000111022302*var_127 + var_132; + A[238] = 0.0000000000000000000000000; + const double var_266 = 0.4000000000000000222044605*var_64 + var_246 + -1.1333333333333333037273860*var_44 + 0.7333333333333332815229255*var_77 + var_103; + A[102] = 2.0317460317460316332471848*var_266*var_8/(var_9*var_9*var_9*var_9); + A[144] = 0.0000000000000000000000000; + A[669] = 0.0000000000000000000000000; + A[771] = A[190]; + A[657] = A[192]; + A[268] = 0.0000000000000000000000000; + A[117] = 0.0000000000000000000000000; + A[670] = 0.0000000000000000000000000; + A[104] = A[102]; + A[53] = 0.0000000000000000000000000; + A[758] = 0.0000000000000000000000000; + A[837] = A[372]; + A[597] = A[132]; + A[288] = 0.0000000000000000000000000; + A[262] = 0.0000000000000000000000000; + A[782] = 0.0000000000000000000000000; + A[552] = 0.0000000000000000000000000; + A[320] = 0.0000000000000000000000000; + A[759] = 0.0000000000000000000000000; + A[70] = A[69]; + A[401] = A[343]; + A[663] = 0.0000000000000000000000000; + const double var_267 = var_80 + var_46; + const double var_268 = var_194*var_3*var_5 + 0.5000000000000000000000000*var_267 + var_1*var_4*var_93 + var_67; + A[32] = 0.1132275132275132323300681*var_268*var_8/(var_9*var_9*var_9*var_9); + A[497] = A[32]; + A[164] = 42.6666666666666642981908808*var_253*var_8/(var_9*var_9*var_9*var_9); + A[629] = A[164]; + const double var_269 = var_226 + 0.2285714285714285642914234*var_44 + 0.0338624338624338647174561*var_45 + 0.0497354497354497368521997*var_52 + 0.0814814814814814880605809*var_84 + var_71 + 0.1470899470899471039864181*var_47; + A[9] = 8.0000000000000000000000000*var_269*var_8/(var_9*var_9*var_9*var_9); + A[270] = A[9]; + A[292] = 0.0000000000000000000000000; + A[490] = 0.0000000000000000000000000; + A[714] = A[249]; + A[851] = 0.0000000000000000000000000; + A[678] = A[97]; + A[465] = A[0]; + A[361] = A[42]; + A[11] = 2.6666666666666665186369300*var_157*var_8/(var_9*var_9*var_9*var_9); + A[330] = A[11]; + A[736] = A[39]; + const double var_270 = var_249 + 1.9142857142857141461433912*var_127 + 1.5333333333333332149095440*var_44 + 1.7238095238095239025710725*var_47 + var_206; + A[34] = 0.2222222222222222098864108*var_270*var_8/(var_9*var_9*var_9*var_9); + A[586] = A[34]; + A[866] = A[343]; + A[230] = 0.0000000000000000000000000; + A[509] = A[42]; + A[550] = 0.0000000000000000000000000; + const double var_271 = var_153 + 0.3142857142857142793701541*var_52 + 0.8857142857142856762209249*var_125 + 0.0190476190476190493372499*var_43 + var_138; + A[158] = 7.1111111111111107163651468*var_271*var_8/(var_9*var_9*var_9*var_9); + const double var_272 = 0.3714285714285714412596917*var_43 + 1.7809523809523810644606101*var_45 + 3.2285714285714286475581503*var_44 + 1.4095238095238096232009184*var_52 + 1.0952380952380951217861593*var_84 + 2.1333333333333333037273860*var_47 + var_242; + A[280] = 1.7777777777777776790912867*var_272*var_8/(var_9*var_9*var_9*var_9); + A[309] = A[280]; + A[719] = A[254]; + A[891] = A[193]; + const double var_273 = 0.0328042328042328079629186*var_75 + 0.0042328042328042330896820*var_43 + -0.1322751322751322677895303*var_44 + 0.0476190476190476164042309*var_64 + 0.0285714285714285705364279*var_115 + 0.0846560846560846513852994*var_77 + var_241; + A[128] = 16.0000000000000000000000000*var_273*var_8/(var_9*var_9*var_9*var_9); + A[709] = A[128]; + A[482] = 0.0000000000000000000000000; + A[508] = A[42]; + A[435] = 0.0000000000000000000000000; + A[429] = A[283]; + A[120] = A[3]; + A[235] = 0.0000000000000000000000000; + A[26] = 0.0000000000000000000000000; + A[673] = 0.0000000000000000000000000; + A[207] = 0.0000000000000000000000000; + A[345] = 0.0000000000000000000000000; + A[187] = 1.7777777777777776790912867*var_243*var_8/(var_9*var_9*var_9*var_9); + A[461] = 0.0000000000000000000000000; + A[600] = 0.0000000000000000000000000; + A[601] = 0.0000000000000000000000000; + const double var_274 = 0.1666666666666666574148081*var_100 + 0.5000000000000000000000000*var_115 + var_209 + var_224 + 0.3333333333333333148296163*var_208*var_4*var_4 + var_179; + A[2] = 0.3396825396825396969902044*var_274*var_8/(var_9*var_9*var_9*var_9); + A[273] = A[99]; + A[281] = 3.0476190476190474498707772*var_176*var_8/(var_9*var_9*var_9*var_9); + A[746] = A[281]; + A[443] = 0.0000000000000000000000000; + A[174] = 0.0000000000000000000000000; + const double var_275 = var_263 + 0.7015873015873015372534383*var_99 + 1.4666666666666665630458510*var_75 + 0.3333333333333333148296163*var_206 + 0.8285714285714285143313873*var_77 + -0.8920634920634921138926643*var_44 + -2.1682539682539681002992893*var_45; + A[7] = 0.6666666666666666296592325*var_275*var_8/(var_9*var_9*var_9*var_9); + A[755] = 0.0000000000000000000000000; + A[407] = 0.0000000000000000000000000; + A[828] = A[102]; + A[463] = 0.0000000000000000000000000; + A[419] = 0.0000000000000000000000000; + const double var_276 = var_113 + 0.0888888888888888922812370*var_47 + 0.0222222222222222230703093*var_64 + 0.1111111111111111049432054*var_127 + var_144; + A[342] = 6.0952380952380948997415544*var_276*var_8/(var_9*var_9*var_9*var_9); + A[896] = A[342]; + A[116] = 0.0000000000000000000000000; + const double var_277 = 0.0285714285714285705364279*var_94 + 0.0328042328042328079629186*var_77 + var_241 + 0.0846560846560846513852994*var_75 + 0.0476190476190476164042309*var_99 + -0.1322751322751322677895303*var_45 + 0.0042328042328042330896820*var_84; + A[131] = 16.0000000000000000000000000*var_277*var_8/(var_9*var_9*var_9*var_9); + A[596] = A[131]; + A[406] = 0.0000000000000000000000000; + A[79] = 0.0000000000000000000000000; + A[98] = 1.0158730158730158166235924*var_265*var_8/(var_9*var_9*var_9*var_9); + A[708] = A[98]; + A[478] = A[12]; + const double var_278 = -0.2761904761904762084512299*var_44 + 0.2857142857142856984253854*var_77 + var_229 + var_105 + var_106; + A[312] = 10.6666666666666660745477202*var_278*var_8/(var_9*var_9*var_9*var_9); + A[835] = A[312]; + const double var_279 = var_67 + 0.3333333333333333148296163*var_131 + var_109; + A[159] = 0.6095238095238095787919974*var_279*var_8/(var_9*var_9*var_9*var_9); + A[740] = A[159]; + A[163] = A[162]; + A[765] = A[10]; + A[624] = A[159]; + A[378] = 0.0000000000000000000000000; + A[725] = 0.0000000000000000000000000; + A[774] = A[280]; + A[804] = A[281]; + const double var_280 = var_205 + 0.3333333333333333148296163*var_115 + 0.1428571428571428492126927*var_75 + var_250 + var_126; + A[314] = 2.1333333333333333037273860*var_280*var_8/(var_9*var_9*var_9*var_9); + const double var_281 = var_171 + 0.0158730158730158721347436*var_131 + 0.0285714285714285705364279*var_43 + 0.0730158730158730201464934*var_45 + var_259; + A[160] = 5.3333333333333330372738601*var_281*var_8/(var_9*var_9*var_9*var_9); + A[770] = A[160]; + A[871] = 0.0000000000000000000000000; + A[358] = 0.0000000000000000000000000; + A[495] = A[1]; + A[357] = 0.0000000000000000000000000; + const double var_282 = var_158 + var_138 + 0.8476190476190477163243031*var_44 + var_239 + 0.3238095238095238248554608*var_52 + 0.5809523809523809978472286*var_47 + var_186; + A[224] = 10.6666666666666660745477202*var_282*var_8/(var_9*var_9*var_9*var_9); + A[689] = A[224]; + A[265] = 0.0000000000000000000000000; + A[821] = 0.0000000000000000000000000; + A[750] = 0.0000000000000000000000000; + A[723] = 0.0000000000000000000000000; + A[516] = 0.0000000000000000000000000; + const double var_283 = 0.1809523809523809756427681*var_47 + 0.4857142857142857095276156*var_52 + 0.7523809523809524835158413*var_45 + var_185 + 0.1428571428571428492126927*var_44 + var_238 + var_199; + A[133] = 10.6666666666666660745477202*var_283*var_8/(var_9*var_9*var_9*var_9); + A[859] = A[133]; + A[728] = 0.0000000000000000000000000; + A[666] = 0.0000000000000000000000000; + A[754] = 0.0000000000000000000000000; + A[263] = 0.0000000000000000000000000; + A[81] = 0.0000000000000000000000000; + const double var_284 = -30.6190476190476168483201036*var_45 + 9.5714285714285711748061658*var_101 + 20.0952380952380948997415544*var_75 + 10.5238095238095237249353886*var_99 + var_254; + A[543] = 0.0000000000000000000000000; + A[354] = 0.0000000000000000000000000; + A[694] = 0.0000000000000000000000000; + A[820] = 0.0000000000000000000000000; + A[222] = 10.6666666666666660745477202*var_201*var_8/(var_9*var_9*var_9*var_9); + A[832] = A[222]; + A[351] = 0.0000000000000000000000000; + A[460] = 0.0000000000000000000000000; + A[582] = 0.0000000000000000000000000; + A[647] = A[66]; + A[704] = 0.0000000000000000000000000; + A[845] = 0.0000000000000000000000000; + A[615] = A[3]; + A[431] = A[342]; + A[886] = A[42]; + A[781] = 0.0000000000000000000000000; + A[467] = A[2]; + A[549] = 0.0000000000000000000000000; + A[368] = A[252]; + A[606] = 0.0000000000000000000000000; + A[863] = A[252]; + A[573] = 0.0000000000000000000000000; + A[48] = 0.0000000000000000000000000; + A[477] = A[12]; + A[618] = A[95]; + A[807] = A[342]; + A[803] = A[251]; + const double var_285 = -8.5555555555555553581825734*var_80 + 2.4285714285714283811046243*var_73 + 3.0634920634920632664943696*var_121 + 5.4920634920634920916882038*var_79; + A[124] = 0.8000000000000000444089210*var_285*var_8/(var_9*var_9*var_9*var_9); + A[589] = A[124]; + A[338] = A[251]; + A[59] = 0.0000000000000000000000000; + A[179] = 0.0000000000000000000000000; + A[535] = A[69]; + A[67] = 0.0444444444444444461406185*var_284*var_8/(var_9*var_9*var_9*var_9); + A[532] = A[67]; + A[456] = 0.0000000000000000000000000; + A[617] = A[65]; + A[542] = 0.0000000000000000000000000; + const double var_286 = 0.0476190476190476164042309*var_123; + const double var_287 = var_174 + var_286 + 0.0285714285714285705364279*var_52 + 0.0380952380952380986744998*var_47 + 0.0539682539682539708092435*var_44 + 0.0349206349206349214719936*var_45 + 0.0190476190476190493372499*var_108; + A[156] = 21.3333333333333321490954404*var_287*var_8/(var_9*var_9*var_9*var_9); + A[650] = A[156]; + A[721] = 0.0000000000000000000000000; + A[122] = A[64]; + A[243] = A[98]; + A[511] = 0.0000000000000000000000000; + A[587] = A[64]; + A[521] = 0.0000000000000000000000000; + const double var_288 = 0.6888888888888888839545643*var_175 + -0.6296296296296296501893153*var_45 + 0.2000000000000000111022302*var_99 + 0.4296296296296296390870850*var_75 + var_177; + A[155] = 9.1428571428571423496123316*var_288*var_8/(var_9*var_9*var_9*var_9); + A[248] = A[155]; + A[194] = A[193]; + A[654] = A[189]; + const double var_289 = 0.0243386243386243400488311*var_73 + -0.0814814814814814880605809*var_80 + 0.0529100529100529071158121*var_79 + 0.0285714285714285705364279*var_121; + A[186] = 64.0000000000000000000000000*var_289*var_8/(var_9*var_9*var_9*var_9); + A[522] = 0.0000000000000000000000000; + A[304] = A[130]; + A[86] = 0.0000000000000000000000000; + A[359] = 0.0000000000000000000000000; + A[585] = A[3]; + A[170] = 0.0000000000000000000000000; + A[716] = A[251]; + A[648] = A[96]; + A[74] = A[72]; + A[685] = A[220]; + A[272] = A[69]; + A[711] = A[188]; + A[297] = 0.0000000000000000000000000; + A[166] = 0.0000000000000000000000000; + A[699] = 0.0000000000000000000000000; + A[554] = 0.0000000000000000000000000; + const double var_290 = var_261 + var_138 + 0.3492063492063491869643599*var_47 + 0.0158730158730158721347436*var_214 + 0.2698412698412698262906417*var_52 + var_165; + A[126] = 1.0666666666666666518636930*var_290*var_8/(var_9*var_9*var_9*var_9); + A[591] = A[126]; + A[793] = 0.0000000000000000000000000; + A[440] = 0.0000000000000000000000000; + A[764] = 0.0000000000000000000000000; + A[140] = 0.0000000000000000000000000; + A[890] = A[164]; + A[811] = 0.0000000000000000000000000; + A[786] = 0.0000000000000000000000000; + A[445] = 0.0000000000000000000000000; + A[200] = 0.0000000000000000000000000; + A[557] = A[63]; + A[472] = A[7]; + A[806] = A[93]; + A[513] = 0.0000000000000000000000000; + A[852] = 0.0000000000000000000000000; + A[876] = 0.0000000000000000000000000; + A[239] = 0.0000000000000000000000000; + A[176] = 0.0000000000000000000000000; + A[409] = 0.0000000000000000000000000; + A[371] = A[342]; + A[438] = 0.0000000000000000000000000; + A[651] = A[186]; + A[329] = 0.0000000000000000000000000; + A[27] = 0.0000000000000000000000000; + A[214] = A[127]; + A[457] = 0.0000000000000000000000000; + A[690] = 0.0000000000000000000000000; + A[348] = 0.0000000000000000000000000; + A[106] = 0.0000000000000000000000000; + A[745] = A[280]; + A[454] = 0.0000000000000000000000000; + A[608] = 0.0000000000000000000000000; + A[691] = 0.0000000000000000000000000; + A[827] = A[72]; + A[842] = 0.0000000000000000000000000; + A[551] = 0.0000000000000000000000000; + A[687] = A[222]; + A[212] = A[67]; + A[315] = 0.0000000000000000000000000; + A[168] = 0.0000000000000000000000000; + A[121] = A[34]; + A[40] = 0.0444444444444444461406185*var_255*var_8/(var_9*var_9*var_9*var_9); + A[505] = A[40]; + const double var_291 = 0.1428571428571428492126927*var_123 + -0.1333333333333333314829616*var_44 + 0.1809523809523809756427681*var_77 + 0.2285714285714285642914234*var_135 + var_168; + A[35] = 0.8888888888888888395456433*var_291*var_8/(var_9*var_9*var_9*var_9); + A[500] = A[35]; + A[571] = 0.0000000000000000000000000; + A[610] = 0.0000000000000000000000000; + A[337] = A[221]; + A[797] = A[69]; + A[46] = 0.0000000000000000000000000; + A[385] = 0.0000000000000000000000000; + A[630] = 0.0000000000000000000000000; + A[634] = 0.0000000000000000000000000; + A[580] = 0.0000000000000000000000000; + A[148] = 0.0000000000000000000000000; + A[286] = 0.0000000000000000000000000; + A[386] = 0.0000000000000000000000000; + A[446] = 0.0000000000000000000000000; + A[245] = A[158]; + A[57] = 0.0000000000000000000000000; + A[215] = A[157]; + A[873] = 0.0000000000000000000000000; + const double var_292 = var_155 + 0.2000000000000000111022302*var_52 + 0.0920634920634920694837433*var_43 + 0.2920634920634920805859736*var_45 + 0.1396825396825396858879742*var_44 + 0.1238095238095238276310184*var_47 + var_286; + A[8] = 2.6666666666666665186369300*var_292*var_8/(var_9*var_9*var_9*var_9); + A[504] = A[39]; + A[114] = 0.0000000000000000000000000; + A[605] = 0.0000000000000000000000000; + A[152] = A[65]; + A[92] = A[63]; + A[885] = A[12]; + A[363] = A[102]; + A[352] = 0.0000000000000000000000000; + A[275] = A[159]; + A[538] = A[72]; + A[285] = 0.0000000000000000000000000; + A[722] = 0.0000000000000000000000000; + A[434] = A[372]; + A[635] = 0.0000000000000000000000000; + A[801] = A[191]; + A[677] = A[67]; + A[403] = A[372]; + A[889] = A[134]; + A[71] = A[69]; + A[536] = A[69]; + A[720] = 0.0000000000000000000000000; + const double var_293 = var_252 + 0.1682539682539682668327430*var_45 + 0.0031746031746031746004211*var_64 + 0.0507936507936507936067372*var_47 + 0.1111111111111111049432054*var_52 + 0.1428571428571428492126927*var_112 + var_140; + A[425] = A[164]; + A[289] = 0.0000000000000000000000000; + A[844] = 0.0000000000000000000000000; + A[344] = A[342]; + A[525] = A[2]; + A[712] = A[218]; + A[327] = 0.0000000000000000000000000; + A[713] = A[155]; + A[645] = A[6]; + A[255] = 0.0000000000000000000000000; + A[479] = A[12]; + A[181] = A[36]; + A[533] = A[68]; + A[424] = A[134]; + A[56] = 0.0000000000000000000000000; + A[640] = 0.0000000000000000000000000; + A[675] = A[7]; + A[632] = 0.0000000000000000000000000; + A[366] = A[192]; + A[259] = 0.0000000000000000000000000; + A[558] = A[93]; + A[203] = 0.0000000000000000000000000; + A[700] = 0.0000000000000000000000000; + A[282] = 42.6666666666666642981908808*var_293*var_8/(var_9*var_9*var_9*var_9); + A[369] = A[282]; + A[60] = A[2]; + A[83] = 0.0000000000000000000000000; + A[776] = A[311]; + A[455] = 0.0000000000000000000000000; + A[195] = 0.0000000000000000000000000; + A[18] = 0.0000000000000000000000000; + A[534] = A[69]; + A[38] = A[36]; + A[537] = A[72]; + A[316] = 0.0000000000000000000000000; + A[614] = 0.0000000000000000000000000; + A[856] = A[42]; + A[421] = A[42]; + A[416] = 0.0000000000000000000000000; + A[718] = A[252]; + A[175] = 0.0000000000000000000000000; + A[49] = 0.0000000000000000000000000; + A[253] = A[252]; + A[398] = A[252]; + A[274] = A[129]; + A[684] = A[219]; + A[514] = 0.0000000000000000000000000; + A[61] = A[32]; + A[517] = 0.0000000000000000000000000; + A[883] = 0.0000000000000000000000000; + A[25] = 0.0000000000000000000000000; + A[560] = A[95]; + A[227] = 0.0000000000000000000000000; + A[766] = A[40]; + A[639] = 0.0000000000000000000000000; + A[242] = A[68]; + A[339] = A[281]; + A[881] = 0.0000000000000000000000000; + A[724] = 0.0000000000000000000000000; + A[826] = A[42]; + A[701] = 0.0000000000000000000000000; + A[734] = 0.0000000000000000000000000; + A[566] = A[101]; + A[448] = 0.0000000000000000000000000; + A[884] = 0.0000000000000000000000000; + A[652] = A[187]; + A[761] = 0.0000000000000000000000000; + A[233] = 0.0000000000000000000000000; + A[569] = A[102]; + A[491] = 0.0000000000000000000000000; + A[800] = A[161]; + A[185] = A[156]; + A[362] = A[72]; + A[792] = 0.0000000000000000000000000; + A[318] = 0.0000000000000000000000000; + A[165] = 0.0000000000000000000000000; + A[893] = A[254]; + A[836] = A[342]; + A[512] = 0.0000000000000000000000000; + A[790] = 0.0000000000000000000000000; + A[112] = 0.0000000000000000000000000; + A[279] = A[186]; + A[466] = A[1]; + A[76] = 0.0000000000000000000000000; + A[427] = A[224]; + A[757] = 0.0000000000000000000000000; + A[370] = A[312]; + A[563] = A[98]; + A[878] = 0.0000000000000000000000000; + A[113] = 0.0000000000000000000000000; + A[570] = 0.0000000000000000000000000; + A[450] = 0.0000000000000000000000000; + A[825] = A[12]; + A[247] = A[218]; + A[441] = 0.0000000000000000000000000; + A[818] = 0.0000000000000000000000000; + A[353] = 0.0000000000000000000000000; + A[236] = 0.0000000000000000000000000; + A[423] = A[102]; + A[135] = 0.0000000000000000000000000; + A[523] = 0.0000000000000000000000000; + A[574] = 0.0000000000000000000000000; + A[777] = A[312]; + A[395] = A[162]; + A[661] = 0.0000000000000000000000000; + A[225] = 0.0000000000000000000000000; + A[545] = 0.0000000000000000000000000; + A[397] = A[223]; + A[546] = 0.0000000000000000000000000; + A[874] = 0.0000000000000000000000000; + A[794] = 0.0000000000000000000000000; + A[668] = 0.0000000000000000000000000; + A[299] = 0.0000000000000000000000000; + A[686] = A[221]; + A[577] = 0.0000000000000000000000000; + A[139] = 0.0000000000000000000000000; + A[715] = A[250]; + A[411] = 0.0000000000000000000000000; + A[326] = 0.0000000000000000000000000; + A[474] = A[9]; + A[88] = 0.0000000000000000000000000; + A[436] = 0.0000000000000000000000000; + A[623] = A[158]; + A[476] = A[11]; + A[662] = 0.0000000000000000000000000; + A[882] = 0.0000000000000000000000000; + A[410] = 0.0000000000000000000000000; + A[602] = 0.0000000000000000000000000; + A[387] = 0.0000000000000000000000000; + A[848] = 0.0000000000000000000000000; + A[52] = 0.0000000000000000000000000; + A[483] = 0.0000000000000000000000000; + A[84] = 0.0000000000000000000000000; + A[846] = 0.0000000000000000000000000; + A[646] = A[36]; + A[555] = A[3]; + A[420] = A[12]; + A[54] = 0.0000000000000000000000000; + A[749] = A[283]; + A[322] = 0.0000000000000000000000000; + A[449] = 0.0000000000000000000000000; + A[805] = A[311]; + A[737] = A[69]; + A[864] = A[283]; + A[350] = 0.0000000000000000000000000; + A[364] = A[132]; + A[857] = A[72]; + A[208] = 0.0000000000000000000000000; + A[688] = A[223]; + A[789] = 0.0000000000000000000000000; + A[298] = 0.0000000000000000000000000; + A[332] = A[69]; + const double var_294 = 142.0000000000000000000000000*var_75 + 64.3333333333333285963817616*var_99 + 233.0000000000000000000000000*var_175 + -206.3333333333333143855270464*var_45 + var_151; + A[310] = 0.0380952380952380986744998*var_294*var_8/(var_9*var_9*var_9*var_9); + A[775] = A[310]; + A[553] = 0.0000000000000000000000000; + A[619] = A[125]; + A[726] = 0.0000000000000000000000000; + A[305] = A[160]; + A[107] = 0.0000000000000000000000000; + A[698] = 0.0000000000000000000000000; + A[412] = 0.0000000000000000000000000; + A[439] = 0.0000000000000000000000000; + A[541] = 0.0000000000000000000000000; + A[599] = A[134]; + A[257] = 0.0000000000000000000000000; + A[198] = 0.0000000000000000000000000; + A[470] = A[3]; + A[824] = 0.0000000000000000000000000; + A[290] = 0.0000000000000000000000000; + A[733] = 0.0000000000000000000000000; + A[183] = A[96]; + A[379] = 0.0000000000000000000000000; + A[21] = 0.0000000000000000000000000; + A[843] = 0.0000000000000000000000000; + A[767] = A[69]; + A[256] = 0.0000000000000000000000000; + A[493] = 0.0000000000000000000000000; + A[594] = A[129]; + A[676] = A[36]; + A[641] = 0.0000000000000000000000000; + A[627] = A[162]; + A[405] = 0.0000000000000000000000000; + A[621] = A[156]; + A[381] = 0.0000000000000000000000000; + A[5] = A[3]; + A[593] = A[128]; + A[115] = 0.0000000000000000000000000; + A[813] = 0.0000000000000000000000000; + A[105] = 0.0000000000000000000000000; + A[452] = 0.0000000000000000000000000; + A[547] = 0.0000000000000000000000000; + A[875] = 0.0000000000000000000000000; + A[291] = 0.0000000000000000000000000; + A[575] = 0.0000000000000000000000000; + A[561] = A[96]; + A[485] = 0.0000000000000000000000000; + A[544] = 0.0000000000000000000000000; + A[510] = 0.0000000000000000000000000; + A[692] = 0.0000000000000000000000000; + A[795] = A[11]; + A[735] = A[9]; + A[141] = 0.0000000000000000000000000; + A[75] = 0.0000000000000000000000000; + A[798] = A[101]; + A[430] = A[314]; + A[784] = 0.0000000000000000000000000; + A[29] = 0.0000000000000000000000000; + A[772] = A[220]; + A[197] = 0.0000000000000000000000000; + A[78] = 0.0000000000000000000000000; + A[43] = A[42]; + A[178] = 0.0000000000000000000000000; + A[204] = 0.0000000000000000000000000; + A[347] = 0.0000000000000000000000000; + A[267] = 0.0000000000000000000000000; + A[870] = 0.0000000000000000000000000; + A[861] = A[193]; + A[480] = 0.0000000000000000000000000; + A[367] = A[222]; + A[108] = 0.0000000000000000000000000; + A[206] = 0.0000000000000000000000000; + A[672] = 0.0000000000000000000000000; + A[447] = 0.0000000000000000000000000; + A[184] = A[126]; + A[501] = A[36]; + A[540] = 0.0000000000000000000000000; + A[697] = 0.0000000000000000000000000; + A[817] = 0.0000000000000000000000000; + A[80] = 0.0000000000000000000000000; + A[205] = 0.0000000000000000000000000; + A[898] = A[404]; + A[665] = 0.0000000000000000000000000; + A[240] = A[8]; + A[422] = A[72]; + const double var_295 = 6.1333333333333328596381762*var_135 + -8.1333333333333328596381762*var_44 + var_64 + 7.1333333333333328596381762*var_77 + var_203; + A[33] = 0.1269841269841269770779490*var_295*var_8/(var_9*var_9*var_9*var_9); + A[91] = A[33]; + A[149] = 0.0000000000000000000000000; + A[519] = 0.0000000000000000000000000; + A[631] = 0.0000000000000000000000000; + A[232] = 0.0000000000000000000000000; + A[172] = 0.0000000000000000000000000; + A[319] = 0.0000000000000000000000000; + A[743] = A[249]; + A[769] = A[130]; + A[137] = 0.0000000000000000000000000; + A[241] = A[36]; + A[779] = A[314]; + A[355] = 0.0000000000000000000000000; + A[489] = 0.0000000000000000000000000; + A[296] = 0.0000000000000000000000000; + A[246] = A[188]; + A[855] = A[12]; + A[377] = 0.0000000000000000000000000; + A[739] = A[129]; + A[499] = A[34]; + A[459] = 0.0000000000000000000000000; + A[89] = 0.0000000000000000000000000; + A[860] = A[162]; + A[833] = A[252]; + A[515] = 0.0000000000000000000000000; + A[604] = 0.0000000000000000000000000; + A[791] = 0.0000000000000000000000000; + A[277] = A[219]; + A[802] = A[221]; + A[210] = A[7]; + A[752] = 0.0000000000000000000000000; + A[73] = A[72]; + A[82] = 0.0000000000000000000000000; + A[16] = 0.0000000000000000000000000; + A[389] = 0.0000000000000000000000000; + A[432] = A[374]; + A[503] = A[36]; + A[598] = A[133]; + A[336] = A[191]; + A[744] = A[186]; + A[382] = 0.0000000000000000000000000; + A[418] = 0.0000000000000000000000000; + A[787] = 0.0000000000000000000000000; + A[658] = A[193]; + A[506] = A[41]; + A[213] = A[97]; + A[660] = 0.0000000000000000000000000; + A[620] = A[155]; + A[603] = 0.0000000000000000000000000; + A[838] = A[373]; + A[539] = A[72]; + A[520] = 0.0000000000000000000000000; + A[90] = A[3]; + A[451] = 0.0000000000000000000000000; + A[394] = A[133]; + A[579] = 0.0000000000000000000000000; + A[308] = A[250]; + A[778] = A[313]; + A[278] = A[249]; + A[667] = 0.0000000000000000000000000; + A[153] = A[95]; + A[24] = 0.0000000000000000000000000; + A[28] = 0.0000000000000000000000000; + A[444] = 0.0000000000000000000000000; + A[19] = 0.0000000000000000000000000; + A[729] = 0.0000000000000000000000000; + A[636] = 0.0000000000000000000000000; + A[895] = A[314]; + A[710] = A[158]; + A[809] = A[342]; + A[30] = A[1]; + A[396] = A[193]; + A[228] = 0.0000000000000000000000000; + A[756] = 0.0000000000000000000000000; + A[892] = A[224]; + A[812] = 0.0000000000000000000000000; + A[783] = 0.0000000000000000000000000; + A[462] = 0.0000000000000000000000000; + A[643] = 0.0000000000000000000000000; + A[705] = A[8]; + A[609] = 0.0000000000000000000000000; + A[77] = 0.0000000000000000000000000; + A[763] = 0.0000000000000000000000000; + A[748] = A[283]; + A[376] = 0.0000000000000000000000000; + A[625] = A[160]; + A[637] = 0.0000000000000000000000000; + A[747] = A[282]; + A[879] = 0.0000000000000000000000000; + A[742] = A[219]; + A[616] = A[35]; + A[613] = 0.0000000000000000000000000; + A[334] = A[131]; + A[888] = A[102]; + A[834] = A[282]; + A[894] = A[283]; + A[323] = 0.0000000000000000000000000; + A[887] = A[72]; + A[607] = 0.0000000000000000000000000; + A[167] = 0.0000000000000000000000000; + A[799] = A[131]; + A[572] = 0.0000000000000000000000000; + A[502] = A[36]; + A[644] = 0.0000000000000000000000000; + A[847] = 0.0000000000000000000000000; + A[51] = 0.0000000000000000000000000; + A[526] = A[32]; + A[324] = 0.0000000000000000000000000; + A[123] = A[94]; + A[269] = 0.0000000000000000000000000; + A[565] = A[100]; + A[244] = A[128]; + A[556] = A[33]; + A[180] = A[6]; + A[751] = 0.0000000000000000000000000; + A[492] = 0.0000000000000000000000000; + A[683] = A[218]; + A[199] = 0.0000000000000000000000000; + A[293] = 0.0000000000000000000000000; + A[464] = 0.0000000000000000000000000; + A[196] = 0.0000000000000000000000000; + A[110] = 0.0000000000000000000000000; + A[703] = 0.0000000000000000000000000; + A[294] = 0.0000000000000000000000000; + A[475] = A[10]; + A[325] = 0.0000000000000000000000000; + A[216] = A[187]; + A[150] = A[3]; + A[177] = 0.0000000000000000000000000; + A[717] = A[252]; + A[44] = A[42]; + A[626] = A[161]; + A[559] = A[94]; + A[682] = A[217]; + A[473] = A[8]; + A[384] = 0.0000000000000000000000000; + A[365] = A[162]; + A[785] = 0.0000000000000000000000000; + A[301] = A[40]; + A[400] = A[313]; + A[702] = 0.0000000000000000000000000; + A[732] = 0.0000000000000000000000000; + A[583] = 0.0000000000000000000000000; + A[753] = 0.0000000000000000000000000; + A[4] = A[3]; + A[58] = 0.0000000000000000000000000; + A[486] = 0.0000000000000000000000000; + A[498] = A[33]; + A[14] = A[12]; + A[679] = A[127]; + A[151] = A[35]; + A[321] = 0.0000000000000000000000000; + A[831] = A[192]; + A[468] = A[3]; + A[142] = 0.0000000000000000000000000; + A[306] = A[190]; + A[681] = A[187]; + A[567] = A[102]; + A[649] = A[126]; + A[415] = 0.0000000000000000000000000; + A[433] = A[404]; + A[507] = A[42]; + A[119] = 0.0000000000000000000000000; + A[55] = 0.0000000000000000000000000; + A[154] = A[125]; + A[109] = 0.0000000000000000000000000; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q4_quadrature.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q4_quadrature.h new file mode 100644 index 0000000..12c6ef5 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q4_quadrature.h @@ -0,0 +1,17682 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F2_P1_Q4_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F2_P1_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q4_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 15; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q4_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 30; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 15: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 20: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 21: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 22: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 23: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 24: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 25: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 26: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 27: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 28: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 29: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[20] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[21] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[22] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[23] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[24] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[25] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[26] = vals[1]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[27] = vals[1]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[28] = vals[1]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[29] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[15]; + vertex_values[3] = dof_values[16]; + vertex_values[5] = dof_values[17]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q4_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q4_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 3*m.num_entities[1] + 3*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 15; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 15; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 5; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 3; + break; + } + case 2: + { + return 3; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q4_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q4_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 6*m.num_entities[1] + 6*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 30; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 30; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 10; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 6; + break; + } + case 2: + { + return 6; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + dofs[15] = offset + c.entity_indices[0][0]; + dofs[16] = offset + c.entity_indices[0][1]; + dofs[17] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[18] = offset + 3*c.entity_indices[1][0]; + dofs[19] = offset + 3*c.entity_indices[1][0] + 1; + dofs[20] = offset + 3*c.entity_indices[1][0] + 2; + dofs[21] = offset + 3*c.entity_indices[1][1]; + dofs[22] = offset + 3*c.entity_indices[1][1] + 1; + dofs[23] = offset + 3*c.entity_indices[1][1] + 2; + dofs[24] = offset + 3*c.entity_indices[1][2]; + dofs[25] = offset + 3*c.entity_indices[1][2] + 1; + dofs[26] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[27] = offset + 3*c.entity_indices[2][0]; + dofs[28] = offset + 3*c.entity_indices[2][0] + 1; + dofs[29] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + dofs[5] = 16; + dofs[6] = 17; + dofs[7] = 18; + dofs[8] = 19; + dofs[9] = 20; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + dofs[5] = 15; + dofs[6] = 17; + dofs[7] = 21; + dofs[8] = 22; + dofs[9] = 23; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + dofs[5] = 15; + dofs[6] = 16; + dofs[7] = 24; + dofs[8] = 25; + dofs[9] = 26; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 15; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 16; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 17; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + dofs[3] = 18; + dofs[4] = 19; + dofs[5] = 20; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + dofs[3] = 21; + dofs[4] = 22; + dofs[5] = 23; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + dofs[3] = 24; + dofs[4] = 25; + dofs[5] = 26; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + dofs[3] = 27; + dofs[4] = 28; + dofs[5] = 29; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + coordinates[15][0] = x[0][0]; + coordinates[15][1] = x[0][1]; + coordinates[16][0] = x[1][0]; + coordinates[16][1] = x[1][1]; + coordinates[17][0] = x[2][0]; + coordinates[17][1] = x[2][1]; + coordinates[18][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[18][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[19][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[19][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[20][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[20][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[21][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[21][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[22][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[22][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[23][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[23][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[24][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[24][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[25][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[25][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[26][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[26][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[27][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[27][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[28][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[28][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[29][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[29][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f2_p1_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W12[12] = {0.0254224531851035, 0.0254224531851035, 0.0254224531851035, 0.0583931378631895, 0.0583931378631895, 0.0583931378631895, 0.041425537809187, 0.041425537809187, 0.041425537809187, 0.041425537809187, 0.041425537809187, 0.041425537809187}; + // Quadrature points on the UFC reference element: (0.873821971016996, 0.063089014491502), (0.063089014491502, 0.873821971016996), (0.063089014491502, 0.063089014491502), (0.501426509658179, 0.24928674517091), (0.24928674517091, 0.501426509658179), (0.24928674517091, 0.24928674517091), (0.636502499121399, 0.310352451033785), (0.636502499121399, 0.053145049844816), (0.310352451033785, 0.636502499121399), (0.310352451033785, 0.053145049844816), (0.053145049844816, 0.636502499121399), (0.053145049844816, 0.310352451033785) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[12][2] = \ + {{-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + static const double FE1_C0_D01[12][14] = \ + {{0.25503123596508, -0.255031235965082, 8.69435091190193, -4.31977685940844, 1.57734044902622, 0.105939243712314, 0.0, -0.105939243712309, -1.57734044902622, 4.31977685940843, -8.69435091190193, -0.445184891121222, 0.0, 0.445184891121223}, + {0.255031235965082, 3.63298524888145, 0.219821542106375, -1.1302567746644, 2.97433324923121, -1.35751890691984, 3.18952008474403, -5.72001766267072, -0.113882298394064, -0.093447192397538, -0.219821542106377, 0.778519075940721, 1.22370396706193, -3.63897002677786}, + {-3.63298524888145, -0.25503123596508, 0.21982154210638, 0.0934471923975435, 0.113882298394063, 5.72001766267072, -3.18952008474403, 1.35751890691984, -2.97433324923121, 1.1302567746644, -0.21982154210638, 3.63897002677786, -1.22370396706193, -0.778519075940723}, + {-0.334276184571048, 0.334276184571049, 0.00767329311884973, 2.00564073509674, -1.33710470732049, 0.666650418191927, 0.0, -0.66665041819193, 1.3371047073205, -2.00564073509676, -0.00767329311884897, -3.98855545674879, 1.50990331349021e-14, 3.98855545674879}, + {-0.334276184571049, -0.335202663479222, 0.00190199739572172, -0.00856710477719524, 1.35235327632684, 1.33900670471621, -2.01420783987394, 1.344679983208, 0.664748420796208, 0.00282864660425459, -0.00190199739572122, -3.98281699857586, 0.00573845817294127, 1.96571530145281}, + {0.335202663479223, 0.334276184571049, 0.00190199739572106, -0.0028286466042553, -0.664748420796206, -1.344679983208, 2.01420783987395, -1.33900670471622, -1.35235327632686, 0.00856710477719541, -0.00190199739572086, -1.96571530145278, -0.00573845817293789, 3.98281699857584}, + {0.349705911290055, 0.203964070416353, 1.43278734550558, 5.83661064102859, -1.400583725025, -0.512351997979363, -0.0759361474850933, 0.0346181637580474, -1.45986486533339, 2.26265886610736, -1.43278734550558, 2.7813716060586, -8.09926950713595, 0.0790769842997865}, + {-0.203964070416352, -0.349705911290058, 1.43278734550558, -2.26265886610737, 1.45986486533339, -0.0346181637580476, 0.0759361474850917, 0.512351997979366, 1.40058372502499, -5.83661064102859, -1.43278734550559, -0.0790769842997787, 8.09926950713596, -2.78137160605861}, + {0.349705911290056, -0.108689564899274, -0.151560504096129, 1.22633132411976, 5.10669707680118, -1.2604009006736, 1.57769621968679, -0.558311665403964, -0.711815962639155, 0.17227281649596, 0.151560504096128, 3.21812528849814, -1.39860414061572, -7.61300640266017}, + {0.108689564899274, -0.349705911290057, -0.151560504096129, -0.172272816495958, 0.711815962639153, 0.558311665403965, -1.57769621968679, 1.26040090067361, -5.10669707680118, -1.22633132411976, 0.151560504096128, 7.61300640266016, 1.39860414061572, -3.21812528849814}, + {-0.203964070416353, -0.108689564899275, 0.199463964659789, -0.684962646420587, 0.874475680101626, 1.24902322092887, -4.61027931690884, 3.6739097312956, 0.116942340338078, 0.248208963981059, -0.199463964659787, -1.4776811249155, 0.436753682439524, 0.486263104475795}, + {0.108689564899276, 0.203964070416351, 0.199463964659789, -0.24820896398106, -0.116942340338075, -3.67390973129559, 4.61027931690883, -1.24902322092887, -0.874475680101624, 0.684962646420587, -0.199463964659788, -0.486263104475796, -0.43675368243953, 1.4776811249155}}; + + // Array of non-zero columns + static const unsigned int nzc10[14] = {15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; + + // Array of non-zero columns + static const unsigned int nzc7[14] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + + static const double FE1_C0_D10[12][14] = \ + {{0.255031235965081, 3.63298524888145, 2.9743332492312, -1.1302567746644, 0.219821542106376, -0.113882298394064, -0.0934471923975434, -0.219821542106376, -1.35751890691984, 3.18952008474404, -5.72001766267072, 0.778519075940721, -3.63897002677786, 1.22370396706194}, + {0.25503123596508, -0.25503123596508, 1.57734044902622, -4.31977685940843, 8.69435091190193, -1.57734044902622, 4.31977685940843, -8.69435091190193, 0.105939243712316, 0.0, -0.105939243712313, -0.445184891121218, 0.445184891121217, -1.3885718641932e-14}, + {-3.63298524888145, -0.25503123596508, 0.113882298394067, 0.0934471923975413, 0.219821542106378, -2.97433324923121, 1.13025677466441, -0.219821542106378, 5.72001766267072, -3.18952008474404, 1.35751890691984, 3.63897002677786, -0.778519075940718, -1.22370396706195}, + {-0.334276184571049, -0.335202663479221, 1.35235327632684, -0.00856710477719638, 0.00190199739572253, 0.664748420796207, 0.00282864660425311, -0.00190199739572225, 1.33900670471622, -2.01420783987394, 1.344679983208, -3.98281699857586, 1.96571530145281, 0.00573845817294158}, + {-0.334276184571049, 0.33427618457105, -1.3371047073205, 2.00564073509674, 0.00767329311885023, 1.3371047073205, -2.00564073509676, -0.00767329311884979, 0.666650418191928, 0.0, -0.666650418191932, -3.98855545674879, 3.9885554567488, 1.67572730715561e-14}, + {0.335202663479223, 0.33427618457105, -0.664748420796208, -0.00282864660425441, 0.00190199739572211, -1.35235327632686, 0.00856710477719472, -0.0019019973957225, -1.344679983208, 2.01420783987395, -1.33900670471622, -1.96571530145278, 3.98281699857584, -0.00573845817294052}, + {0.349705911290055, -0.108689564899275, 5.10669707680118, 1.22633132411975, -0.151560504096126, -0.711815962639155, 0.172272816495964, 0.151560504096127, -1.2604009006736, 1.57769621968678, -0.55831166540396, 3.21812528849813, -7.61300640266015, -1.39860414061572}, + {-0.203964070416353, -0.108689564899274, 0.874475680101621, -0.68496264642058, 0.199463964659786, 0.116942340338081, 0.248208963981053, -0.199463964659786, 1.24902322092887, -4.61027931690883, 3.67390973129559, -1.4776811249155, 0.486263104475798, 0.436753682439526}, + {0.349705911290056, 0.203964070416352, -1.40058372502499, 5.83661064102859, 1.43278734550559, -1.4598648653334, 2.26265886610737, -1.43278734550559, -0.512351997979363, -0.0759361474850956, 0.0346181637580502, 2.78137160605861, 0.0790769842997796, -8.09926950713596}, + {0.108689564899274, 0.203964070416352, -0.116942340338078, -0.248208963981051, 0.199463964659787, -0.87447568010162, 0.684962646420584, -0.199463964659787, -3.67390973129559, 4.61027931690883, -1.24902322092886, -0.486263104475797, 1.4776811249155, -0.436753682439534}, + {-0.203964070416352, -0.349705911290056, 1.45986486533339, -2.26265886610737, 1.43278734550559, 1.400583725025, -5.83661064102859, -1.43278734550559, -0.0346181637580502, 0.0759361474850956, 0.512351997979363, -0.0790769842997782, -2.78137160605861, 8.09926950713596}, + {0.108689564899276, -0.349705911290055, 0.711815962639149, -0.17227281649596, -0.151560504096129, -5.10669707680118, -1.22633132411976, 0.151560504096128, 0.558311665403961, -1.57769621968678, 1.2604009006736, 7.61300640266016, -3.21812528849813, 1.39860414061572}}; + + // Array of non-zero columns + static const unsigned int nzc11[14] = {15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; + + // Array of non-zero columns + static const unsigned int nzc8[14] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 900; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 180. + double G[30]; + G[0] = K_00*K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_00*K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_00*K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_00*K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_10*K_10*det*(K_10*K_10 + K_11*K_11); + G[5] = K_01*K_10*det*(K_10*K_10 + K_11*K_11); + G[6] = K_10*K_11*det*(K_10*K_10 + K_11*K_11); + G[7] = K_01*K_01*det*(K_10*K_10 + K_11*K_11); + G[8] = K_01*K_11*det*(K_10*K_10 + K_11*K_11); + G[9] = K_11*K_11*det*(K_10*K_10 + K_11*K_11); + G[10] = K_00*K_00*det*(K_00*K_10 + K_01*K_11); + G[11] = K_00*K_10*det*(K_00*K_10 + K_01*K_11); + G[12] = K_00*K_01*det*(K_00*K_10 + K_01*K_11); + G[13] = K_00*K_11*det*(K_00*K_10 + K_01*K_11); + G[14] = K_10*K_10*det*(K_00*K_10 + K_01*K_11); + G[15] = K_01*K_10*det*(K_00*K_10 + K_01*K_11); + G[16] = K_10*K_11*det*(K_00*K_10 + K_01*K_11); + G[17] = K_01*K_01*det*(K_00*K_10 + K_01*K_11); + G[18] = K_01*K_11*det*(K_00*K_10 + K_01*K_11); + G[19] = K_11*K_11*det*(K_00*K_10 + K_01*K_11); + G[20] = K_00*K_00*det*(K_00*K_00 + K_01*K_01); + G[21] = K_00*K_10*det*(K_00*K_00 + K_01*K_01); + G[22] = K_00*K_01*det*(K_00*K_00 + K_01*K_01); + G[23] = K_00*K_11*det*(K_00*K_00 + K_01*K_01); + G[24] = K_10*K_10*det*(K_00*K_00 + K_01*K_01); + G[25] = K_01*K_10*det*(K_00*K_00 + K_01*K_01); + G[26] = K_10*K_11*det*(K_00*K_00 + K_01*K_01); + G[27] = K_01*K_01*det*(K_00*K_00 + K_01*K_01); + G[28] = K_01*K_11*det*(K_00*K_00 + K_01*K_01); + G[29] = K_11*K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 58128 + for (unsigned int ip = 0; ip < 12; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + double F4 = 0.0; + double F5 = 0.0; + double F6 = 0.0; + double F7 = 0.0; + + // Total number of operations to compute function values = 32 + for (unsigned int r = 0; r < 2; r++) + { + F0 += FE0_C0_D01[ip][r]*w[0][nzc2[r]]; + F1 += FE0_C0_D01[ip][r]*w[0][nzc1[r]]; + F2 += FE0_C0_D01[ip][r]*w[0][nzc5[r]]; + F3 += FE0_C0_D01[ip][r]*w[0][nzc4[r]]; + F4 += FE0_C0_D01[ip][r]*w[1][nzc2[r]]; + F5 += FE0_C0_D01[ip][r]*w[1][nzc1[r]]; + F6 += FE0_C0_D01[ip][r]*w[1][nzc5[r]]; + F7 += FE0_C0_D01[ip][r]*w[1][nzc4[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 108 + double I[3]; + // Number of operations: 36 + I[0] = W12[ip]*(F4*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]) + F5*(F0*G[1] + F1*G[4] + F2*G[5] + F3*G[6]) + F6*(F0*G[2] + F1*G[5] + F2*G[7] + F3*G[8]) + F7*(F0*G[3] + F1*G[6] + F2*G[8] + F3*G[9])); + + // Number of operations: 36 + I[1] = W12[ip]*(F4*(F0*G[10] + F1*G[11] + F2*G[12] + F3*G[13]) + F5*(F0*G[11] + F1*G[14] + F2*G[15] + F3*G[16]) + F6*(F0*G[12] + F1*G[15] + F2*G[17] + F3*G[18]) + F7*(F0*G[13] + F1*G[16] + F2*G[18] + F3*G[19])); + + // Number of operations: 36 + I[2] = W12[ip]*(F4*(F0*G[20] + F1*G[21] + F2*G[22] + F3*G[23]) + F5*(F0*G[21] + F1*G[24] + F2*G[25] + F3*G[26]) + F6*(F0*G[22] + F1*G[25] + F2*G[27] + F3*G[28]) + F7*(F0*G[23] + F1*G[26] + F2*G[28] + F3*G[29])); + + + // Number of operations for primary indices: 4704 + for (unsigned int j = 0; j < 14; j++) + { + for (unsigned int k = 0; k < 14; k++) + { + // Number of operations to compute entry: 3 + A[nzc10[j]*30 + nzc10[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc10[j]*30 + nzc11[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*30 + nzc10[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc11[j]*30 + nzc11[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc7[j]*30 + nzc7[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc7[j]*30 + nzc8[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*30 + nzc7[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*I[1]; + // Number of operations to compute entry: 3 + A[nzc8[j]*30 + nzc8[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f2_p1_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), Product(IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 2; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q4_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q4_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f2_p1_q4_tensor.h b/vector_laplacian_2d/vector_laplacian_f2_p1_q4_tensor.h new file mode 100644 index 0000000..c1d48c9 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p1_q4_tensor.h @@ -0,0 +1,18663 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F2_P1_Q4_TENSOR_H +#define __VECTOR_LAPLACIAN_F2_P1_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q4_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 15; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 15; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p1_q4_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 30; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Compute value(s). + for (unsigned int r = 0; r < 15; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 1: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 2: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 4: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 5: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 6: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 7: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 8: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 9: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 10: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 11: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 12: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 13: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 14: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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 15: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, -0.0412393049421161, -0.0238095238095238, 0.0289800294976278, 0.0224478343233825, 0.012960263189329, -0.0395942580610999, -0.0334632556631574, -0.025920526378658, -0.014965222882255, 0.0321247254366312, 0.0283313448138523, 0.023944356611608, 0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 16: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0412393049421161, -0.0238095238095238, 0.0289800294976278, -0.0224478343233825, 0.012960263189329, 0.0395942580610999, -0.0334632556631574, 0.025920526378658, -0.014965222882255, 0.0321247254366312, -0.0283313448138523, 0.023944356611608, -0.0185472188784818, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 17: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.0, 0.0, 0.0476190476190476, 0.0, 0.0, 0.038880789567987, 0.0, 0.0, 0.0, 0.0598608915290199, 0.0, 0.0, 0.0, 0.0, 0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 18: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.131965775814772, -0.0253968253968253, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977599, 0.0267706045305259, -0.0622092633087791, 0.0478887132232159, 0.0, 0.0566626896277046, -0.0838052481406279, 0.0834624849531682, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 19: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527355, 0.0109971479845642, 0.00634920634920636, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.0, 0.0, 0.0838052481406279, -0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 20: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, 0.0439885919382572, 0.126984126984127, 0.0, 0.035916534917412, 0.155523158271948, 0.0, 0.0, 0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, 0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 21: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977599, 0.0267706045305259, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -0.0834624849531681, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 22: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527353, -0.0109971479845644, 0.00634920634920625, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703138, 0.0, 0.0, 0.0838052481406278, 0.139104141588614, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 23: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0439885919382572, 0.126984126984127, 0.0, -0.0359165349174119, 0.155523158271948, 0.0, 0.0, -0.103682105514632, -0.011972178305804, 0.0, 0.0, 0.0, -0.0927360943924091, -0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 24: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210942, -0.0879771838765144, -0.101587301587302, 0.0927360943924091, 0.107749604752236, 0.0725774738602423, 0.0791885161221998, -0.013385302265263, -0.0518410527573159, -0.0419026240703139, -0.128498901746525, -0.0566626896277046, -0.011972178305804, 0.00927360943924089, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 25: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {-0.0314269680527354, 0.0, -0.0126984126984126, -0.243432247780074, 0.0, 0.0544331053951817, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 0.192748352619787, 0.0, -0.023944356611608, 0.0, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 26: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.125707872210941, 0.0879771838765144, -0.101587301587302, 0.0927360943924091, -0.107749604752236, 0.0725774738602423, -0.0791885161221998, -0.013385302265263, 0.051841052757316, -0.0419026240703139, -0.128498901746525, 0.0566626896277046, -0.011972178305804, -0.00927360943924091, 0.0107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 27: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, -0.351908735506058, -0.203174603174603, -0.139104141588614, -0.107749604752236, -0.0622092633087791, 0.19005243869328, -0.0267706045305259, 0.124418526617558, 0.155638317975452, 0.0, 0.169988068883114, 0.0838052481406278, -0.0278208283177227, -0.053541209061052}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 28: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421884, 0.351908735506058, -0.203174603174603, -0.139104141588614, 0.107749604752236, -0.0622092633087792, -0.19005243869328, -0.0267706045305259, -0.124418526617558, 0.155638317975452, 0.0, -0.169988068883114, 0.0838052481406278, 0.0278208283177227, -0.0535412090610519}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 29: + { + + // Array of basisvalues. + double basisvalues[15] = {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}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[6] = basisvalues[3]*1.66666666666667*tmp0 - basisvalues[1]*0.666666666666667*tmp2; + basisvalues[10] = basisvalues[6]*1.75*tmp0 - basisvalues[3]*0.75*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[7] = basisvalues[3]*(2.5 + 3.5*Y); + basisvalues[11] = basisvalues[6]*(3.5 + 4.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[9] = basisvalues[5]*(0.05 + Y*1.75) - basisvalues[2]*0.7; + basisvalues[14] = basisvalues[9]*(0.0285714285714286 + Y*1.8) - basisvalues[5]*0.771428571428571; + basisvalues[8] = basisvalues[4]*(0.54 + Y*2.1) - basisvalues[1]*0.56; + basisvalues[13] = basisvalues[8]*(0.285714285714286 + Y*2.0) - basisvalues[4]*0.714285714285714; + basisvalues[12] = basisvalues[7]*(1.02040816326531 + Y*2.57142857142857) - basisvalues[3]*0.551020408163265; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[9] *= std::sqrt(2.0); + basisvalues[14] *= std::sqrt(2.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[8] *= std::sqrt(6.0); + basisvalues[13] *= std::sqrt(7.5); + basisvalues[3] *= std::sqrt(7.5); + basisvalues[7] *= std::sqrt(10.0); + basisvalues[12] *= std::sqrt(12.5); + basisvalues[6] *= std::sqrt(14.0); + basisvalues[11] *= std::sqrt(17.5); + basisvalues[10] *= std::sqrt(22.5); + + // Table(s) of coefficients. + static const double coefficients0[15] = \ + {0.251415744421883, 0.0, 0.406349206349206, 0.0, 0.0, -0.186627789926337, 0.0, -0.187394231713682, 0.0, -0.203527031198668, 0.0, 0.0, -0.167610496281256, 0.0, 0.107082418122104}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[15][15] = \ + {{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}, + {4.89897948556635, 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, 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, 9.48683298050513, 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}, + {4.0, 0.0, 7.07106781186548, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.61101009266078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 1.36319883402694e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999965, 0.0, 17.7482393492989, 0.0, 0.553283335172492, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933237, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285714, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 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, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{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}, + {2.44948974278318, 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}, + {4.24264068711928, 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}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063974, -1.05830052442584, 0.305505046330393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002067, 2.52982212813471, 8.08290376865477, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.8284271247462, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206988, 8.87411967464942, -1.07142857142857, 0.276641667586246, -0.0958314847499898, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306816, 2.18217890235992, 5.74704893215391, -2.53734018966618, 10.0623058987491, 8.50420064270762, -2.1957751641342, 0.760638829255666, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.42307488958091, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393187, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696593, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.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.0, 1.0}}; + + // 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; 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 < 15; s++) + { + for (unsigned int t = 0; t < 15; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 30; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 7: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 8: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 9: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 11: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 12: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 13: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 14: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 15: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 16: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 17: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 18: + { + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 19: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 20: + { + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 21: + { + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 22: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 23: + { + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 24: + { + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 25: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 26: + { + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 27: + { + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 28: + { + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 29: + { + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[6] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[7] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[0]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[9] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[10] = vals[0]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[0]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[12] = vals[0]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[13] = vals[0]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[14] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[15] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[16] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[17] = vals[1]; + y[0] = 0.75*x[1][0] + 0.25*x[2][0]; + y[1] = 0.75*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[18] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[19] = vals[1]; + y[0] = 0.25*x[1][0] + 0.75*x[2][0]; + y[1] = 0.25*x[1][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[20] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[2][0]; + y[1] = 0.75*x[0][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[21] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[22] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[2][0]; + y[1] = 0.25*x[0][1] + 0.75*x[2][1]; + f.evaluate(vals, y, c); + values[23] = vals[1]; + y[0] = 0.75*x[0][0] + 0.25*x[1][0]; + y[1] = 0.75*x[0][1] + 0.25*x[1][1]; + f.evaluate(vals, y, c); + values[24] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[25] = vals[1]; + y[0] = 0.25*x[0][0] + 0.75*x[1][0]; + y[1] = 0.25*x[0][1] + 0.75*x[1][1]; + f.evaluate(vals, y, c); + values[26] = vals[1]; + y[0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + y[1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[27] = vals[1]; + y[0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + y[1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + f.evaluate(vals, y, c); + values[28] = vals[1]; + y[0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + y[1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[29] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[15]; + vertex_values[3] = dof_values[16]; + vertex_values[5] = dof_values[17]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q4_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q4_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + 3*m.num_entities[1] + 3*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 15; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 15; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 5; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 3; + break; + } + case 2: + { + return 3; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p1_q4_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p1_q4_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return true; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 6*m.num_entities[1] + 6*m.num_entities[2]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 30; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 30; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 10; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 6; + break; + } + case 2: + { + return 6; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + 3*c.entity_indices[1][0]; + dofs[4] = offset + 3*c.entity_indices[1][0] + 1; + dofs[5] = offset + 3*c.entity_indices[1][0] + 2; + dofs[6] = offset + 3*c.entity_indices[1][1]; + dofs[7] = offset + 3*c.entity_indices[1][1] + 1; + dofs[8] = offset + 3*c.entity_indices[1][1] + 2; + dofs[9] = offset + 3*c.entity_indices[1][2]; + dofs[10] = offset + 3*c.entity_indices[1][2] + 1; + dofs[11] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[12] = offset + 3*c.entity_indices[2][0]; + dofs[13] = offset + 3*c.entity_indices[2][0] + 1; + dofs[14] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + dofs[15] = offset + c.entity_indices[0][0]; + dofs[16] = offset + c.entity_indices[0][1]; + dofs[17] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[18] = offset + 3*c.entity_indices[1][0]; + dofs[19] = offset + 3*c.entity_indices[1][0] + 1; + dofs[20] = offset + 3*c.entity_indices[1][0] + 2; + dofs[21] = offset + 3*c.entity_indices[1][1]; + dofs[22] = offset + 3*c.entity_indices[1][1] + 1; + dofs[23] = offset + 3*c.entity_indices[1][1] + 2; + dofs[24] = offset + 3*c.entity_indices[1][2]; + dofs[25] = offset + 3*c.entity_indices[1][2] + 1; + dofs[26] = offset + 3*c.entity_indices[1][2] + 2; + offset += 3*m.num_entities[1]; + dofs[27] = offset + 3*c.entity_indices[2][0]; + dofs[28] = offset + 3*c.entity_indices[2][0] + 1; + dofs[29] = offset + 3*c.entity_indices[2][0] + 2; + offset += 3*m.num_entities[2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 4; + dofs[4] = 5; + dofs[5] = 16; + dofs[6] = 17; + dofs[7] = 18; + dofs[8] = 19; + dofs[9] = 20; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 6; + dofs[3] = 7; + dofs[4] = 8; + dofs[5] = 15; + dofs[6] = 17; + dofs[7] = 21; + dofs[8] = 22; + dofs[9] = 23; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 9; + dofs[3] = 10; + dofs[4] = 11; + dofs[5] = 15; + dofs[6] = 16; + dofs[7] = 24; + dofs[8] = 25; + dofs[9] = 26; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 15; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 16; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 17; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 4; + dofs[2] = 5; + dofs[3] = 18; + dofs[4] = 19; + dofs[5] = 20; + break; + } + case 1: + { + dofs[0] = 6; + dofs[1] = 7; + dofs[2] = 8; + dofs[3] = 21; + dofs[4] = 22; + dofs[5] = 23; + break; + } + case 2: + { + dofs[0] = 9; + dofs[1] = 10; + dofs[2] = 11; + dofs[3] = 24; + dofs[4] = 25; + dofs[5] = 26; + break; + } + } + + break; + } + case 2: + { + if (i > 0) + { + throw std::runtime_error("i is larger than number of entities (0)"); + } + + dofs[0] = 12; + dofs[1] = 13; + dofs[2] = 14; + dofs[3] = 27; + dofs[4] = 28; + dofs[5] = 29; + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[3][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[5][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[5][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[6][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[6][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[7][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[7][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[8][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[8][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[9][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[9][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[10][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[10][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[11][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[11][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[12][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[12][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[13][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[13][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[14][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[14][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + coordinates[15][0] = x[0][0]; + coordinates[15][1] = x[0][1]; + coordinates[16][0] = x[1][0]; + coordinates[16][1] = x[1][1]; + coordinates[17][0] = x[2][0]; + coordinates[17][1] = x[2][1]; + coordinates[18][0] = 0.75*x[1][0] + 0.25*x[2][0]; + coordinates[18][1] = 0.75*x[1][1] + 0.25*x[2][1]; + coordinates[19][0] = 0.5*x[1][0] + 0.5*x[2][0]; + coordinates[19][1] = 0.5*x[1][1] + 0.5*x[2][1]; + coordinates[20][0] = 0.25*x[1][0] + 0.75*x[2][0]; + coordinates[20][1] = 0.25*x[1][1] + 0.75*x[2][1]; + coordinates[21][0] = 0.75*x[0][0] + 0.25*x[2][0]; + coordinates[21][1] = 0.75*x[0][1] + 0.25*x[2][1]; + coordinates[22][0] = 0.5*x[0][0] + 0.5*x[2][0]; + coordinates[22][1] = 0.5*x[0][1] + 0.5*x[2][1]; + coordinates[23][0] = 0.25*x[0][0] + 0.75*x[2][0]; + coordinates[23][1] = 0.25*x[0][1] + 0.75*x[2][1]; + coordinates[24][0] = 0.75*x[0][0] + 0.25*x[1][0]; + coordinates[24][1] = 0.75*x[0][1] + 0.25*x[1][1]; + coordinates[25][0] = 0.5*x[0][0] + 0.5*x[1][0]; + coordinates[25][1] = 0.5*x[0][1] + 0.5*x[1][1]; + coordinates[26][0] = 0.25*x[0][0] + 0.75*x[1][0]; + coordinates[26][1] = 0.25*x[0][1] + 0.75*x[1][1]; + coordinates[27][0] = 0.5*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0]; + coordinates[27][1] = 0.5*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1]; + coordinates[28][0] = 0.25*x[0][0] + 0.5*x[1][0] + 0.25*x[2][0]; + coordinates[28][1] = 0.25*x[0][1] + 0.5*x[1][1] + 0.25*x[2][1]; + coordinates[29][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.5*x[2][0]; + coordinates[29][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.5*x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f2_p1_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 1024 + // Number of operations (multiply-add pairs) for tensor contraction: 14524 + // Total number of operations (multiply-add pairs): 15559 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_3_1_0 = det*(w[0][0]*w[1][3]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_3_1_1 = det*(w[0][0]*w[1][3]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_4_1_0 = det*(w[0][0]*w[1][4]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_5_1_1 = det*(w[0][0]*w[1][5]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_3_1_0 = det*(w[0][0]*w[1][3]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_3_1_1 = det*(w[0][0]*w[1][3]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_4_1_0 = det*(w[0][0]*w[1][4]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_5_1_1 = det*(w[0][0]*w[1][5]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_3_1_0 = det*(w[0][1]*w[1][3]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_3_1_1 = det*(w[0][1]*w[1][3]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_4_1_0 = det*(w[0][1]*w[1][4]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_5_1_1 = det*(w[0][1]*w[1][5]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_3_1_0 = det*(w[0][2]*w[1][3]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_3_1_1 = det*(w[0][2]*w[1][3]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_4_1_0 = det*(w[0][2]*w[1][4]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_5_1_1 = det*(w[0][2]*w[1][5]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_0_0_0 = det*(w[0][3]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_0_0_1 = det*(w[0][3]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_1_0_0 = det*(w[0][3]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_2_0_1 = det*(w[0][3]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_3_1_0 = det*(w[0][3]*w[1][3]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_3_1_1 = det*(w[0][3]*w[1][3]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_4_1_0 = det*(w[0][3]*w[1][4]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_0_5_1_1 = det*(w[0][3]*w[1][5]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_0_0_0 = det*(w[0][3]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_0_0_1 = det*(w[0][3]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_1_0_0 = det*(w[0][3]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_2_0_1 = det*(w[0][3]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_3_1_0 = det*(w[0][3]*w[1][3]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_3_1_1 = det*(w[0][3]*w[1][3]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_4_1_0 = det*(w[0][3]*w[1][4]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_1_1_5_1_1 = det*(w[0][3]*w[1][5]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_0_0_0 = det*(w[0][4]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_0_0_1 = det*(w[0][4]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_1_0_0 = det*(w[0][4]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_2_0_1 = det*(w[0][4]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_3_1_0 = det*(w[0][4]*w[1][3]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_3_1_1 = det*(w[0][4]*w[1][3]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_4_1_0 = det*(w[0][4]*w[1][4]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_1_0_5_1_1 = det*(w[0][4]*w[1][5]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_0_0_0 = det*(w[0][5]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_0_0_1 = det*(w[0][5]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_1_0_0 = det*(w[0][5]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_2_0_1 = det*(w[0][5]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_3_1_0 = det*(w[0][5]*w[1][3]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_3_1_1 = det*(w[0][5]*w[1][3]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_4_1_0 = det*(w[0][5]*w[1][4]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_1_1_5_1_1 = det*(w[0][5]*w[1][5]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[213] = -0.152380952380962*G0_0_0_0_0_0_0_0_0 - 0.152380952380962*G0_0_0_0_0_0_0_0_1 + 0.152380952380962*G0_0_0_0_0_0_1_0_0 + 0.152380952380962*G0_0_0_0_0_0_2_0_1 - 0.152380952380962*G0_0_0_0_0_0_3_1_0 - 0.152380952380962*G0_0_0_0_0_0_3_1_1 + 0.152380952380962*G0_0_0_0_0_0_4_1_0 + 0.152380952380962*G0_0_0_0_0_0_5_1_1 - 0.152380952380962*G0_0_0_0_0_1_0_0_0 - 0.152380952380962*G0_0_0_0_0_1_0_0_1 + 0.152380952380962*G0_0_0_0_0_1_1_0_0 + 0.152380952380962*G0_0_0_0_0_1_2_0_1 - 0.152380952380962*G0_0_0_0_0_1_3_1_0 - 0.152380952380962*G0_0_0_0_0_1_3_1_1 + 0.152380952380962*G0_0_0_0_0_1_4_1_0 + 0.152380952380962*G0_0_0_0_0_1_5_1_1 + 0.152380952380962*G0_0_0_1_0_0_0_0_0 + 0.152380952380962*G0_0_0_1_0_0_0_0_1 - 0.152380952380962*G0_0_0_1_0_0_1_0_0 - 0.152380952380962*G0_0_0_1_0_0_2_0_1 + 0.152380952380962*G0_0_0_1_0_0_3_1_0 + 0.152380952380962*G0_0_0_1_0_0_3_1_1 - 0.152380952380962*G0_0_0_1_0_0_4_1_0 - 0.152380952380962*G0_0_0_1_0_0_5_1_1 + 0.152380952380962*G0_0_0_2_0_1_0_0_0 + 0.152380952380962*G0_0_0_2_0_1_0_0_1 - 0.152380952380962*G0_0_0_2_0_1_1_0_0 - 0.152380952380962*G0_0_0_2_0_1_2_0_1 + 0.152380952380962*G0_0_0_2_0_1_3_1_0 + 0.152380952380962*G0_0_0_2_0_1_3_1_1 - 0.152380952380962*G0_0_0_2_0_1_4_1_0 - 0.152380952380962*G0_0_0_2_0_1_5_1_1 - 0.152380952380962*G0_0_0_3_1_0_0_0_0 - 0.152380952380962*G0_0_0_3_1_0_0_0_1 + 0.152380952380962*G0_0_0_3_1_0_1_0_0 + 0.152380952380962*G0_0_0_3_1_0_2_0_1 - 0.152380952380962*G0_0_0_3_1_0_3_1_0 - 0.152380952380962*G0_0_0_3_1_0_3_1_1 + 0.152380952380962*G0_0_0_3_1_0_4_1_0 + 0.152380952380962*G0_0_0_3_1_0_5_1_1 - 0.152380952380962*G0_0_0_3_1_1_0_0_0 - 0.152380952380962*G0_0_0_3_1_1_0_0_1 + 0.152380952380962*G0_0_0_3_1_1_1_0_0 + 0.152380952380962*G0_0_0_3_1_1_2_0_1 - 0.152380952380962*G0_0_0_3_1_1_3_1_0 - 0.152380952380962*G0_0_0_3_1_1_3_1_1 + 0.152380952380962*G0_0_0_3_1_1_4_1_0 + 0.152380952380962*G0_0_0_3_1_1_5_1_1 + 0.152380952380962*G0_0_0_4_1_0_0_0_0 + 0.152380952380962*G0_0_0_4_1_0_0_0_1 - 0.152380952380962*G0_0_0_4_1_0_1_0_0 - 0.152380952380962*G0_0_0_4_1_0_2_0_1 + 0.152380952380962*G0_0_0_4_1_0_3_1_0 + 0.152380952380962*G0_0_0_4_1_0_3_1_1 - 0.152380952380962*G0_0_0_4_1_0_4_1_0 - 0.152380952380962*G0_0_0_4_1_0_5_1_1 + 0.152380952380962*G0_0_0_5_1_1_0_0_0 + 0.152380952380962*G0_0_0_5_1_1_0_0_1 - 0.152380952380962*G0_0_0_5_1_1_1_0_0 - 0.152380952380962*G0_0_0_5_1_1_2_0_1 + 0.152380952380962*G0_0_0_5_1_1_3_1_0 + 0.152380952380962*G0_0_0_5_1_1_3_1_1 - 0.152380952380962*G0_0_0_5_1_1_4_1_0 - 0.152380952380962*G0_0_0_5_1_1_5_1_1 - 0.042328042328044*G0_0_1_0_0_0_0_0_0 - 0.042328042328044*G0_0_1_0_0_0_0_0_1 + 0.042328042328044*G0_0_1_0_0_0_1_0_0 + 0.042328042328044*G0_0_1_0_0_0_2_0_1 - 0.042328042328044*G0_0_1_0_0_0_3_1_0 - 0.042328042328044*G0_0_1_0_0_0_3_1_1 + 0.042328042328044*G0_0_1_0_0_0_4_1_0 + 0.042328042328044*G0_0_1_0_0_0_5_1_1 - 0.042328042328044*G0_0_1_0_0_1_0_0_0 - 0.042328042328044*G0_0_1_0_0_1_0_0_1 + 0.042328042328044*G0_0_1_0_0_1_1_0_0 + 0.042328042328044*G0_0_1_0_0_1_2_0_1 - 0.042328042328044*G0_0_1_0_0_1_3_1_0 - 0.042328042328044*G0_0_1_0_0_1_3_1_1 + 0.042328042328044*G0_0_1_0_0_1_4_1_0 + 0.042328042328044*G0_0_1_0_0_1_5_1_1 + 0.042328042328044*G0_0_1_1_0_0_0_0_0 + 0.042328042328044*G0_0_1_1_0_0_0_0_1 - 0.042328042328044*G0_0_1_1_0_0_1_0_0 - 0.042328042328044*G0_0_1_1_0_0_2_0_1 + 0.042328042328044*G0_0_1_1_0_0_3_1_0 + 0.042328042328044*G0_0_1_1_0_0_3_1_1 - 0.042328042328044*G0_0_1_1_0_0_4_1_0 - 0.042328042328044*G0_0_1_1_0_0_5_1_1 + 0.042328042328044*G0_0_1_2_0_1_0_0_0 + 0.042328042328044*G0_0_1_2_0_1_0_0_1 - 0.042328042328044*G0_0_1_2_0_1_1_0_0 - 0.042328042328044*G0_0_1_2_0_1_2_0_1 + 0.042328042328044*G0_0_1_2_0_1_3_1_0 + 0.042328042328044*G0_0_1_2_0_1_3_1_1 - 0.042328042328044*G0_0_1_2_0_1_4_1_0 - 0.042328042328044*G0_0_1_2_0_1_5_1_1 - 0.042328042328044*G0_0_1_3_1_0_0_0_0 - 0.042328042328044*G0_0_1_3_1_0_0_0_1 + 0.042328042328044*G0_0_1_3_1_0_1_0_0 + 0.042328042328044*G0_0_1_3_1_0_2_0_1 - 0.042328042328044*G0_0_1_3_1_0_3_1_0 - 0.042328042328044*G0_0_1_3_1_0_3_1_1 + 0.042328042328044*G0_0_1_3_1_0_4_1_0 + 0.042328042328044*G0_0_1_3_1_0_5_1_1 - 0.042328042328044*G0_0_1_3_1_1_0_0_0 - 0.042328042328044*G0_0_1_3_1_1_0_0_1 + 0.042328042328044*G0_0_1_3_1_1_1_0_0 + 0.042328042328044*G0_0_1_3_1_1_2_0_1 - 0.042328042328044*G0_0_1_3_1_1_3_1_0 - 0.042328042328044*G0_0_1_3_1_1_3_1_1 + 0.042328042328044*G0_0_1_3_1_1_4_1_0 + 0.042328042328044*G0_0_1_3_1_1_5_1_1 + 0.042328042328044*G0_0_1_4_1_0_0_0_0 + 0.042328042328044*G0_0_1_4_1_0_0_0_1 - 0.042328042328044*G0_0_1_4_1_0_1_0_0 - 0.042328042328044*G0_0_1_4_1_0_2_0_1 + 0.042328042328044*G0_0_1_4_1_0_3_1_0 + 0.042328042328044*G0_0_1_4_1_0_3_1_1 - 0.042328042328044*G0_0_1_4_1_0_4_1_0 - 0.042328042328044*G0_0_1_4_1_0_5_1_1 + 0.042328042328044*G0_0_1_5_1_1_0_0_0 + 0.042328042328044*G0_0_1_5_1_1_0_0_1 - 0.042328042328044*G0_0_1_5_1_1_1_0_0 - 0.042328042328044*G0_0_1_5_1_1_2_0_1 + 0.042328042328044*G0_0_1_5_1_1_3_1_0 + 0.042328042328044*G0_0_1_5_1_1_3_1_1 - 0.042328042328044*G0_0_1_5_1_1_4_1_0 - 0.042328042328044*G0_0_1_5_1_1_5_1_1 - 0.0423280423280468*G0_1_0_0_0_0_0_0_0 - 0.0423280423280468*G0_1_0_0_0_0_0_0_1 + 0.0423280423280468*G0_1_0_0_0_0_1_0_0 + 0.0423280423280468*G0_1_0_0_0_0_2_0_1 - 0.0423280423280468*G0_1_0_0_0_0_3_1_0 - 0.0423280423280468*G0_1_0_0_0_0_3_1_1 + 0.0423280423280468*G0_1_0_0_0_0_4_1_0 + 0.0423280423280468*G0_1_0_0_0_0_5_1_1 - 0.0423280423280468*G0_1_0_0_0_1_0_0_0 - 0.0423280423280468*G0_1_0_0_0_1_0_0_1 + 0.0423280423280468*G0_1_0_0_0_1_1_0_0 + 0.0423280423280468*G0_1_0_0_0_1_2_0_1 - 0.0423280423280468*G0_1_0_0_0_1_3_1_0 - 0.0423280423280468*G0_1_0_0_0_1_3_1_1 + 0.0423280423280468*G0_1_0_0_0_1_4_1_0 + 0.0423280423280468*G0_1_0_0_0_1_5_1_1 + 0.0423280423280468*G0_1_0_1_0_0_0_0_0 + 0.0423280423280468*G0_1_0_1_0_0_0_0_1 - 0.0423280423280468*G0_1_0_1_0_0_1_0_0 - 0.0423280423280468*G0_1_0_1_0_0_2_0_1 + 0.0423280423280468*G0_1_0_1_0_0_3_1_0 + 0.0423280423280468*G0_1_0_1_0_0_3_1_1 - 0.0423280423280468*G0_1_0_1_0_0_4_1_0 - 0.0423280423280468*G0_1_0_1_0_0_5_1_1 + 0.0423280423280468*G0_1_0_2_0_1_0_0_0 + 0.0423280423280468*G0_1_0_2_0_1_0_0_1 - 0.0423280423280468*G0_1_0_2_0_1_1_0_0 - 0.0423280423280468*G0_1_0_2_0_1_2_0_1 + 0.0423280423280468*G0_1_0_2_0_1_3_1_0 + 0.0423280423280468*G0_1_0_2_0_1_3_1_1 - 0.0423280423280468*G0_1_0_2_0_1_4_1_0 - 0.0423280423280468*G0_1_0_2_0_1_5_1_1 - 0.0423280423280468*G0_1_0_3_1_0_0_0_0 - 0.0423280423280468*G0_1_0_3_1_0_0_0_1 + 0.0423280423280468*G0_1_0_3_1_0_1_0_0 + 0.0423280423280468*G0_1_0_3_1_0_2_0_1 - 0.0423280423280468*G0_1_0_3_1_0_3_1_0 - 0.0423280423280468*G0_1_0_3_1_0_3_1_1 + 0.0423280423280468*G0_1_0_3_1_0_4_1_0 + 0.0423280423280468*G0_1_0_3_1_0_5_1_1 - 0.0423280423280468*G0_1_0_3_1_1_0_0_0 - 0.0423280423280468*G0_1_0_3_1_1_0_0_1 + 0.0423280423280468*G0_1_0_3_1_1_1_0_0 + 0.0423280423280468*G0_1_0_3_1_1_2_0_1 - 0.0423280423280468*G0_1_0_3_1_1_3_1_0 - 0.0423280423280468*G0_1_0_3_1_1_3_1_1 + 0.0423280423280468*G0_1_0_3_1_1_4_1_0 + 0.0423280423280468*G0_1_0_3_1_1_5_1_1 + 0.0423280423280468*G0_1_0_4_1_0_0_0_0 + 0.0423280423280468*G0_1_0_4_1_0_0_0_1 - 0.0423280423280468*G0_1_0_4_1_0_1_0_0 - 0.0423280423280468*G0_1_0_4_1_0_2_0_1 + 0.0423280423280468*G0_1_0_4_1_0_3_1_0 + 0.0423280423280468*G0_1_0_4_1_0_3_1_1 - 0.0423280423280468*G0_1_0_4_1_0_4_1_0 - 0.0423280423280468*G0_1_0_4_1_0_5_1_1 + 0.0423280423280468*G0_1_0_5_1_1_0_0_0 + 0.0423280423280468*G0_1_0_5_1_1_0_0_1 - 0.0423280423280468*G0_1_0_5_1_1_1_0_0 - 0.0423280423280468*G0_1_0_5_1_1_2_0_1 + 0.0423280423280468*G0_1_0_5_1_1_3_1_0 + 0.0423280423280468*G0_1_0_5_1_1_3_1_1 - 0.0423280423280468*G0_1_0_5_1_1_4_1_0 - 0.0423280423280468*G0_1_0_5_1_1_5_1_1; + A[625] = A[213] + 0.152380952380962*G0_0_0_0_0_0_0_0_0 + 0.152380952380962*G0_0_0_0_0_0_0_0_1 - 0.152380952380962*G0_0_0_0_0_0_1_0_0 - 0.152380952380962*G0_0_0_0_0_0_2_0_1 + 0.152380952380962*G0_0_0_0_0_0_3_1_0 + 0.152380952380962*G0_0_0_0_0_0_3_1_1 - 0.152380952380962*G0_0_0_0_0_0_4_1_0 - 0.152380952380962*G0_0_0_0_0_0_5_1_1 + 0.152380952380962*G0_0_0_0_0_1_0_0_0 + 0.152380952380962*G0_0_0_0_0_1_0_0_1 - 0.152380952380962*G0_0_0_0_0_1_1_0_0 - 0.152380952380962*G0_0_0_0_0_1_2_0_1 + 0.152380952380962*G0_0_0_0_0_1_3_1_0 + 0.152380952380962*G0_0_0_0_0_1_3_1_1 - 0.152380952380962*G0_0_0_0_0_1_4_1_0 - 0.152380952380962*G0_0_0_0_0_1_5_1_1 - 0.152380952380962*G0_0_0_1_0_0_0_0_0 - 0.152380952380962*G0_0_0_1_0_0_0_0_1 + 0.152380952380962*G0_0_0_1_0_0_1_0_0 + 0.152380952380962*G0_0_0_1_0_0_2_0_1 - 0.152380952380962*G0_0_0_1_0_0_3_1_0 - 0.152380952380962*G0_0_0_1_0_0_3_1_1 + 0.152380952380962*G0_0_0_1_0_0_4_1_0 + 0.152380952380962*G0_0_0_1_0_0_5_1_1 - 0.152380952380962*G0_0_0_2_0_1_0_0_0 - 0.152380952380962*G0_0_0_2_0_1_0_0_1 + 0.152380952380962*G0_0_0_2_0_1_1_0_0 + 0.152380952380962*G0_0_0_2_0_1_2_0_1 - 0.152380952380962*G0_0_0_2_0_1_3_1_0 - 0.152380952380962*G0_0_0_2_0_1_3_1_1 + 0.152380952380962*G0_0_0_2_0_1_4_1_0 + 0.152380952380962*G0_0_0_2_0_1_5_1_1 + 0.152380952380962*G0_0_0_3_1_0_0_0_0 + 0.152380952380962*G0_0_0_3_1_0_0_0_1 - 0.152380952380962*G0_0_0_3_1_0_1_0_0 - 0.152380952380962*G0_0_0_3_1_0_2_0_1 + 0.152380952380962*G0_0_0_3_1_0_3_1_0 + 0.152380952380962*G0_0_0_3_1_0_3_1_1 - 0.152380952380962*G0_0_0_3_1_0_4_1_0 - 0.152380952380962*G0_0_0_3_1_0_5_1_1 + 0.152380952380962*G0_0_0_3_1_1_0_0_0 + 0.152380952380962*G0_0_0_3_1_1_0_0_1 - 0.152380952380962*G0_0_0_3_1_1_1_0_0 - 0.152380952380962*G0_0_0_3_1_1_2_0_1 + 0.152380952380962*G0_0_0_3_1_1_3_1_0 + 0.152380952380962*G0_0_0_3_1_1_3_1_1 - 0.152380952380962*G0_0_0_3_1_1_4_1_0 - 0.152380952380962*G0_0_0_3_1_1_5_1_1 - 0.152380952380962*G0_0_0_4_1_0_0_0_0 - 0.152380952380962*G0_0_0_4_1_0_0_0_1 + 0.152380952380962*G0_0_0_4_1_0_1_0_0 + 0.152380952380962*G0_0_0_4_1_0_2_0_1 - 0.152380952380962*G0_0_0_4_1_0_3_1_0 - 0.152380952380962*G0_0_0_4_1_0_3_1_1 + 0.152380952380962*G0_0_0_4_1_0_4_1_0 + 0.152380952380962*G0_0_0_4_1_0_5_1_1 - 0.152380952380962*G0_0_0_5_1_1_0_0_0 - 0.152380952380962*G0_0_0_5_1_1_0_0_1 + 0.152380952380962*G0_0_0_5_1_1_1_0_0 + 0.152380952380962*G0_0_0_5_1_1_2_0_1 - 0.152380952380962*G0_0_0_5_1_1_3_1_0 - 0.152380952380962*G0_0_0_5_1_1_3_1_1 + 0.152380952380962*G0_0_0_5_1_1_4_1_0 + 0.152380952380962*G0_0_0_5_1_1_5_1_1 - 0.152380952380961*G0_1_1_0_0_0_0_0_0 - 0.152380952380961*G0_1_1_0_0_0_0_0_1 + 0.152380952380961*G0_1_1_0_0_0_1_0_0 + 0.152380952380961*G0_1_1_0_0_0_2_0_1 - 0.152380952380961*G0_1_1_0_0_0_3_1_0 - 0.152380952380961*G0_1_1_0_0_0_3_1_1 + 0.152380952380961*G0_1_1_0_0_0_4_1_0 + 0.152380952380961*G0_1_1_0_0_0_5_1_1 - 0.152380952380961*G0_1_1_0_0_1_0_0_0 - 0.152380952380961*G0_1_1_0_0_1_0_0_1 + 0.152380952380961*G0_1_1_0_0_1_1_0_0 + 0.152380952380961*G0_1_1_0_0_1_2_0_1 - 0.152380952380961*G0_1_1_0_0_1_3_1_0 - 0.152380952380961*G0_1_1_0_0_1_3_1_1 + 0.152380952380961*G0_1_1_0_0_1_4_1_0 + 0.152380952380961*G0_1_1_0_0_1_5_1_1 + 0.152380952380961*G0_1_1_1_0_0_0_0_0 + 0.152380952380961*G0_1_1_1_0_0_0_0_1 - 0.152380952380961*G0_1_1_1_0_0_1_0_0 - 0.152380952380961*G0_1_1_1_0_0_2_0_1 + 0.152380952380961*G0_1_1_1_0_0_3_1_0 + 0.152380952380961*G0_1_1_1_0_0_3_1_1 - 0.152380952380961*G0_1_1_1_0_0_4_1_0 - 0.152380952380961*G0_1_1_1_0_0_5_1_1 + 0.152380952380961*G0_1_1_2_0_1_0_0_0 + 0.152380952380961*G0_1_1_2_0_1_0_0_1 - 0.152380952380961*G0_1_1_2_0_1_1_0_0 - 0.152380952380961*G0_1_1_2_0_1_2_0_1 + 0.152380952380961*G0_1_1_2_0_1_3_1_0 + 0.152380952380961*G0_1_1_2_0_1_3_1_1 - 0.152380952380961*G0_1_1_2_0_1_4_1_0 - 0.152380952380961*G0_1_1_2_0_1_5_1_1 - 0.152380952380961*G0_1_1_3_1_0_0_0_0 - 0.152380952380961*G0_1_1_3_1_0_0_0_1 + 0.152380952380961*G0_1_1_3_1_0_1_0_0 + 0.152380952380961*G0_1_1_3_1_0_2_0_1 - 0.152380952380961*G0_1_1_3_1_0_3_1_0 - 0.152380952380961*G0_1_1_3_1_0_3_1_1 + 0.152380952380961*G0_1_1_3_1_0_4_1_0 + 0.152380952380961*G0_1_1_3_1_0_5_1_1 - 0.152380952380961*G0_1_1_3_1_1_0_0_0 - 0.152380952380961*G0_1_1_3_1_1_0_0_1 + 0.152380952380961*G0_1_1_3_1_1_1_0_0 + 0.152380952380961*G0_1_1_3_1_1_2_0_1 - 0.152380952380961*G0_1_1_3_1_1_3_1_0 - 0.152380952380961*G0_1_1_3_1_1_3_1_1 + 0.152380952380961*G0_1_1_3_1_1_4_1_0 + 0.152380952380961*G0_1_1_3_1_1_5_1_1 + 0.152380952380961*G0_1_1_4_1_0_0_0_0 + 0.152380952380961*G0_1_1_4_1_0_0_0_1 - 0.152380952380961*G0_1_1_4_1_0_1_0_0 - 0.152380952380961*G0_1_1_4_1_0_2_0_1 + 0.152380952380961*G0_1_1_4_1_0_3_1_0 + 0.152380952380961*G0_1_1_4_1_0_3_1_1 - 0.152380952380961*G0_1_1_4_1_0_4_1_0 - 0.152380952380961*G0_1_1_4_1_0_5_1_1 + 0.152380952380961*G0_1_1_5_1_1_0_0_0 + 0.152380952380961*G0_1_1_5_1_1_0_0_1 - 0.152380952380961*G0_1_1_5_1_1_1_0_0 - 0.152380952380961*G0_1_1_5_1_1_2_0_1 + 0.152380952380961*G0_1_1_5_1_1_3_1_0 + 0.152380952380961*G0_1_1_5_1_1_3_1_1 - 0.152380952380961*G0_1_1_5_1_1_4_1_0 - 0.152380952380961*G0_1_1_5_1_1_5_1_1; + A[489] = 0.0; + A[208] = 0.0; + A[574] = 0.0; + A[530] = 0.778835978835987*G0_1_0_0_0_0_0_0_0 + 0.778835978835987*G0_1_0_0_0_0_0_0_1 - 0.778835978835987*G0_1_0_0_0_0_1_0_0 - 0.778835978835987*G0_1_0_0_0_0_2_0_1 + 0.778835978835987*G0_1_0_0_0_0_3_1_0 + 0.778835978835987*G0_1_0_0_0_0_3_1_1 - 0.778835978835987*G0_1_0_0_0_0_4_1_0 - 0.778835978835987*G0_1_0_0_0_0_5_1_1 + 0.778835978835987*G0_1_0_0_0_1_0_0_0 + 0.778835978835987*G0_1_0_0_0_1_0_0_1 - 0.778835978835987*G0_1_0_0_0_1_1_0_0 - 0.778835978835987*G0_1_0_0_0_1_2_0_1 + 0.778835978835987*G0_1_0_0_0_1_3_1_0 + 0.778835978835987*G0_1_0_0_0_1_3_1_1 - 0.778835978835987*G0_1_0_0_0_1_4_1_0 - 0.778835978835987*G0_1_0_0_0_1_5_1_1 - 0.778835978835987*G0_1_0_1_0_0_0_0_0 - 0.778835978835987*G0_1_0_1_0_0_0_0_1 + 0.778835978835987*G0_1_0_1_0_0_1_0_0 + 0.778835978835987*G0_1_0_1_0_0_2_0_1 - 0.778835978835987*G0_1_0_1_0_0_3_1_0 - 0.778835978835987*G0_1_0_1_0_0_3_1_1 + 0.778835978835987*G0_1_0_1_0_0_4_1_0 + 0.778835978835987*G0_1_0_1_0_0_5_1_1 - 0.778835978835987*G0_1_0_2_0_1_0_0_0 - 0.778835978835987*G0_1_0_2_0_1_0_0_1 + 0.778835978835987*G0_1_0_2_0_1_1_0_0 + 0.778835978835987*G0_1_0_2_0_1_2_0_1 - 0.778835978835987*G0_1_0_2_0_1_3_1_0 - 0.778835978835987*G0_1_0_2_0_1_3_1_1 + 0.778835978835987*G0_1_0_2_0_1_4_1_0 + 0.778835978835987*G0_1_0_2_0_1_5_1_1 + 0.778835978835987*G0_1_0_3_1_0_0_0_0 + 0.778835978835987*G0_1_0_3_1_0_0_0_1 - 0.778835978835987*G0_1_0_3_1_0_1_0_0 - 0.778835978835987*G0_1_0_3_1_0_2_0_1 + 0.778835978835987*G0_1_0_3_1_0_3_1_0 + 0.778835978835987*G0_1_0_3_1_0_3_1_1 - 0.778835978835987*G0_1_0_3_1_0_4_1_0 - 0.778835978835987*G0_1_0_3_1_0_5_1_1 + 0.778835978835987*G0_1_0_3_1_1_0_0_0 + 0.778835978835987*G0_1_0_3_1_1_0_0_1 - 0.778835978835987*G0_1_0_3_1_1_1_0_0 - 0.778835978835987*G0_1_0_3_1_1_2_0_1 + 0.778835978835987*G0_1_0_3_1_1_3_1_0 + 0.778835978835987*G0_1_0_3_1_1_3_1_1 - 0.778835978835987*G0_1_0_3_1_1_4_1_0 - 0.778835978835987*G0_1_0_3_1_1_5_1_1 - 0.778835978835987*G0_1_0_4_1_0_0_0_0 - 0.778835978835987*G0_1_0_4_1_0_0_0_1 + 0.778835978835987*G0_1_0_4_1_0_1_0_0 + 0.778835978835987*G0_1_0_4_1_0_2_0_1 - 0.778835978835987*G0_1_0_4_1_0_3_1_0 - 0.778835978835987*G0_1_0_4_1_0_3_1_1 + 0.778835978835987*G0_1_0_4_1_0_4_1_0 + 0.778835978835987*G0_1_0_4_1_0_5_1_1 - 0.778835978835987*G0_1_0_5_1_1_0_0_0 - 0.778835978835987*G0_1_0_5_1_1_0_0_1 + 0.778835978835987*G0_1_0_5_1_1_1_0_0 + 0.778835978835987*G0_1_0_5_1_1_2_0_1 - 0.778835978835987*G0_1_0_5_1_1_3_1_0 - 0.778835978835987*G0_1_0_5_1_1_3_1_1 + 0.778835978835987*G0_1_0_5_1_1_4_1_0 + 0.778835978835987*G0_1_0_5_1_1_5_1_1 + 0.126984126984127*G0_1_1_0_0_0_0_0_0 + 0.126984126984127*G0_1_1_0_0_0_0_0_1 - 0.126984126984127*G0_1_1_0_0_0_1_0_0 - 0.126984126984127*G0_1_1_0_0_0_2_0_1 + 0.126984126984127*G0_1_1_0_0_0_3_1_0 + 0.126984126984127*G0_1_1_0_0_0_3_1_1 - 0.126984126984127*G0_1_1_0_0_0_4_1_0 - 0.126984126984127*G0_1_1_0_0_0_5_1_1 + 0.126984126984127*G0_1_1_0_0_1_0_0_0 + 0.126984126984127*G0_1_1_0_0_1_0_0_1 - 0.126984126984127*G0_1_1_0_0_1_1_0_0 - 0.126984126984127*G0_1_1_0_0_1_2_0_1 + 0.126984126984127*G0_1_1_0_0_1_3_1_0 + 0.126984126984127*G0_1_1_0_0_1_3_1_1 - 0.126984126984127*G0_1_1_0_0_1_4_1_0 - 0.126984126984127*G0_1_1_0_0_1_5_1_1 - 0.126984126984127*G0_1_1_1_0_0_0_0_0 - 0.126984126984127*G0_1_1_1_0_0_0_0_1 + 0.126984126984127*G0_1_1_1_0_0_1_0_0 + 0.126984126984127*G0_1_1_1_0_0_2_0_1 - 0.126984126984127*G0_1_1_1_0_0_3_1_0 - 0.126984126984127*G0_1_1_1_0_0_3_1_1 + 0.126984126984127*G0_1_1_1_0_0_4_1_0 + 0.126984126984127*G0_1_1_1_0_0_5_1_1 - 0.126984126984127*G0_1_1_2_0_1_0_0_0 - 0.126984126984127*G0_1_1_2_0_1_0_0_1 + 0.126984126984127*G0_1_1_2_0_1_1_0_0 + 0.126984126984127*G0_1_1_2_0_1_2_0_1 - 0.126984126984127*G0_1_1_2_0_1_3_1_0 - 0.126984126984127*G0_1_1_2_0_1_3_1_1 + 0.126984126984127*G0_1_1_2_0_1_4_1_0 + 0.126984126984127*G0_1_1_2_0_1_5_1_1 + 0.126984126984127*G0_1_1_3_1_0_0_0_0 + 0.126984126984127*G0_1_1_3_1_0_0_0_1 - 0.126984126984127*G0_1_1_3_1_0_1_0_0 - 0.126984126984127*G0_1_1_3_1_0_2_0_1 + 0.126984126984127*G0_1_1_3_1_0_3_1_0 + 0.126984126984127*G0_1_1_3_1_0_3_1_1 - 0.126984126984127*G0_1_1_3_1_0_4_1_0 - 0.126984126984127*G0_1_1_3_1_0_5_1_1 + 0.126984126984127*G0_1_1_3_1_1_0_0_0 + 0.126984126984127*G0_1_1_3_1_1_0_0_1 - 0.126984126984127*G0_1_1_3_1_1_1_0_0 - 0.126984126984127*G0_1_1_3_1_1_2_0_1 + 0.126984126984127*G0_1_1_3_1_1_3_1_0 + 0.126984126984127*G0_1_1_3_1_1_3_1_1 - 0.126984126984127*G0_1_1_3_1_1_4_1_0 - 0.126984126984127*G0_1_1_3_1_1_5_1_1 - 0.126984126984127*G0_1_1_4_1_0_0_0_0 - 0.126984126984127*G0_1_1_4_1_0_0_0_1 + 0.126984126984127*G0_1_1_4_1_0_1_0_0 + 0.126984126984127*G0_1_1_4_1_0_2_0_1 - 0.126984126984127*G0_1_1_4_1_0_3_1_0 - 0.126984126984127*G0_1_1_4_1_0_3_1_1 + 0.126984126984127*G0_1_1_4_1_0_4_1_0 + 0.126984126984127*G0_1_1_4_1_0_5_1_1 - 0.126984126984127*G0_1_1_5_1_1_0_0_0 - 0.126984126984127*G0_1_1_5_1_1_0_0_1 + 0.126984126984127*G0_1_1_5_1_1_1_0_0 + 0.126984126984127*G0_1_1_5_1_1_2_0_1 - 0.126984126984127*G0_1_1_5_1_1_3_1_0 - 0.126984126984127*G0_1_1_5_1_1_3_1_1 + 0.126984126984127*G0_1_1_5_1_1_4_1_0 + 0.126984126984127*G0_1_1_5_1_1_5_1_1; + A[235] = 0.0; + A[679] = 0.393650793650818*G0_0_0_0_0_0_0_0_0 + 0.393650793650818*G0_0_0_0_0_0_0_0_1 - 0.393650793650818*G0_0_0_0_0_0_1_0_0 - 0.393650793650818*G0_0_0_0_0_0_2_0_1 + 0.393650793650818*G0_0_0_0_0_0_3_1_0 + 0.393650793650818*G0_0_0_0_0_0_3_1_1 - 0.393650793650818*G0_0_0_0_0_0_4_1_0 - 0.393650793650818*G0_0_0_0_0_0_5_1_1 + 0.393650793650818*G0_0_0_0_0_1_0_0_0 + 0.393650793650818*G0_0_0_0_0_1_0_0_1 - 0.393650793650818*G0_0_0_0_0_1_1_0_0 - 0.393650793650818*G0_0_0_0_0_1_2_0_1 + 0.393650793650818*G0_0_0_0_0_1_3_1_0 + 0.393650793650818*G0_0_0_0_0_1_3_1_1 - 0.393650793650818*G0_0_0_0_0_1_4_1_0 - 0.393650793650818*G0_0_0_0_0_1_5_1_1 - 0.393650793650818*G0_0_0_1_0_0_0_0_0 - 0.393650793650818*G0_0_0_1_0_0_0_0_1 + 0.393650793650818*G0_0_0_1_0_0_1_0_0 + 0.393650793650818*G0_0_0_1_0_0_2_0_1 - 0.393650793650818*G0_0_0_1_0_0_3_1_0 - 0.393650793650818*G0_0_0_1_0_0_3_1_1 + 0.393650793650818*G0_0_0_1_0_0_4_1_0 + 0.393650793650818*G0_0_0_1_0_0_5_1_1 - 0.393650793650818*G0_0_0_2_0_1_0_0_0 - 0.393650793650818*G0_0_0_2_0_1_0_0_1 + 0.393650793650818*G0_0_0_2_0_1_1_0_0 + 0.393650793650818*G0_0_0_2_0_1_2_0_1 - 0.393650793650818*G0_0_0_2_0_1_3_1_0 - 0.393650793650818*G0_0_0_2_0_1_3_1_1 + 0.393650793650818*G0_0_0_2_0_1_4_1_0 + 0.393650793650818*G0_0_0_2_0_1_5_1_1 + 0.393650793650818*G0_0_0_3_1_0_0_0_0 + 0.393650793650818*G0_0_0_3_1_0_0_0_1 - 0.393650793650818*G0_0_0_3_1_0_1_0_0 - 0.393650793650818*G0_0_0_3_1_0_2_0_1 + 0.393650793650818*G0_0_0_3_1_0_3_1_0 + 0.393650793650818*G0_0_0_3_1_0_3_1_1 - 0.393650793650818*G0_0_0_3_1_0_4_1_0 - 0.393650793650818*G0_0_0_3_1_0_5_1_1 + 0.393650793650818*G0_0_0_3_1_1_0_0_0 + 0.393650793650818*G0_0_0_3_1_1_0_0_1 - 0.393650793650818*G0_0_0_3_1_1_1_0_0 - 0.393650793650818*G0_0_0_3_1_1_2_0_1 + 0.393650793650818*G0_0_0_3_1_1_3_1_0 + 0.393650793650818*G0_0_0_3_1_1_3_1_1 - 0.393650793650818*G0_0_0_3_1_1_4_1_0 - 0.393650793650818*G0_0_0_3_1_1_5_1_1 - 0.393650793650818*G0_0_0_4_1_0_0_0_0 - 0.393650793650818*G0_0_0_4_1_0_0_0_1 + 0.393650793650818*G0_0_0_4_1_0_1_0_0 + 0.393650793650818*G0_0_0_4_1_0_2_0_1 - 0.393650793650818*G0_0_0_4_1_0_3_1_0 - 0.393650793650818*G0_0_0_4_1_0_3_1_1 + 0.393650793650818*G0_0_0_4_1_0_4_1_0 + 0.393650793650818*G0_0_0_4_1_0_5_1_1 - 0.393650793650818*G0_0_0_5_1_1_0_0_0 - 0.393650793650818*G0_0_0_5_1_1_0_0_1 + 0.393650793650818*G0_0_0_5_1_1_1_0_0 + 0.393650793650818*G0_0_0_5_1_1_2_0_1 - 0.393650793650818*G0_0_0_5_1_1_3_1_0 - 0.393650793650818*G0_0_0_5_1_1_3_1_1 + 0.393650793650818*G0_0_0_5_1_1_4_1_0 + 0.393650793650818*G0_0_0_5_1_1_5_1_1 + 0.196825396825405*G0_0_1_0_0_0_0_0_0 + 0.196825396825405*G0_0_1_0_0_0_0_0_1 - 0.196825396825405*G0_0_1_0_0_0_1_0_0 - 0.196825396825405*G0_0_1_0_0_0_2_0_1 + 0.196825396825405*G0_0_1_0_0_0_3_1_0 + 0.196825396825405*G0_0_1_0_0_0_3_1_1 - 0.196825396825405*G0_0_1_0_0_0_4_1_0 - 0.196825396825405*G0_0_1_0_0_0_5_1_1 + 0.196825396825405*G0_0_1_0_0_1_0_0_0 + 0.196825396825405*G0_0_1_0_0_1_0_0_1 - 0.196825396825405*G0_0_1_0_0_1_1_0_0 - 0.196825396825405*G0_0_1_0_0_1_2_0_1 + 0.196825396825405*G0_0_1_0_0_1_3_1_0 + 0.196825396825405*G0_0_1_0_0_1_3_1_1 - 0.196825396825405*G0_0_1_0_0_1_4_1_0 - 0.196825396825405*G0_0_1_0_0_1_5_1_1 - 0.196825396825405*G0_0_1_1_0_0_0_0_0 - 0.196825396825405*G0_0_1_1_0_0_0_0_1 + 0.196825396825405*G0_0_1_1_0_0_1_0_0 + 0.196825396825405*G0_0_1_1_0_0_2_0_1 - 0.196825396825405*G0_0_1_1_0_0_3_1_0 - 0.196825396825405*G0_0_1_1_0_0_3_1_1 + 0.196825396825405*G0_0_1_1_0_0_4_1_0 + 0.196825396825405*G0_0_1_1_0_0_5_1_1 - 0.196825396825405*G0_0_1_2_0_1_0_0_0 - 0.196825396825405*G0_0_1_2_0_1_0_0_1 + 0.196825396825405*G0_0_1_2_0_1_1_0_0 + 0.196825396825405*G0_0_1_2_0_1_2_0_1 - 0.196825396825405*G0_0_1_2_0_1_3_1_0 - 0.196825396825405*G0_0_1_2_0_1_3_1_1 + 0.196825396825405*G0_0_1_2_0_1_4_1_0 + 0.196825396825405*G0_0_1_2_0_1_5_1_1 + 0.196825396825405*G0_0_1_3_1_0_0_0_0 + 0.196825396825405*G0_0_1_3_1_0_0_0_1 - 0.196825396825405*G0_0_1_3_1_0_1_0_0 - 0.196825396825405*G0_0_1_3_1_0_2_0_1 + 0.196825396825405*G0_0_1_3_1_0_3_1_0 + 0.196825396825405*G0_0_1_3_1_0_3_1_1 - 0.196825396825405*G0_0_1_3_1_0_4_1_0 - 0.196825396825405*G0_0_1_3_1_0_5_1_1 + 0.196825396825405*G0_0_1_3_1_1_0_0_0 + 0.196825396825405*G0_0_1_3_1_1_0_0_1 - 0.196825396825405*G0_0_1_3_1_1_1_0_0 - 0.196825396825405*G0_0_1_3_1_1_2_0_1 + 0.196825396825405*G0_0_1_3_1_1_3_1_0 + 0.196825396825405*G0_0_1_3_1_1_3_1_1 - 0.196825396825405*G0_0_1_3_1_1_4_1_0 - 0.196825396825405*G0_0_1_3_1_1_5_1_1 - 0.196825396825405*G0_0_1_4_1_0_0_0_0 - 0.196825396825405*G0_0_1_4_1_0_0_0_1 + 0.196825396825405*G0_0_1_4_1_0_1_0_0 + 0.196825396825405*G0_0_1_4_1_0_2_0_1 - 0.196825396825405*G0_0_1_4_1_0_3_1_0 - 0.196825396825405*G0_0_1_4_1_0_3_1_1 + 0.196825396825405*G0_0_1_4_1_0_4_1_0 + 0.196825396825405*G0_0_1_4_1_0_5_1_1 - 0.196825396825405*G0_0_1_5_1_1_0_0_0 - 0.196825396825405*G0_0_1_5_1_1_0_0_1 + 0.196825396825405*G0_0_1_5_1_1_1_0_0 + 0.196825396825405*G0_0_1_5_1_1_2_0_1 - 0.196825396825405*G0_0_1_5_1_1_3_1_0 - 0.196825396825405*G0_0_1_5_1_1_3_1_1 + 0.196825396825405*G0_0_1_5_1_1_4_1_0 + 0.196825396825405*G0_0_1_5_1_1_5_1_1 + 0.196825396825417*G0_1_0_0_0_0_0_0_0 + 0.196825396825417*G0_1_0_0_0_0_0_0_1 - 0.196825396825417*G0_1_0_0_0_0_1_0_0 - 0.196825396825417*G0_1_0_0_0_0_2_0_1 + 0.196825396825417*G0_1_0_0_0_0_3_1_0 + 0.196825396825417*G0_1_0_0_0_0_3_1_1 - 0.196825396825417*G0_1_0_0_0_0_4_1_0 - 0.196825396825417*G0_1_0_0_0_0_5_1_1 + 0.196825396825417*G0_1_0_0_0_1_0_0_0 + 0.196825396825417*G0_1_0_0_0_1_0_0_1 - 0.196825396825417*G0_1_0_0_0_1_1_0_0 - 0.196825396825417*G0_1_0_0_0_1_2_0_1 + 0.196825396825417*G0_1_0_0_0_1_3_1_0 + 0.196825396825417*G0_1_0_0_0_1_3_1_1 - 0.196825396825417*G0_1_0_0_0_1_4_1_0 - 0.196825396825417*G0_1_0_0_0_1_5_1_1 - 0.196825396825417*G0_1_0_1_0_0_0_0_0 - 0.196825396825417*G0_1_0_1_0_0_0_0_1 + 0.196825396825417*G0_1_0_1_0_0_1_0_0 + 0.196825396825417*G0_1_0_1_0_0_2_0_1 - 0.196825396825417*G0_1_0_1_0_0_3_1_0 - 0.196825396825417*G0_1_0_1_0_0_3_1_1 + 0.196825396825417*G0_1_0_1_0_0_4_1_0 + 0.196825396825417*G0_1_0_1_0_0_5_1_1 - 0.196825396825417*G0_1_0_2_0_1_0_0_0 - 0.196825396825417*G0_1_0_2_0_1_0_0_1 + 0.196825396825417*G0_1_0_2_0_1_1_0_0 + 0.196825396825417*G0_1_0_2_0_1_2_0_1 - 0.196825396825417*G0_1_0_2_0_1_3_1_0 - 0.196825396825417*G0_1_0_2_0_1_3_1_1 + 0.196825396825417*G0_1_0_2_0_1_4_1_0 + 0.196825396825417*G0_1_0_2_0_1_5_1_1 + 0.196825396825417*G0_1_0_3_1_0_0_0_0 + 0.196825396825417*G0_1_0_3_1_0_0_0_1 - 0.196825396825417*G0_1_0_3_1_0_1_0_0 - 0.196825396825417*G0_1_0_3_1_0_2_0_1 + 0.196825396825417*G0_1_0_3_1_0_3_1_0 + 0.196825396825417*G0_1_0_3_1_0_3_1_1 - 0.196825396825417*G0_1_0_3_1_0_4_1_0 - 0.196825396825417*G0_1_0_3_1_0_5_1_1 + 0.196825396825417*G0_1_0_3_1_1_0_0_0 + 0.196825396825417*G0_1_0_3_1_1_0_0_1 - 0.196825396825417*G0_1_0_3_1_1_1_0_0 - 0.196825396825417*G0_1_0_3_1_1_2_0_1 + 0.196825396825417*G0_1_0_3_1_1_3_1_0 + 0.196825396825417*G0_1_0_3_1_1_3_1_1 - 0.196825396825417*G0_1_0_3_1_1_4_1_0 - 0.196825396825417*G0_1_0_3_1_1_5_1_1 - 0.196825396825417*G0_1_0_4_1_0_0_0_0 - 0.196825396825417*G0_1_0_4_1_0_0_0_1 + 0.196825396825417*G0_1_0_4_1_0_1_0_0 + 0.196825396825417*G0_1_0_4_1_0_2_0_1 - 0.196825396825417*G0_1_0_4_1_0_3_1_0 - 0.196825396825417*G0_1_0_4_1_0_3_1_1 + 0.196825396825417*G0_1_0_4_1_0_4_1_0 + 0.196825396825417*G0_1_0_4_1_0_5_1_1 - 0.196825396825417*G0_1_0_5_1_1_0_0_0 - 0.196825396825417*G0_1_0_5_1_1_0_0_1 + 0.196825396825417*G0_1_0_5_1_1_1_0_0 + 0.196825396825417*G0_1_0_5_1_1_2_0_1 - 0.196825396825417*G0_1_0_5_1_1_3_1_0 - 0.196825396825417*G0_1_0_5_1_1_3_1_1 + 0.196825396825417*G0_1_0_5_1_1_4_1_0 + 0.196825396825417*G0_1_0_5_1_1_5_1_1 + 0.0507936507936571*G0_1_1_0_0_0_0_0_0 + 0.0507936507936571*G0_1_1_0_0_0_0_0_1 - 0.0507936507936571*G0_1_1_0_0_0_1_0_0 - 0.0507936507936571*G0_1_1_0_0_0_2_0_1 + 0.0507936507936571*G0_1_1_0_0_0_3_1_0 + 0.0507936507936571*G0_1_1_0_0_0_3_1_1 - 0.0507936507936571*G0_1_1_0_0_0_4_1_0 - 0.0507936507936571*G0_1_1_0_0_0_5_1_1 + 0.0507936507936571*G0_1_1_0_0_1_0_0_0 + 0.0507936507936571*G0_1_1_0_0_1_0_0_1 - 0.0507936507936571*G0_1_1_0_0_1_1_0_0 - 0.0507936507936571*G0_1_1_0_0_1_2_0_1 + 0.0507936507936571*G0_1_1_0_0_1_3_1_0 + 0.0507936507936571*G0_1_1_0_0_1_3_1_1 - 0.0507936507936571*G0_1_1_0_0_1_4_1_0 - 0.0507936507936571*G0_1_1_0_0_1_5_1_1 - 0.0507936507936571*G0_1_1_1_0_0_0_0_0 - 0.0507936507936571*G0_1_1_1_0_0_0_0_1 + 0.0507936507936571*G0_1_1_1_0_0_1_0_0 + 0.0507936507936571*G0_1_1_1_0_0_2_0_1 - 0.0507936507936571*G0_1_1_1_0_0_3_1_0 - 0.0507936507936571*G0_1_1_1_0_0_3_1_1 + 0.0507936507936571*G0_1_1_1_0_0_4_1_0 + 0.0507936507936571*G0_1_1_1_0_0_5_1_1 - 0.0507936507936571*G0_1_1_2_0_1_0_0_0 - 0.0507936507936571*G0_1_1_2_0_1_0_0_1 + 0.0507936507936571*G0_1_1_2_0_1_1_0_0 + 0.0507936507936571*G0_1_1_2_0_1_2_0_1 - 0.0507936507936571*G0_1_1_2_0_1_3_1_0 - 0.0507936507936571*G0_1_1_2_0_1_3_1_1 + 0.0507936507936571*G0_1_1_2_0_1_4_1_0 + 0.0507936507936571*G0_1_1_2_0_1_5_1_1 + 0.0507936507936571*G0_1_1_3_1_0_0_0_0 + 0.0507936507936571*G0_1_1_3_1_0_0_0_1 - 0.0507936507936571*G0_1_1_3_1_0_1_0_0 - 0.0507936507936571*G0_1_1_3_1_0_2_0_1 + 0.0507936507936571*G0_1_1_3_1_0_3_1_0 + 0.0507936507936571*G0_1_1_3_1_0_3_1_1 - 0.0507936507936571*G0_1_1_3_1_0_4_1_0 - 0.0507936507936571*G0_1_1_3_1_0_5_1_1 + 0.0507936507936571*G0_1_1_3_1_1_0_0_0 + 0.0507936507936571*G0_1_1_3_1_1_0_0_1 - 0.0507936507936571*G0_1_1_3_1_1_1_0_0 - 0.0507936507936571*G0_1_1_3_1_1_2_0_1 + 0.0507936507936571*G0_1_1_3_1_1_3_1_0 + 0.0507936507936571*G0_1_1_3_1_1_3_1_1 - 0.0507936507936571*G0_1_1_3_1_1_4_1_0 - 0.0507936507936571*G0_1_1_3_1_1_5_1_1 - 0.0507936507936571*G0_1_1_4_1_0_0_0_0 - 0.0507936507936571*G0_1_1_4_1_0_0_0_1 + 0.0507936507936571*G0_1_1_4_1_0_1_0_0 + 0.0507936507936571*G0_1_1_4_1_0_2_0_1 - 0.0507936507936571*G0_1_1_4_1_0_3_1_0 - 0.0507936507936571*G0_1_1_4_1_0_3_1_1 + 0.0507936507936571*G0_1_1_4_1_0_4_1_0 + 0.0507936507936571*G0_1_1_4_1_0_5_1_1 - 0.0507936507936571*G0_1_1_5_1_1_0_0_0 - 0.0507936507936571*G0_1_1_5_1_1_0_0_1 + 0.0507936507936571*G0_1_1_5_1_1_1_0_0 + 0.0507936507936571*G0_1_1_5_1_1_2_0_1 - 0.0507936507936571*G0_1_1_5_1_1_3_1_0 - 0.0507936507936571*G0_1_1_5_1_1_3_1_1 + 0.0507936507936571*G0_1_1_5_1_1_4_1_0 + 0.0507936507936571*G0_1_1_5_1_1_5_1_1; + A[607] = 0.0; + A[716] = 0.101587301587301*G0_0_1_0_0_0_0_0_0 + 0.101587301587301*G0_0_1_0_0_0_0_0_1 - 0.101587301587301*G0_0_1_0_0_0_1_0_0 - 0.101587301587301*G0_0_1_0_0_0_2_0_1 + 0.101587301587301*G0_0_1_0_0_0_3_1_0 + 0.101587301587301*G0_0_1_0_0_0_3_1_1 - 0.101587301587301*G0_0_1_0_0_0_4_1_0 - 0.101587301587301*G0_0_1_0_0_0_5_1_1 + 0.101587301587301*G0_0_1_0_0_1_0_0_0 + 0.101587301587301*G0_0_1_0_0_1_0_0_1 - 0.101587301587301*G0_0_1_0_0_1_1_0_0 - 0.101587301587301*G0_0_1_0_0_1_2_0_1 + 0.101587301587301*G0_0_1_0_0_1_3_1_0 + 0.101587301587301*G0_0_1_0_0_1_3_1_1 - 0.101587301587301*G0_0_1_0_0_1_4_1_0 - 0.101587301587301*G0_0_1_0_0_1_5_1_1 - 0.101587301587301*G0_0_1_1_0_0_0_0_0 - 0.101587301587301*G0_0_1_1_0_0_0_0_1 + 0.101587301587301*G0_0_1_1_0_0_1_0_0 + 0.101587301587301*G0_0_1_1_0_0_2_0_1 - 0.101587301587301*G0_0_1_1_0_0_3_1_0 - 0.101587301587301*G0_0_1_1_0_0_3_1_1 + 0.101587301587301*G0_0_1_1_0_0_4_1_0 + 0.101587301587301*G0_0_1_1_0_0_5_1_1 - 0.101587301587301*G0_0_1_2_0_1_0_0_0 - 0.101587301587301*G0_0_1_2_0_1_0_0_1 + 0.101587301587301*G0_0_1_2_0_1_1_0_0 + 0.101587301587301*G0_0_1_2_0_1_2_0_1 - 0.101587301587301*G0_0_1_2_0_1_3_1_0 - 0.101587301587301*G0_0_1_2_0_1_3_1_1 + 0.101587301587301*G0_0_1_2_0_1_4_1_0 + 0.101587301587301*G0_0_1_2_0_1_5_1_1 + 0.101587301587301*G0_0_1_3_1_0_0_0_0 + 0.101587301587301*G0_0_1_3_1_0_0_0_1 - 0.101587301587301*G0_0_1_3_1_0_1_0_0 - 0.101587301587301*G0_0_1_3_1_0_2_0_1 + 0.101587301587301*G0_0_1_3_1_0_3_1_0 + 0.101587301587301*G0_0_1_3_1_0_3_1_1 - 0.101587301587301*G0_0_1_3_1_0_4_1_0 - 0.101587301587301*G0_0_1_3_1_0_5_1_1 + 0.101587301587301*G0_0_1_3_1_1_0_0_0 + 0.101587301587301*G0_0_1_3_1_1_0_0_1 - 0.101587301587301*G0_0_1_3_1_1_1_0_0 - 0.101587301587301*G0_0_1_3_1_1_2_0_1 + 0.101587301587301*G0_0_1_3_1_1_3_1_0 + 0.101587301587301*G0_0_1_3_1_1_3_1_1 - 0.101587301587301*G0_0_1_3_1_1_4_1_0 - 0.101587301587301*G0_0_1_3_1_1_5_1_1 - 0.101587301587301*G0_0_1_4_1_0_0_0_0 - 0.101587301587301*G0_0_1_4_1_0_0_0_1 + 0.101587301587301*G0_0_1_4_1_0_1_0_0 + 0.101587301587301*G0_0_1_4_1_0_2_0_1 - 0.101587301587301*G0_0_1_4_1_0_3_1_0 - 0.101587301587301*G0_0_1_4_1_0_3_1_1 + 0.101587301587301*G0_0_1_4_1_0_4_1_0 + 0.101587301587301*G0_0_1_4_1_0_5_1_1 - 0.101587301587301*G0_0_1_5_1_1_0_0_0 - 0.101587301587301*G0_0_1_5_1_1_0_0_1 + 0.101587301587301*G0_0_1_5_1_1_1_0_0 + 0.101587301587301*G0_0_1_5_1_1_2_0_1 - 0.101587301587301*G0_0_1_5_1_1_3_1_0 - 0.101587301587301*G0_0_1_5_1_1_3_1_1 + 0.101587301587301*G0_0_1_5_1_1_4_1_0 + 0.101587301587301*G0_0_1_5_1_1_5_1_1 + 0.101587301587306*G0_1_0_0_0_0_0_0_0 + 0.101587301587306*G0_1_0_0_0_0_0_0_1 - 0.101587301587306*G0_1_0_0_0_0_1_0_0 - 0.101587301587306*G0_1_0_0_0_0_2_0_1 + 0.101587301587306*G0_1_0_0_0_0_3_1_0 + 0.101587301587306*G0_1_0_0_0_0_3_1_1 - 0.101587301587306*G0_1_0_0_0_0_4_1_0 - 0.101587301587306*G0_1_0_0_0_0_5_1_1 + 0.101587301587306*G0_1_0_0_0_1_0_0_0 + 0.101587301587306*G0_1_0_0_0_1_0_0_1 - 0.101587301587306*G0_1_0_0_0_1_1_0_0 - 0.101587301587306*G0_1_0_0_0_1_2_0_1 + 0.101587301587306*G0_1_0_0_0_1_3_1_0 + 0.101587301587306*G0_1_0_0_0_1_3_1_1 - 0.101587301587306*G0_1_0_0_0_1_4_1_0 - 0.101587301587306*G0_1_0_0_0_1_5_1_1 - 0.101587301587306*G0_1_0_1_0_0_0_0_0 - 0.101587301587306*G0_1_0_1_0_0_0_0_1 + 0.101587301587306*G0_1_0_1_0_0_1_0_0 + 0.101587301587306*G0_1_0_1_0_0_2_0_1 - 0.101587301587306*G0_1_0_1_0_0_3_1_0 - 0.101587301587306*G0_1_0_1_0_0_3_1_1 + 0.101587301587306*G0_1_0_1_0_0_4_1_0 + 0.101587301587306*G0_1_0_1_0_0_5_1_1 - 0.101587301587306*G0_1_0_2_0_1_0_0_0 - 0.101587301587306*G0_1_0_2_0_1_0_0_1 + 0.101587301587306*G0_1_0_2_0_1_1_0_0 + 0.101587301587306*G0_1_0_2_0_1_2_0_1 - 0.101587301587306*G0_1_0_2_0_1_3_1_0 - 0.101587301587306*G0_1_0_2_0_1_3_1_1 + 0.101587301587306*G0_1_0_2_0_1_4_1_0 + 0.101587301587306*G0_1_0_2_0_1_5_1_1 + 0.101587301587306*G0_1_0_3_1_0_0_0_0 + 0.101587301587306*G0_1_0_3_1_0_0_0_1 - 0.101587301587306*G0_1_0_3_1_0_1_0_0 - 0.101587301587306*G0_1_0_3_1_0_2_0_1 + 0.101587301587306*G0_1_0_3_1_0_3_1_0 + 0.101587301587306*G0_1_0_3_1_0_3_1_1 - 0.101587301587306*G0_1_0_3_1_0_4_1_0 - 0.101587301587306*G0_1_0_3_1_0_5_1_1 + 0.101587301587306*G0_1_0_3_1_1_0_0_0 + 0.101587301587306*G0_1_0_3_1_1_0_0_1 - 0.101587301587306*G0_1_0_3_1_1_1_0_0 - 0.101587301587306*G0_1_0_3_1_1_2_0_1 + 0.101587301587306*G0_1_0_3_1_1_3_1_0 + 0.101587301587306*G0_1_0_3_1_1_3_1_1 - 0.101587301587306*G0_1_0_3_1_1_4_1_0 - 0.101587301587306*G0_1_0_3_1_1_5_1_1 - 0.101587301587306*G0_1_0_4_1_0_0_0_0 - 0.101587301587306*G0_1_0_4_1_0_0_0_1 + 0.101587301587306*G0_1_0_4_1_0_1_0_0 + 0.101587301587306*G0_1_0_4_1_0_2_0_1 - 0.101587301587306*G0_1_0_4_1_0_3_1_0 - 0.101587301587306*G0_1_0_4_1_0_3_1_1 + 0.101587301587306*G0_1_0_4_1_0_4_1_0 + 0.101587301587306*G0_1_0_4_1_0_5_1_1 - 0.101587301587306*G0_1_0_5_1_1_0_0_0 - 0.101587301587306*G0_1_0_5_1_1_0_0_1 + 0.101587301587306*G0_1_0_5_1_1_1_0_0 + 0.101587301587306*G0_1_0_5_1_1_2_0_1 - 0.101587301587306*G0_1_0_5_1_1_3_1_0 - 0.101587301587306*G0_1_0_5_1_1_3_1_1 + 0.101587301587306*G0_1_0_5_1_1_4_1_0 + 0.101587301587306*G0_1_0_5_1_1_5_1_1; + A[636] = 0.0; + A[270] = A[530] - 0.651851851851859*G0_0_0_0_0_0_0_0_0 - 0.651851851851859*G0_0_0_0_0_0_0_0_1 + 0.651851851851859*G0_0_0_0_0_0_1_0_0 + 0.651851851851859*G0_0_0_0_0_0_2_0_1 - 0.651851851851859*G0_0_0_0_0_0_3_1_0 - 0.651851851851859*G0_0_0_0_0_0_3_1_1 + 0.651851851851859*G0_0_0_0_0_0_4_1_0 + 0.651851851851859*G0_0_0_0_0_0_5_1_1 - 0.651851851851859*G0_0_0_0_0_1_0_0_0 - 0.651851851851859*G0_0_0_0_0_1_0_0_1 + 0.651851851851859*G0_0_0_0_0_1_1_0_0 + 0.651851851851859*G0_0_0_0_0_1_2_0_1 - 0.651851851851859*G0_0_0_0_0_1_3_1_0 - 0.651851851851859*G0_0_0_0_0_1_3_1_1 + 0.651851851851859*G0_0_0_0_0_1_4_1_0 + 0.651851851851859*G0_0_0_0_0_1_5_1_1 + 0.651851851851859*G0_0_0_1_0_0_0_0_0 + 0.651851851851859*G0_0_0_1_0_0_0_0_1 - 0.651851851851859*G0_0_0_1_0_0_1_0_0 - 0.651851851851859*G0_0_0_1_0_0_2_0_1 + 0.651851851851859*G0_0_0_1_0_0_3_1_0 + 0.651851851851859*G0_0_0_1_0_0_3_1_1 - 0.651851851851859*G0_0_0_1_0_0_4_1_0 - 0.651851851851859*G0_0_0_1_0_0_5_1_1 + 0.651851851851859*G0_0_0_2_0_1_0_0_0 + 0.651851851851859*G0_0_0_2_0_1_0_0_1 - 0.651851851851859*G0_0_0_2_0_1_1_0_0 - 0.651851851851859*G0_0_0_2_0_1_2_0_1 + 0.651851851851859*G0_0_0_2_0_1_3_1_0 + 0.651851851851859*G0_0_0_2_0_1_3_1_1 - 0.651851851851859*G0_0_0_2_0_1_4_1_0 - 0.651851851851859*G0_0_0_2_0_1_5_1_1 - 0.651851851851859*G0_0_0_3_1_0_0_0_0 - 0.651851851851859*G0_0_0_3_1_0_0_0_1 + 0.651851851851859*G0_0_0_3_1_0_1_0_0 + 0.651851851851859*G0_0_0_3_1_0_2_0_1 - 0.651851851851859*G0_0_0_3_1_0_3_1_0 - 0.651851851851859*G0_0_0_3_1_0_3_1_1 + 0.651851851851859*G0_0_0_3_1_0_4_1_0 + 0.651851851851859*G0_0_0_3_1_0_5_1_1 - 0.651851851851859*G0_0_0_3_1_1_0_0_0 - 0.651851851851859*G0_0_0_3_1_1_0_0_1 + 0.651851851851859*G0_0_0_3_1_1_1_0_0 + 0.651851851851859*G0_0_0_3_1_1_2_0_1 - 0.651851851851859*G0_0_0_3_1_1_3_1_0 - 0.651851851851859*G0_0_0_3_1_1_3_1_1 + 0.651851851851859*G0_0_0_3_1_1_4_1_0 + 0.651851851851859*G0_0_0_3_1_1_5_1_1 + 0.651851851851859*G0_0_0_4_1_0_0_0_0 + 0.651851851851859*G0_0_0_4_1_0_0_0_1 - 0.651851851851859*G0_0_0_4_1_0_1_0_0 - 0.651851851851859*G0_0_0_4_1_0_2_0_1 + 0.651851851851859*G0_0_0_4_1_0_3_1_0 + 0.651851851851859*G0_0_0_4_1_0_3_1_1 - 0.651851851851859*G0_0_0_4_1_0_4_1_0 - 0.651851851851859*G0_0_0_4_1_0_5_1_1 + 0.651851851851859*G0_0_0_5_1_1_0_0_0 + 0.651851851851859*G0_0_0_5_1_1_0_0_1 - 0.651851851851859*G0_0_0_5_1_1_1_0_0 - 0.651851851851859*G0_0_0_5_1_1_2_0_1 + 0.651851851851859*G0_0_0_5_1_1_3_1_0 + 0.651851851851859*G0_0_0_5_1_1_3_1_1 - 0.651851851851859*G0_0_0_5_1_1_4_1_0 - 0.651851851851859*G0_0_0_5_1_1_5_1_1 - 0.651851851851859*G0_0_1_0_0_0_0_0_0 - 0.651851851851859*G0_0_1_0_0_0_0_0_1 + 0.651851851851859*G0_0_1_0_0_0_1_0_0 + 0.651851851851859*G0_0_1_0_0_0_2_0_1 - 0.651851851851859*G0_0_1_0_0_0_3_1_0 - 0.651851851851859*G0_0_1_0_0_0_3_1_1 + 0.651851851851859*G0_0_1_0_0_0_4_1_0 + 0.651851851851859*G0_0_1_0_0_0_5_1_1 - 0.651851851851859*G0_0_1_0_0_1_0_0_0 - 0.651851851851859*G0_0_1_0_0_1_0_0_1 + 0.651851851851859*G0_0_1_0_0_1_1_0_0 + 0.651851851851859*G0_0_1_0_0_1_2_0_1 - 0.651851851851859*G0_0_1_0_0_1_3_1_0 - 0.651851851851859*G0_0_1_0_0_1_3_1_1 + 0.651851851851859*G0_0_1_0_0_1_4_1_0 + 0.651851851851859*G0_0_1_0_0_1_5_1_1 + 0.651851851851859*G0_0_1_1_0_0_0_0_0 + 0.651851851851859*G0_0_1_1_0_0_0_0_1 - 0.651851851851859*G0_0_1_1_0_0_1_0_0 - 0.651851851851859*G0_0_1_1_0_0_2_0_1 + 0.651851851851859*G0_0_1_1_0_0_3_1_0 + 0.651851851851859*G0_0_1_1_0_0_3_1_1 - 0.651851851851859*G0_0_1_1_0_0_4_1_0 - 0.651851851851859*G0_0_1_1_0_0_5_1_1 + 0.651851851851859*G0_0_1_2_0_1_0_0_0 + 0.651851851851859*G0_0_1_2_0_1_0_0_1 - 0.651851851851859*G0_0_1_2_0_1_1_0_0 - 0.651851851851859*G0_0_1_2_0_1_2_0_1 + 0.651851851851859*G0_0_1_2_0_1_3_1_0 + 0.651851851851859*G0_0_1_2_0_1_3_1_1 - 0.651851851851859*G0_0_1_2_0_1_4_1_0 - 0.651851851851859*G0_0_1_2_0_1_5_1_1 - 0.651851851851859*G0_0_1_3_1_0_0_0_0 - 0.651851851851859*G0_0_1_3_1_0_0_0_1 + 0.651851851851859*G0_0_1_3_1_0_1_0_0 + 0.651851851851859*G0_0_1_3_1_0_2_0_1 - 0.651851851851859*G0_0_1_3_1_0_3_1_0 - 0.651851851851859*G0_0_1_3_1_0_3_1_1 + 0.651851851851859*G0_0_1_3_1_0_4_1_0 + 0.651851851851859*G0_0_1_3_1_0_5_1_1 - 0.651851851851859*G0_0_1_3_1_1_0_0_0 - 0.651851851851859*G0_0_1_3_1_1_0_0_1 + 0.651851851851859*G0_0_1_3_1_1_1_0_0 + 0.651851851851859*G0_0_1_3_1_1_2_0_1 - 0.651851851851859*G0_0_1_3_1_1_3_1_0 - 0.651851851851859*G0_0_1_3_1_1_3_1_1 + 0.651851851851859*G0_0_1_3_1_1_4_1_0 + 0.651851851851859*G0_0_1_3_1_1_5_1_1 + 0.651851851851859*G0_0_1_4_1_0_0_0_0 + 0.651851851851859*G0_0_1_4_1_0_0_0_1 - 0.651851851851859*G0_0_1_4_1_0_1_0_0 - 0.651851851851859*G0_0_1_4_1_0_2_0_1 + 0.651851851851859*G0_0_1_4_1_0_3_1_0 + 0.651851851851859*G0_0_1_4_1_0_3_1_1 - 0.651851851851859*G0_0_1_4_1_0_4_1_0 - 0.651851851851859*G0_0_1_4_1_0_5_1_1 + 0.651851851851859*G0_0_1_5_1_1_0_0_0 + 0.651851851851859*G0_0_1_5_1_1_0_0_1 - 0.651851851851859*G0_0_1_5_1_1_1_0_0 - 0.651851851851859*G0_0_1_5_1_1_2_0_1 + 0.651851851851859*G0_0_1_5_1_1_3_1_0 + 0.651851851851859*G0_0_1_5_1_1_3_1_1 - 0.651851851851859*G0_0_1_5_1_1_4_1_0 - 0.651851851851859*G0_0_1_5_1_1_5_1_1 - 0.65185185185186*G0_1_0_0_0_0_0_0_0 - 0.65185185185186*G0_1_0_0_0_0_0_0_1 + 0.65185185185186*G0_1_0_0_0_0_1_0_0 + 0.65185185185186*G0_1_0_0_0_0_2_0_1 - 0.65185185185186*G0_1_0_0_0_0_3_1_0 - 0.65185185185186*G0_1_0_0_0_0_3_1_1 + 0.65185185185186*G0_1_0_0_0_0_4_1_0 + 0.65185185185186*G0_1_0_0_0_0_5_1_1 - 0.65185185185186*G0_1_0_0_0_1_0_0_0 - 0.65185185185186*G0_1_0_0_0_1_0_0_1 + 0.65185185185186*G0_1_0_0_0_1_1_0_0 + 0.65185185185186*G0_1_0_0_0_1_2_0_1 - 0.65185185185186*G0_1_0_0_0_1_3_1_0 - 0.65185185185186*G0_1_0_0_0_1_3_1_1 + 0.65185185185186*G0_1_0_0_0_1_4_1_0 + 0.65185185185186*G0_1_0_0_0_1_5_1_1 + 0.65185185185186*G0_1_0_1_0_0_0_0_0 + 0.65185185185186*G0_1_0_1_0_0_0_0_1 - 0.65185185185186*G0_1_0_1_0_0_1_0_0 - 0.65185185185186*G0_1_0_1_0_0_2_0_1 + 0.65185185185186*G0_1_0_1_0_0_3_1_0 + 0.65185185185186*G0_1_0_1_0_0_3_1_1 - 0.65185185185186*G0_1_0_1_0_0_4_1_0 - 0.65185185185186*G0_1_0_1_0_0_5_1_1 + 0.65185185185186*G0_1_0_2_0_1_0_0_0 + 0.65185185185186*G0_1_0_2_0_1_0_0_1 - 0.65185185185186*G0_1_0_2_0_1_1_0_0 - 0.65185185185186*G0_1_0_2_0_1_2_0_1 + 0.65185185185186*G0_1_0_2_0_1_3_1_0 + 0.65185185185186*G0_1_0_2_0_1_3_1_1 - 0.65185185185186*G0_1_0_2_0_1_4_1_0 - 0.65185185185186*G0_1_0_2_0_1_5_1_1 - 0.65185185185186*G0_1_0_3_1_0_0_0_0 - 0.65185185185186*G0_1_0_3_1_0_0_0_1 + 0.65185185185186*G0_1_0_3_1_0_1_0_0 + 0.65185185185186*G0_1_0_3_1_0_2_0_1 - 0.65185185185186*G0_1_0_3_1_0_3_1_0 - 0.65185185185186*G0_1_0_3_1_0_3_1_1 + 0.65185185185186*G0_1_0_3_1_0_4_1_0 + 0.65185185185186*G0_1_0_3_1_0_5_1_1 - 0.65185185185186*G0_1_0_3_1_1_0_0_0 - 0.65185185185186*G0_1_0_3_1_1_0_0_1 + 0.65185185185186*G0_1_0_3_1_1_1_0_0 + 0.65185185185186*G0_1_0_3_1_1_2_0_1 - 0.65185185185186*G0_1_0_3_1_1_3_1_0 - 0.65185185185186*G0_1_0_3_1_1_3_1_1 + 0.65185185185186*G0_1_0_3_1_1_4_1_0 + 0.65185185185186*G0_1_0_3_1_1_5_1_1 + 0.65185185185186*G0_1_0_4_1_0_0_0_0 + 0.65185185185186*G0_1_0_4_1_0_0_0_1 - 0.65185185185186*G0_1_0_4_1_0_1_0_0 - 0.65185185185186*G0_1_0_4_1_0_2_0_1 + 0.65185185185186*G0_1_0_4_1_0_3_1_0 + 0.65185185185186*G0_1_0_4_1_0_3_1_1 - 0.65185185185186*G0_1_0_4_1_0_4_1_0 - 0.65185185185186*G0_1_0_4_1_0_5_1_1 + 0.65185185185186*G0_1_0_5_1_1_0_0_0 + 0.65185185185186*G0_1_0_5_1_1_0_0_1 - 0.65185185185186*G0_1_0_5_1_1_1_0_0 - 0.65185185185186*G0_1_0_5_1_1_2_0_1 + 0.65185185185186*G0_1_0_5_1_1_3_1_0 + 0.65185185185186*G0_1_0_5_1_1_3_1_1 - 0.65185185185186*G0_1_0_5_1_1_4_1_0 - 0.65185185185186*G0_1_0_5_1_1_5_1_1; + A[307] = A[679] - 0.342857142857164*G0_0_0_0_0_0_0_0_0 - 0.342857142857164*G0_0_0_0_0_0_0_0_1 + 0.342857142857164*G0_0_0_0_0_0_1_0_0 + 0.342857142857164*G0_0_0_0_0_0_2_0_1 - 0.342857142857164*G0_0_0_0_0_0_3_1_0 - 0.342857142857164*G0_0_0_0_0_0_3_1_1 + 0.342857142857164*G0_0_0_0_0_0_4_1_0 + 0.342857142857164*G0_0_0_0_0_0_5_1_1 - 0.342857142857164*G0_0_0_0_0_1_0_0_0 - 0.342857142857164*G0_0_0_0_0_1_0_0_1 + 0.342857142857164*G0_0_0_0_0_1_1_0_0 + 0.342857142857164*G0_0_0_0_0_1_2_0_1 - 0.342857142857164*G0_0_0_0_0_1_3_1_0 - 0.342857142857164*G0_0_0_0_0_1_3_1_1 + 0.342857142857164*G0_0_0_0_0_1_4_1_0 + 0.342857142857164*G0_0_0_0_0_1_5_1_1 + 0.342857142857164*G0_0_0_1_0_0_0_0_0 + 0.342857142857164*G0_0_0_1_0_0_0_0_1 - 0.342857142857164*G0_0_0_1_0_0_1_0_0 - 0.342857142857164*G0_0_0_1_0_0_2_0_1 + 0.342857142857164*G0_0_0_1_0_0_3_1_0 + 0.342857142857164*G0_0_0_1_0_0_3_1_1 - 0.342857142857164*G0_0_0_1_0_0_4_1_0 - 0.342857142857164*G0_0_0_1_0_0_5_1_1 + 0.342857142857164*G0_0_0_2_0_1_0_0_0 + 0.342857142857164*G0_0_0_2_0_1_0_0_1 - 0.342857142857164*G0_0_0_2_0_1_1_0_0 - 0.342857142857164*G0_0_0_2_0_1_2_0_1 + 0.342857142857164*G0_0_0_2_0_1_3_1_0 + 0.342857142857164*G0_0_0_2_0_1_3_1_1 - 0.342857142857164*G0_0_0_2_0_1_4_1_0 - 0.342857142857164*G0_0_0_2_0_1_5_1_1 - 0.342857142857164*G0_0_0_3_1_0_0_0_0 - 0.342857142857164*G0_0_0_3_1_0_0_0_1 + 0.342857142857164*G0_0_0_3_1_0_1_0_0 + 0.342857142857164*G0_0_0_3_1_0_2_0_1 - 0.342857142857164*G0_0_0_3_1_0_3_1_0 - 0.342857142857164*G0_0_0_3_1_0_3_1_1 + 0.342857142857164*G0_0_0_3_1_0_4_1_0 + 0.342857142857164*G0_0_0_3_1_0_5_1_1 - 0.342857142857164*G0_0_0_3_1_1_0_0_0 - 0.342857142857164*G0_0_0_3_1_1_0_0_1 + 0.342857142857164*G0_0_0_3_1_1_1_0_0 + 0.342857142857164*G0_0_0_3_1_1_2_0_1 - 0.342857142857164*G0_0_0_3_1_1_3_1_0 - 0.342857142857164*G0_0_0_3_1_1_3_1_1 + 0.342857142857164*G0_0_0_3_1_1_4_1_0 + 0.342857142857164*G0_0_0_3_1_1_5_1_1 + 0.342857142857164*G0_0_0_4_1_0_0_0_0 + 0.342857142857164*G0_0_0_4_1_0_0_0_1 - 0.342857142857164*G0_0_0_4_1_0_1_0_0 - 0.342857142857164*G0_0_0_4_1_0_2_0_1 + 0.342857142857164*G0_0_0_4_1_0_3_1_0 + 0.342857142857164*G0_0_0_4_1_0_3_1_1 - 0.342857142857164*G0_0_0_4_1_0_4_1_0 - 0.342857142857164*G0_0_0_4_1_0_5_1_1 + 0.342857142857164*G0_0_0_5_1_1_0_0_0 + 0.342857142857164*G0_0_0_5_1_1_0_0_1 - 0.342857142857164*G0_0_0_5_1_1_1_0_0 - 0.342857142857164*G0_0_0_5_1_1_2_0_1 + 0.342857142857164*G0_0_0_5_1_1_3_1_0 + 0.342857142857164*G0_0_0_5_1_1_3_1_1 - 0.342857142857164*G0_0_0_5_1_1_4_1_0 - 0.342857142857164*G0_0_0_5_1_1_5_1_1 - 0.342857142857163*G0_0_1_0_0_0_0_0_0 - 0.342857142857163*G0_0_1_0_0_0_0_0_1 + 0.342857142857163*G0_0_1_0_0_0_1_0_0 + 0.342857142857163*G0_0_1_0_0_0_2_0_1 - 0.342857142857163*G0_0_1_0_0_0_3_1_0 - 0.342857142857163*G0_0_1_0_0_0_3_1_1 + 0.342857142857163*G0_0_1_0_0_0_4_1_0 + 0.342857142857163*G0_0_1_0_0_0_5_1_1 - 0.342857142857163*G0_0_1_0_0_1_0_0_0 - 0.342857142857163*G0_0_1_0_0_1_0_0_1 + 0.342857142857163*G0_0_1_0_0_1_1_0_0 + 0.342857142857163*G0_0_1_0_0_1_2_0_1 - 0.342857142857163*G0_0_1_0_0_1_3_1_0 - 0.342857142857163*G0_0_1_0_0_1_3_1_1 + 0.342857142857163*G0_0_1_0_0_1_4_1_0 + 0.342857142857163*G0_0_1_0_0_1_5_1_1 + 0.342857142857163*G0_0_1_1_0_0_0_0_0 + 0.342857142857163*G0_0_1_1_0_0_0_0_1 - 0.342857142857163*G0_0_1_1_0_0_1_0_0 - 0.342857142857163*G0_0_1_1_0_0_2_0_1 + 0.342857142857163*G0_0_1_1_0_0_3_1_0 + 0.342857142857163*G0_0_1_1_0_0_3_1_1 - 0.342857142857163*G0_0_1_1_0_0_4_1_0 - 0.342857142857163*G0_0_1_1_0_0_5_1_1 + 0.342857142857163*G0_0_1_2_0_1_0_0_0 + 0.342857142857163*G0_0_1_2_0_1_0_0_1 - 0.342857142857163*G0_0_1_2_0_1_1_0_0 - 0.342857142857163*G0_0_1_2_0_1_2_0_1 + 0.342857142857163*G0_0_1_2_0_1_3_1_0 + 0.342857142857163*G0_0_1_2_0_1_3_1_1 - 0.342857142857163*G0_0_1_2_0_1_4_1_0 - 0.342857142857163*G0_0_1_2_0_1_5_1_1 - 0.342857142857163*G0_0_1_3_1_0_0_0_0 - 0.342857142857163*G0_0_1_3_1_0_0_0_1 + 0.342857142857163*G0_0_1_3_1_0_1_0_0 + 0.342857142857163*G0_0_1_3_1_0_2_0_1 - 0.342857142857163*G0_0_1_3_1_0_3_1_0 - 0.342857142857163*G0_0_1_3_1_0_3_1_1 + 0.342857142857163*G0_0_1_3_1_0_4_1_0 + 0.342857142857163*G0_0_1_3_1_0_5_1_1 - 0.342857142857163*G0_0_1_3_1_1_0_0_0 - 0.342857142857163*G0_0_1_3_1_1_0_0_1 + 0.342857142857163*G0_0_1_3_1_1_1_0_0 + 0.342857142857163*G0_0_1_3_1_1_2_0_1 - 0.342857142857163*G0_0_1_3_1_1_3_1_0 - 0.342857142857163*G0_0_1_3_1_1_3_1_1 + 0.342857142857163*G0_0_1_3_1_1_4_1_0 + 0.342857142857163*G0_0_1_3_1_1_5_1_1 + 0.342857142857163*G0_0_1_4_1_0_0_0_0 + 0.342857142857163*G0_0_1_4_1_0_0_0_1 - 0.342857142857163*G0_0_1_4_1_0_1_0_0 - 0.342857142857163*G0_0_1_4_1_0_2_0_1 + 0.342857142857163*G0_0_1_4_1_0_3_1_0 + 0.342857142857163*G0_0_1_4_1_0_3_1_1 - 0.342857142857163*G0_0_1_4_1_0_4_1_0 - 0.342857142857163*G0_0_1_4_1_0_5_1_1 + 0.342857142857163*G0_0_1_5_1_1_0_0_0 + 0.342857142857163*G0_0_1_5_1_1_0_0_1 - 0.342857142857163*G0_0_1_5_1_1_1_0_0 - 0.342857142857163*G0_0_1_5_1_1_2_0_1 + 0.342857142857163*G0_0_1_5_1_1_3_1_0 + 0.342857142857163*G0_0_1_5_1_1_3_1_1 - 0.342857142857163*G0_0_1_5_1_1_4_1_0 - 0.342857142857163*G0_0_1_5_1_1_5_1_1 - 0.342857142857163*G0_1_0_0_0_0_0_0_0 - 0.342857142857163*G0_1_0_0_0_0_0_0_1 + 0.342857142857163*G0_1_0_0_0_0_1_0_0 + 0.342857142857163*G0_1_0_0_0_0_2_0_1 - 0.342857142857163*G0_1_0_0_0_0_3_1_0 - 0.342857142857163*G0_1_0_0_0_0_3_1_1 + 0.342857142857163*G0_1_0_0_0_0_4_1_0 + 0.342857142857163*G0_1_0_0_0_0_5_1_1 - 0.342857142857163*G0_1_0_0_0_1_0_0_0 - 0.342857142857163*G0_1_0_0_0_1_0_0_1 + 0.342857142857163*G0_1_0_0_0_1_1_0_0 + 0.342857142857163*G0_1_0_0_0_1_2_0_1 - 0.342857142857163*G0_1_0_0_0_1_3_1_0 - 0.342857142857163*G0_1_0_0_0_1_3_1_1 + 0.342857142857163*G0_1_0_0_0_1_4_1_0 + 0.342857142857163*G0_1_0_0_0_1_5_1_1 + 0.342857142857163*G0_1_0_1_0_0_0_0_0 + 0.342857142857163*G0_1_0_1_0_0_0_0_1 - 0.342857142857163*G0_1_0_1_0_0_1_0_0 - 0.342857142857163*G0_1_0_1_0_0_2_0_1 + 0.342857142857163*G0_1_0_1_0_0_3_1_0 + 0.342857142857163*G0_1_0_1_0_0_3_1_1 - 0.342857142857163*G0_1_0_1_0_0_4_1_0 - 0.342857142857163*G0_1_0_1_0_0_5_1_1 + 0.342857142857163*G0_1_0_2_0_1_0_0_0 + 0.342857142857163*G0_1_0_2_0_1_0_0_1 - 0.342857142857163*G0_1_0_2_0_1_1_0_0 - 0.342857142857163*G0_1_0_2_0_1_2_0_1 + 0.342857142857163*G0_1_0_2_0_1_3_1_0 + 0.342857142857163*G0_1_0_2_0_1_3_1_1 - 0.342857142857163*G0_1_0_2_0_1_4_1_0 - 0.342857142857163*G0_1_0_2_0_1_5_1_1 - 0.342857142857163*G0_1_0_3_1_0_0_0_0 - 0.342857142857163*G0_1_0_3_1_0_0_0_1 + 0.342857142857163*G0_1_0_3_1_0_1_0_0 + 0.342857142857163*G0_1_0_3_1_0_2_0_1 - 0.342857142857163*G0_1_0_3_1_0_3_1_0 - 0.342857142857163*G0_1_0_3_1_0_3_1_1 + 0.342857142857163*G0_1_0_3_1_0_4_1_0 + 0.342857142857163*G0_1_0_3_1_0_5_1_1 - 0.342857142857163*G0_1_0_3_1_1_0_0_0 - 0.342857142857163*G0_1_0_3_1_1_0_0_1 + 0.342857142857163*G0_1_0_3_1_1_1_0_0 + 0.342857142857163*G0_1_0_3_1_1_2_0_1 - 0.342857142857163*G0_1_0_3_1_1_3_1_0 - 0.342857142857163*G0_1_0_3_1_1_3_1_1 + 0.342857142857163*G0_1_0_3_1_1_4_1_0 + 0.342857142857163*G0_1_0_3_1_1_5_1_1 + 0.342857142857163*G0_1_0_4_1_0_0_0_0 + 0.342857142857163*G0_1_0_4_1_0_0_0_1 - 0.342857142857163*G0_1_0_4_1_0_1_0_0 - 0.342857142857163*G0_1_0_4_1_0_2_0_1 + 0.342857142857163*G0_1_0_4_1_0_3_1_0 + 0.342857142857163*G0_1_0_4_1_0_3_1_1 - 0.342857142857163*G0_1_0_4_1_0_4_1_0 - 0.342857142857163*G0_1_0_4_1_0_5_1_1 + 0.342857142857163*G0_1_0_5_1_1_0_0_0 + 0.342857142857163*G0_1_0_5_1_1_0_0_1 - 0.342857142857163*G0_1_0_5_1_1_1_0_0 - 0.342857142857163*G0_1_0_5_1_1_2_0_1 + 0.342857142857163*G0_1_0_5_1_1_3_1_0 + 0.342857142857163*G0_1_0_5_1_1_3_1_1 - 0.342857142857163*G0_1_0_5_1_1_4_1_0 - 0.342857142857163*G0_1_0_5_1_1_5_1_1; + A[352] = 0.0; + A[17] = 0.0; + A[734] = 0.0; + A[421] = -0.0846560846560889*G0_0_0_0_0_0_0_0_0 - 0.0846560846560889*G0_0_0_0_0_0_0_0_1 + 0.0846560846560889*G0_0_0_0_0_0_1_0_0 + 0.0846560846560889*G0_0_0_0_0_0_2_0_1 - 0.0846560846560889*G0_0_0_0_0_0_3_1_0 - 0.0846560846560889*G0_0_0_0_0_0_3_1_1 + 0.0846560846560889*G0_0_0_0_0_0_4_1_0 + 0.0846560846560889*G0_0_0_0_0_0_5_1_1 - 0.0846560846560889*G0_0_0_0_0_1_0_0_0 - 0.0846560846560889*G0_0_0_0_0_1_0_0_1 + 0.0846560846560889*G0_0_0_0_0_1_1_0_0 + 0.0846560846560889*G0_0_0_0_0_1_2_0_1 - 0.0846560846560889*G0_0_0_0_0_1_3_1_0 - 0.0846560846560889*G0_0_0_0_0_1_3_1_1 + 0.0846560846560889*G0_0_0_0_0_1_4_1_0 + 0.0846560846560889*G0_0_0_0_0_1_5_1_1 + 0.0846560846560889*G0_0_0_1_0_0_0_0_0 + 0.0846560846560889*G0_0_0_1_0_0_0_0_1 - 0.0846560846560889*G0_0_0_1_0_0_1_0_0 - 0.0846560846560889*G0_0_0_1_0_0_2_0_1 + 0.0846560846560889*G0_0_0_1_0_0_3_1_0 + 0.0846560846560889*G0_0_0_1_0_0_3_1_1 - 0.0846560846560889*G0_0_0_1_0_0_4_1_0 - 0.0846560846560889*G0_0_0_1_0_0_5_1_1 + 0.0846560846560889*G0_0_0_2_0_1_0_0_0 + 0.0846560846560889*G0_0_0_2_0_1_0_0_1 - 0.0846560846560889*G0_0_0_2_0_1_1_0_0 - 0.0846560846560889*G0_0_0_2_0_1_2_0_1 + 0.0846560846560889*G0_0_0_2_0_1_3_1_0 + 0.0846560846560889*G0_0_0_2_0_1_3_1_1 - 0.0846560846560889*G0_0_0_2_0_1_4_1_0 - 0.0846560846560889*G0_0_0_2_0_1_5_1_1 - 0.0846560846560889*G0_0_0_3_1_0_0_0_0 - 0.0846560846560889*G0_0_0_3_1_0_0_0_1 + 0.0846560846560889*G0_0_0_3_1_0_1_0_0 + 0.0846560846560889*G0_0_0_3_1_0_2_0_1 - 0.0846560846560889*G0_0_0_3_1_0_3_1_0 - 0.0846560846560889*G0_0_0_3_1_0_3_1_1 + 0.0846560846560889*G0_0_0_3_1_0_4_1_0 + 0.0846560846560889*G0_0_0_3_1_0_5_1_1 - 0.0846560846560889*G0_0_0_3_1_1_0_0_0 - 0.0846560846560889*G0_0_0_3_1_1_0_0_1 + 0.0846560846560889*G0_0_0_3_1_1_1_0_0 + 0.0846560846560889*G0_0_0_3_1_1_2_0_1 - 0.0846560846560889*G0_0_0_3_1_1_3_1_0 - 0.0846560846560889*G0_0_0_3_1_1_3_1_1 + 0.0846560846560889*G0_0_0_3_1_1_4_1_0 + 0.0846560846560889*G0_0_0_3_1_1_5_1_1 + 0.0846560846560889*G0_0_0_4_1_0_0_0_0 + 0.0846560846560889*G0_0_0_4_1_0_0_0_1 - 0.0846560846560889*G0_0_0_4_1_0_1_0_0 - 0.0846560846560889*G0_0_0_4_1_0_2_0_1 + 0.0846560846560889*G0_0_0_4_1_0_3_1_0 + 0.0846560846560889*G0_0_0_4_1_0_3_1_1 - 0.0846560846560889*G0_0_0_4_1_0_4_1_0 - 0.0846560846560889*G0_0_0_4_1_0_5_1_1 + 0.0846560846560889*G0_0_0_5_1_1_0_0_0 + 0.0846560846560889*G0_0_0_5_1_1_0_0_1 - 0.0846560846560889*G0_0_0_5_1_1_1_0_0 - 0.0846560846560889*G0_0_0_5_1_1_2_0_1 + 0.0846560846560889*G0_0_0_5_1_1_3_1_0 + 0.0846560846560889*G0_0_0_5_1_1_3_1_1 - 0.0846560846560889*G0_0_0_5_1_1_4_1_0 - 0.0846560846560889*G0_0_0_5_1_1_5_1_1; + A[377] = 0.0; + A[58] = 0.0; + A[454] = 0.0; + A[410] = 0.0; + A[87] = 0.0; + A[792] = 0.0; + A[887] = -0.0846560846560837*G0_1_1_0_0_0_0_0_0 - 0.0846560846560837*G0_1_1_0_0_0_0_0_1 + 0.0846560846560837*G0_1_1_0_0_0_1_0_0 + 0.0846560846560837*G0_1_1_0_0_0_2_0_1 - 0.0846560846560837*G0_1_1_0_0_0_3_1_0 - 0.0846560846560837*G0_1_1_0_0_0_3_1_1 + 0.0846560846560837*G0_1_1_0_0_0_4_1_0 + 0.0846560846560837*G0_1_1_0_0_0_5_1_1 - 0.0846560846560837*G0_1_1_0_0_1_0_0_0 - 0.0846560846560837*G0_1_1_0_0_1_0_0_1 + 0.0846560846560837*G0_1_1_0_0_1_1_0_0 + 0.0846560846560837*G0_1_1_0_0_1_2_0_1 - 0.0846560846560837*G0_1_1_0_0_1_3_1_0 - 0.0846560846560837*G0_1_1_0_0_1_3_1_1 + 0.0846560846560837*G0_1_1_0_0_1_4_1_0 + 0.0846560846560837*G0_1_1_0_0_1_5_1_1 + 0.0846560846560837*G0_1_1_1_0_0_0_0_0 + 0.0846560846560837*G0_1_1_1_0_0_0_0_1 - 0.0846560846560837*G0_1_1_1_0_0_1_0_0 - 0.0846560846560837*G0_1_1_1_0_0_2_0_1 + 0.0846560846560837*G0_1_1_1_0_0_3_1_0 + 0.0846560846560837*G0_1_1_1_0_0_3_1_1 - 0.0846560846560837*G0_1_1_1_0_0_4_1_0 - 0.0846560846560837*G0_1_1_1_0_0_5_1_1 + 0.0846560846560837*G0_1_1_2_0_1_0_0_0 + 0.0846560846560837*G0_1_1_2_0_1_0_0_1 - 0.0846560846560837*G0_1_1_2_0_1_1_0_0 - 0.0846560846560837*G0_1_1_2_0_1_2_0_1 + 0.0846560846560837*G0_1_1_2_0_1_3_1_0 + 0.0846560846560837*G0_1_1_2_0_1_3_1_1 - 0.0846560846560837*G0_1_1_2_0_1_4_1_0 - 0.0846560846560837*G0_1_1_2_0_1_5_1_1 - 0.0846560846560837*G0_1_1_3_1_0_0_0_0 - 0.0846560846560837*G0_1_1_3_1_0_0_0_1 + 0.0846560846560837*G0_1_1_3_1_0_1_0_0 + 0.0846560846560837*G0_1_1_3_1_0_2_0_1 - 0.0846560846560837*G0_1_1_3_1_0_3_1_0 - 0.0846560846560837*G0_1_1_3_1_0_3_1_1 + 0.0846560846560837*G0_1_1_3_1_0_4_1_0 + 0.0846560846560837*G0_1_1_3_1_0_5_1_1 - 0.0846560846560837*G0_1_1_3_1_1_0_0_0 - 0.0846560846560837*G0_1_1_3_1_1_0_0_1 + 0.0846560846560837*G0_1_1_3_1_1_1_0_0 + 0.0846560846560837*G0_1_1_3_1_1_2_0_1 - 0.0846560846560837*G0_1_1_3_1_1_3_1_0 - 0.0846560846560837*G0_1_1_3_1_1_3_1_1 + 0.0846560846560837*G0_1_1_3_1_1_4_1_0 + 0.0846560846560837*G0_1_1_3_1_1_5_1_1 + 0.0846560846560837*G0_1_1_4_1_0_0_0_0 + 0.0846560846560837*G0_1_1_4_1_0_0_0_1 - 0.0846560846560837*G0_1_1_4_1_0_1_0_0 - 0.0846560846560837*G0_1_1_4_1_0_2_0_1 + 0.0846560846560837*G0_1_1_4_1_0_3_1_0 + 0.0846560846560837*G0_1_1_4_1_0_3_1_1 - 0.0846560846560837*G0_1_1_4_1_0_4_1_0 - 0.0846560846560837*G0_1_1_4_1_0_5_1_1 + 0.0846560846560837*G0_1_1_5_1_1_0_0_0 + 0.0846560846560837*G0_1_1_5_1_1_0_0_1 - 0.0846560846560837*G0_1_1_5_1_1_1_0_0 - 0.0846560846560837*G0_1_1_5_1_1_2_0_1 + 0.0846560846560837*G0_1_1_5_1_1_3_1_0 + 0.0846560846560837*G0_1_1_5_1_1_3_1_1 - 0.0846560846560837*G0_1_1_5_1_1_4_1_0 - 0.0846560846560837*G0_1_1_5_1_1_5_1_1; + A[811] = 0.0; + A[850] = 0.0; + A[174] = 0.0; + A[881] = 0.0; + A[480] = 0.0; + A[203] = 0.0; + A[583] = 0.0; + A[523] = 0.0; + A[232] = 0.0; + A[614] = 0.0; + A[550] = 0.0; + A[672] = 0.0; + A[279] = A[530] + 1.82857142857145*G0_0_0_0_0_0_0_0_0 + 1.82857142857145*G0_0_0_0_0_0_0_0_1 - 1.82857142857145*G0_0_0_0_0_0_1_0_0 - 1.82857142857145*G0_0_0_0_0_0_2_0_1 + 1.82857142857145*G0_0_0_0_0_0_3_1_0 + 1.82857142857145*G0_0_0_0_0_0_3_1_1 - 1.82857142857145*G0_0_0_0_0_0_4_1_0 - 1.82857142857145*G0_0_0_0_0_0_5_1_1 + 1.82857142857145*G0_0_0_0_0_1_0_0_0 + 1.82857142857145*G0_0_0_0_0_1_0_0_1 - 1.82857142857145*G0_0_0_0_0_1_1_0_0 - 1.82857142857145*G0_0_0_0_0_1_2_0_1 + 1.82857142857145*G0_0_0_0_0_1_3_1_0 + 1.82857142857145*G0_0_0_0_0_1_3_1_1 - 1.82857142857145*G0_0_0_0_0_1_4_1_0 - 1.82857142857145*G0_0_0_0_0_1_5_1_1 - 1.82857142857145*G0_0_0_1_0_0_0_0_0 - 1.82857142857145*G0_0_0_1_0_0_0_0_1 + 1.82857142857145*G0_0_0_1_0_0_1_0_0 + 1.82857142857145*G0_0_0_1_0_0_2_0_1 - 1.82857142857145*G0_0_0_1_0_0_3_1_0 - 1.82857142857145*G0_0_0_1_0_0_3_1_1 + 1.82857142857145*G0_0_0_1_0_0_4_1_0 + 1.82857142857145*G0_0_0_1_0_0_5_1_1 - 1.82857142857145*G0_0_0_2_0_1_0_0_0 - 1.82857142857145*G0_0_0_2_0_1_0_0_1 + 1.82857142857145*G0_0_0_2_0_1_1_0_0 + 1.82857142857145*G0_0_0_2_0_1_2_0_1 - 1.82857142857145*G0_0_0_2_0_1_3_1_0 - 1.82857142857145*G0_0_0_2_0_1_3_1_1 + 1.82857142857145*G0_0_0_2_0_1_4_1_0 + 1.82857142857145*G0_0_0_2_0_1_5_1_1 + 1.82857142857145*G0_0_0_3_1_0_0_0_0 + 1.82857142857145*G0_0_0_3_1_0_0_0_1 - 1.82857142857145*G0_0_0_3_1_0_1_0_0 - 1.82857142857145*G0_0_0_3_1_0_2_0_1 + 1.82857142857145*G0_0_0_3_1_0_3_1_0 + 1.82857142857145*G0_0_0_3_1_0_3_1_1 - 1.82857142857145*G0_0_0_3_1_0_4_1_0 - 1.82857142857145*G0_0_0_3_1_0_5_1_1 + 1.82857142857145*G0_0_0_3_1_1_0_0_0 + 1.82857142857145*G0_0_0_3_1_1_0_0_1 - 1.82857142857145*G0_0_0_3_1_1_1_0_0 - 1.82857142857145*G0_0_0_3_1_1_2_0_1 + 1.82857142857145*G0_0_0_3_1_1_3_1_0 + 1.82857142857145*G0_0_0_3_1_1_3_1_1 - 1.82857142857145*G0_0_0_3_1_1_4_1_0 - 1.82857142857145*G0_0_0_3_1_1_5_1_1 - 1.82857142857145*G0_0_0_4_1_0_0_0_0 - 1.82857142857145*G0_0_0_4_1_0_0_0_1 + 1.82857142857145*G0_0_0_4_1_0_1_0_0 + 1.82857142857145*G0_0_0_4_1_0_2_0_1 - 1.82857142857145*G0_0_0_4_1_0_3_1_0 - 1.82857142857145*G0_0_0_4_1_0_3_1_1 + 1.82857142857145*G0_0_0_4_1_0_4_1_0 + 1.82857142857145*G0_0_0_4_1_0_5_1_1 - 1.82857142857145*G0_0_0_5_1_1_0_0_0 - 1.82857142857145*G0_0_0_5_1_1_0_0_1 + 1.82857142857145*G0_0_0_5_1_1_1_0_0 + 1.82857142857145*G0_0_0_5_1_1_2_0_1 - 1.82857142857145*G0_0_0_5_1_1_3_1_0 - 1.82857142857145*G0_0_0_5_1_1_3_1_1 + 1.82857142857145*G0_0_0_5_1_1_4_1_0 + 1.82857142857145*G0_0_0_5_1_1_5_1_1 + 0.778835978835992*G0_0_1_0_0_0_0_0_0 + 0.778835978835992*G0_0_1_0_0_0_0_0_1 - 0.778835978835992*G0_0_1_0_0_0_1_0_0 - 0.778835978835992*G0_0_1_0_0_0_2_0_1 + 0.778835978835992*G0_0_1_0_0_0_3_1_0 + 0.778835978835992*G0_0_1_0_0_0_3_1_1 - 0.778835978835992*G0_0_1_0_0_0_4_1_0 - 0.778835978835992*G0_0_1_0_0_0_5_1_1 + 0.778835978835992*G0_0_1_0_0_1_0_0_0 + 0.778835978835992*G0_0_1_0_0_1_0_0_1 - 0.778835978835992*G0_0_1_0_0_1_1_0_0 - 0.778835978835992*G0_0_1_0_0_1_2_0_1 + 0.778835978835992*G0_0_1_0_0_1_3_1_0 + 0.778835978835992*G0_0_1_0_0_1_3_1_1 - 0.778835978835992*G0_0_1_0_0_1_4_1_0 - 0.778835978835992*G0_0_1_0_0_1_5_1_1 - 0.778835978835992*G0_0_1_1_0_0_0_0_0 - 0.778835978835992*G0_0_1_1_0_0_0_0_1 + 0.778835978835992*G0_0_1_1_0_0_1_0_0 + 0.778835978835992*G0_0_1_1_0_0_2_0_1 - 0.778835978835992*G0_0_1_1_0_0_3_1_0 - 0.778835978835992*G0_0_1_1_0_0_3_1_1 + 0.778835978835992*G0_0_1_1_0_0_4_1_0 + 0.778835978835992*G0_0_1_1_0_0_5_1_1 - 0.778835978835992*G0_0_1_2_0_1_0_0_0 - 0.778835978835992*G0_0_1_2_0_1_0_0_1 + 0.778835978835992*G0_0_1_2_0_1_1_0_0 + 0.778835978835992*G0_0_1_2_0_1_2_0_1 - 0.778835978835992*G0_0_1_2_0_1_3_1_0 - 0.778835978835992*G0_0_1_2_0_1_3_1_1 + 0.778835978835992*G0_0_1_2_0_1_4_1_0 + 0.778835978835992*G0_0_1_2_0_1_5_1_1 + 0.778835978835992*G0_0_1_3_1_0_0_0_0 + 0.778835978835992*G0_0_1_3_1_0_0_0_1 - 0.778835978835992*G0_0_1_3_1_0_1_0_0 - 0.778835978835992*G0_0_1_3_1_0_2_0_1 + 0.778835978835992*G0_0_1_3_1_0_3_1_0 + 0.778835978835992*G0_0_1_3_1_0_3_1_1 - 0.778835978835992*G0_0_1_3_1_0_4_1_0 - 0.778835978835992*G0_0_1_3_1_0_5_1_1 + 0.778835978835992*G0_0_1_3_1_1_0_0_0 + 0.778835978835992*G0_0_1_3_1_1_0_0_1 - 0.778835978835992*G0_0_1_3_1_1_1_0_0 - 0.778835978835992*G0_0_1_3_1_1_2_0_1 + 0.778835978835992*G0_0_1_3_1_1_3_1_0 + 0.778835978835992*G0_0_1_3_1_1_3_1_1 - 0.778835978835992*G0_0_1_3_1_1_4_1_0 - 0.778835978835992*G0_0_1_3_1_1_5_1_1 - 0.778835978835992*G0_0_1_4_1_0_0_0_0 - 0.778835978835992*G0_0_1_4_1_0_0_0_1 + 0.778835978835992*G0_0_1_4_1_0_1_0_0 + 0.778835978835992*G0_0_1_4_1_0_2_0_1 - 0.778835978835992*G0_0_1_4_1_0_3_1_0 - 0.778835978835992*G0_0_1_4_1_0_3_1_1 + 0.778835978835992*G0_0_1_4_1_0_4_1_0 + 0.778835978835992*G0_0_1_4_1_0_5_1_1 - 0.778835978835992*G0_0_1_5_1_1_0_0_0 - 0.778835978835992*G0_0_1_5_1_1_0_0_1 + 0.778835978835992*G0_0_1_5_1_1_1_0_0 + 0.778835978835992*G0_0_1_5_1_1_2_0_1 - 0.778835978835992*G0_0_1_5_1_1_3_1_0 - 0.778835978835992*G0_0_1_5_1_1_3_1_1 + 0.778835978835992*G0_0_1_5_1_1_4_1_0 + 0.778835978835992*G0_0_1_5_1_1_5_1_1 + 1.70158730158732*G0_1_1_0_0_0_0_0_0 + 1.70158730158732*G0_1_1_0_0_0_0_0_1 - 1.70158730158732*G0_1_1_0_0_0_1_0_0 - 1.70158730158732*G0_1_1_0_0_0_2_0_1 + 1.70158730158732*G0_1_1_0_0_0_3_1_0 + 1.70158730158732*G0_1_1_0_0_0_3_1_1 - 1.70158730158732*G0_1_1_0_0_0_4_1_0 - 1.70158730158732*G0_1_1_0_0_0_5_1_1 + 1.70158730158732*G0_1_1_0_0_1_0_0_0 + 1.70158730158732*G0_1_1_0_0_1_0_0_1 - 1.70158730158732*G0_1_1_0_0_1_1_0_0 - 1.70158730158732*G0_1_1_0_0_1_2_0_1 + 1.70158730158732*G0_1_1_0_0_1_3_1_0 + 1.70158730158732*G0_1_1_0_0_1_3_1_1 - 1.70158730158732*G0_1_1_0_0_1_4_1_0 - 1.70158730158732*G0_1_1_0_0_1_5_1_1 - 1.70158730158732*G0_1_1_1_0_0_0_0_0 - 1.70158730158732*G0_1_1_1_0_0_0_0_1 + 1.70158730158732*G0_1_1_1_0_0_1_0_0 + 1.70158730158732*G0_1_1_1_0_0_2_0_1 - 1.70158730158732*G0_1_1_1_0_0_3_1_0 - 1.70158730158732*G0_1_1_1_0_0_3_1_1 + 1.70158730158732*G0_1_1_1_0_0_4_1_0 + 1.70158730158732*G0_1_1_1_0_0_5_1_1 - 1.70158730158732*G0_1_1_2_0_1_0_0_0 - 1.70158730158732*G0_1_1_2_0_1_0_0_1 + 1.70158730158732*G0_1_1_2_0_1_1_0_0 + 1.70158730158732*G0_1_1_2_0_1_2_0_1 - 1.70158730158732*G0_1_1_2_0_1_3_1_0 - 1.70158730158732*G0_1_1_2_0_1_3_1_1 + 1.70158730158732*G0_1_1_2_0_1_4_1_0 + 1.70158730158732*G0_1_1_2_0_1_5_1_1 + 1.70158730158732*G0_1_1_3_1_0_0_0_0 + 1.70158730158732*G0_1_1_3_1_0_0_0_1 - 1.70158730158732*G0_1_1_3_1_0_1_0_0 - 1.70158730158732*G0_1_1_3_1_0_2_0_1 + 1.70158730158732*G0_1_1_3_1_0_3_1_0 + 1.70158730158732*G0_1_1_3_1_0_3_1_1 - 1.70158730158732*G0_1_1_3_1_0_4_1_0 - 1.70158730158732*G0_1_1_3_1_0_5_1_1 + 1.70158730158732*G0_1_1_3_1_1_0_0_0 + 1.70158730158732*G0_1_1_3_1_1_0_0_1 - 1.70158730158732*G0_1_1_3_1_1_1_0_0 - 1.70158730158732*G0_1_1_3_1_1_2_0_1 + 1.70158730158732*G0_1_1_3_1_1_3_1_0 + 1.70158730158732*G0_1_1_3_1_1_3_1_1 - 1.70158730158732*G0_1_1_3_1_1_4_1_0 - 1.70158730158732*G0_1_1_3_1_1_5_1_1 - 1.70158730158732*G0_1_1_4_1_0_0_0_0 - 1.70158730158732*G0_1_1_4_1_0_0_0_1 + 1.70158730158732*G0_1_1_4_1_0_1_0_0 + 1.70158730158732*G0_1_1_4_1_0_2_0_1 - 1.70158730158732*G0_1_1_4_1_0_3_1_0 - 1.70158730158732*G0_1_1_4_1_0_3_1_1 + 1.70158730158732*G0_1_1_4_1_0_4_1_0 + 1.70158730158732*G0_1_1_4_1_0_5_1_1 - 1.70158730158732*G0_1_1_5_1_1_0_0_0 - 1.70158730158732*G0_1_1_5_1_1_0_0_1 + 1.70158730158732*G0_1_1_5_1_1_1_0_0 + 1.70158730158732*G0_1_1_5_1_1_2_0_1 - 1.70158730158732*G0_1_1_5_1_1_3_1_0 - 1.70158730158732*G0_1_1_5_1_1_3_1_1 + 1.70158730158732*G0_1_1_5_1_1_4_1_0 + 1.70158730158732*G0_1_1_5_1_1_5_1_1; + A[699] = 0.0; + A[258] = 0.0; + A[345] = 0.0; + A[289] = 0.0; + A[51] = 0.0; + A[463] = 0.0; + A[403] = 5.68888888888896*G0_0_0_0_0_0_0_0_0 + 5.68888888888896*G0_0_0_0_0_0_0_0_1 - 5.68888888888896*G0_0_0_0_0_0_1_0_0 - 5.68888888888896*G0_0_0_0_0_0_2_0_1 + 5.68888888888896*G0_0_0_0_0_0_3_1_0 + 5.68888888888896*G0_0_0_0_0_0_3_1_1 - 5.68888888888896*G0_0_0_0_0_0_4_1_0 - 5.68888888888896*G0_0_0_0_0_0_5_1_1 + 5.68888888888896*G0_0_0_0_0_1_0_0_0 + 5.68888888888896*G0_0_0_0_0_1_0_0_1 - 5.68888888888896*G0_0_0_0_0_1_1_0_0 - 5.68888888888896*G0_0_0_0_0_1_2_0_1 + 5.68888888888896*G0_0_0_0_0_1_3_1_0 + 5.68888888888896*G0_0_0_0_0_1_3_1_1 - 5.68888888888896*G0_0_0_0_0_1_4_1_0 - 5.68888888888896*G0_0_0_0_0_1_5_1_1 - 5.68888888888896*G0_0_0_1_0_0_0_0_0 - 5.68888888888896*G0_0_0_1_0_0_0_0_1 + 5.68888888888896*G0_0_0_1_0_0_1_0_0 + 5.68888888888896*G0_0_0_1_0_0_2_0_1 - 5.68888888888896*G0_0_0_1_0_0_3_1_0 - 5.68888888888896*G0_0_0_1_0_0_3_1_1 + 5.68888888888896*G0_0_0_1_0_0_4_1_0 + 5.68888888888896*G0_0_0_1_0_0_5_1_1 - 5.68888888888896*G0_0_0_2_0_1_0_0_0 - 5.68888888888896*G0_0_0_2_0_1_0_0_1 + 5.68888888888896*G0_0_0_2_0_1_1_0_0 + 5.68888888888896*G0_0_0_2_0_1_2_0_1 - 5.68888888888896*G0_0_0_2_0_1_3_1_0 - 5.68888888888896*G0_0_0_2_0_1_3_1_1 + 5.68888888888896*G0_0_0_2_0_1_4_1_0 + 5.68888888888896*G0_0_0_2_0_1_5_1_1 + 5.68888888888896*G0_0_0_3_1_0_0_0_0 + 5.68888888888896*G0_0_0_3_1_0_0_0_1 - 5.68888888888896*G0_0_0_3_1_0_1_0_0 - 5.68888888888896*G0_0_0_3_1_0_2_0_1 + 5.68888888888896*G0_0_0_3_1_0_3_1_0 + 5.68888888888896*G0_0_0_3_1_0_3_1_1 - 5.68888888888896*G0_0_0_3_1_0_4_1_0 - 5.68888888888896*G0_0_0_3_1_0_5_1_1 + 5.68888888888896*G0_0_0_3_1_1_0_0_0 + 5.68888888888896*G0_0_0_3_1_1_0_0_1 - 5.68888888888896*G0_0_0_3_1_1_1_0_0 - 5.68888888888896*G0_0_0_3_1_1_2_0_1 + 5.68888888888896*G0_0_0_3_1_1_3_1_0 + 5.68888888888896*G0_0_0_3_1_1_3_1_1 - 5.68888888888896*G0_0_0_3_1_1_4_1_0 - 5.68888888888896*G0_0_0_3_1_1_5_1_1 - 5.68888888888896*G0_0_0_4_1_0_0_0_0 - 5.68888888888896*G0_0_0_4_1_0_0_0_1 + 5.68888888888896*G0_0_0_4_1_0_1_0_0 + 5.68888888888896*G0_0_0_4_1_0_2_0_1 - 5.68888888888896*G0_0_0_4_1_0_3_1_0 - 5.68888888888896*G0_0_0_4_1_0_3_1_1 + 5.68888888888896*G0_0_0_4_1_0_4_1_0 + 5.68888888888896*G0_0_0_4_1_0_5_1_1 - 5.68888888888896*G0_0_0_5_1_1_0_0_0 - 5.68888888888896*G0_0_0_5_1_1_0_0_1 + 5.68888888888896*G0_0_0_5_1_1_1_0_0 + 5.68888888888896*G0_0_0_5_1_1_2_0_1 - 5.68888888888896*G0_0_0_5_1_1_3_1_0 - 5.68888888888896*G0_0_0_5_1_1_3_1_1 + 5.68888888888896*G0_0_0_5_1_1_4_1_0 + 5.68888888888896*G0_0_0_5_1_1_5_1_1 + 2.8444444444445*G0_0_1_0_0_0_0_0_0 + 2.8444444444445*G0_0_1_0_0_0_0_0_1 - 2.8444444444445*G0_0_1_0_0_0_1_0_0 - 2.8444444444445*G0_0_1_0_0_0_2_0_1 + 2.8444444444445*G0_0_1_0_0_0_3_1_0 + 2.8444444444445*G0_0_1_0_0_0_3_1_1 - 2.8444444444445*G0_0_1_0_0_0_4_1_0 - 2.8444444444445*G0_0_1_0_0_0_5_1_1 + 2.8444444444445*G0_0_1_0_0_1_0_0_0 + 2.8444444444445*G0_0_1_0_0_1_0_0_1 - 2.8444444444445*G0_0_1_0_0_1_1_0_0 - 2.8444444444445*G0_0_1_0_0_1_2_0_1 + 2.8444444444445*G0_0_1_0_0_1_3_1_0 + 2.8444444444445*G0_0_1_0_0_1_3_1_1 - 2.8444444444445*G0_0_1_0_0_1_4_1_0 - 2.8444444444445*G0_0_1_0_0_1_5_1_1 - 2.8444444444445*G0_0_1_1_0_0_0_0_0 - 2.8444444444445*G0_0_1_1_0_0_0_0_1 + 2.8444444444445*G0_0_1_1_0_0_1_0_0 + 2.8444444444445*G0_0_1_1_0_0_2_0_1 - 2.8444444444445*G0_0_1_1_0_0_3_1_0 - 2.8444444444445*G0_0_1_1_0_0_3_1_1 + 2.8444444444445*G0_0_1_1_0_0_4_1_0 + 2.8444444444445*G0_0_1_1_0_0_5_1_1 - 2.8444444444445*G0_0_1_2_0_1_0_0_0 - 2.8444444444445*G0_0_1_2_0_1_0_0_1 + 2.8444444444445*G0_0_1_2_0_1_1_0_0 + 2.8444444444445*G0_0_1_2_0_1_2_0_1 - 2.8444444444445*G0_0_1_2_0_1_3_1_0 - 2.8444444444445*G0_0_1_2_0_1_3_1_1 + 2.8444444444445*G0_0_1_2_0_1_4_1_0 + 2.8444444444445*G0_0_1_2_0_1_5_1_1 + 2.8444444444445*G0_0_1_3_1_0_0_0_0 + 2.8444444444445*G0_0_1_3_1_0_0_0_1 - 2.8444444444445*G0_0_1_3_1_0_1_0_0 - 2.8444444444445*G0_0_1_3_1_0_2_0_1 + 2.8444444444445*G0_0_1_3_1_0_3_1_0 + 2.8444444444445*G0_0_1_3_1_0_3_1_1 - 2.8444444444445*G0_0_1_3_1_0_4_1_0 - 2.8444444444445*G0_0_1_3_1_0_5_1_1 + 2.8444444444445*G0_0_1_3_1_1_0_0_0 + 2.8444444444445*G0_0_1_3_1_1_0_0_1 - 2.8444444444445*G0_0_1_3_1_1_1_0_0 - 2.8444444444445*G0_0_1_3_1_1_2_0_1 + 2.8444444444445*G0_0_1_3_1_1_3_1_0 + 2.8444444444445*G0_0_1_3_1_1_3_1_1 - 2.8444444444445*G0_0_1_3_1_1_4_1_0 - 2.8444444444445*G0_0_1_3_1_1_5_1_1 - 2.8444444444445*G0_0_1_4_1_0_0_0_0 - 2.8444444444445*G0_0_1_4_1_0_0_0_1 + 2.8444444444445*G0_0_1_4_1_0_1_0_0 + 2.8444444444445*G0_0_1_4_1_0_2_0_1 - 2.8444444444445*G0_0_1_4_1_0_3_1_0 - 2.8444444444445*G0_0_1_4_1_0_3_1_1 + 2.8444444444445*G0_0_1_4_1_0_4_1_0 + 2.8444444444445*G0_0_1_4_1_0_5_1_1 - 2.8444444444445*G0_0_1_5_1_1_0_0_0 - 2.8444444444445*G0_0_1_5_1_1_0_0_1 + 2.8444444444445*G0_0_1_5_1_1_1_0_0 + 2.8444444444445*G0_0_1_5_1_1_2_0_1 - 2.8444444444445*G0_0_1_5_1_1_3_1_0 - 2.8444444444445*G0_0_1_5_1_1_3_1_1 + 2.8444444444445*G0_0_1_5_1_1_4_1_0 + 2.8444444444445*G0_0_1_5_1_1_5_1_1 + 2.8444444444445*G0_1_0_0_0_0_0_0_0 + 2.8444444444445*G0_1_0_0_0_0_0_0_1 - 2.8444444444445*G0_1_0_0_0_0_1_0_0 - 2.8444444444445*G0_1_0_0_0_0_2_0_1 + 2.8444444444445*G0_1_0_0_0_0_3_1_0 + 2.8444444444445*G0_1_0_0_0_0_3_1_1 - 2.8444444444445*G0_1_0_0_0_0_4_1_0 - 2.8444444444445*G0_1_0_0_0_0_5_1_1 + 2.8444444444445*G0_1_0_0_0_1_0_0_0 + 2.8444444444445*G0_1_0_0_0_1_0_0_1 - 2.8444444444445*G0_1_0_0_0_1_1_0_0 - 2.8444444444445*G0_1_0_0_0_1_2_0_1 + 2.8444444444445*G0_1_0_0_0_1_3_1_0 + 2.8444444444445*G0_1_0_0_0_1_3_1_1 - 2.8444444444445*G0_1_0_0_0_1_4_1_0 - 2.8444444444445*G0_1_0_0_0_1_5_1_1 - 2.8444444444445*G0_1_0_1_0_0_0_0_0 - 2.8444444444445*G0_1_0_1_0_0_0_0_1 + 2.8444444444445*G0_1_0_1_0_0_1_0_0 + 2.8444444444445*G0_1_0_1_0_0_2_0_1 - 2.8444444444445*G0_1_0_1_0_0_3_1_0 - 2.8444444444445*G0_1_0_1_0_0_3_1_1 + 2.8444444444445*G0_1_0_1_0_0_4_1_0 + 2.8444444444445*G0_1_0_1_0_0_5_1_1 - 2.8444444444445*G0_1_0_2_0_1_0_0_0 - 2.8444444444445*G0_1_0_2_0_1_0_0_1 + 2.8444444444445*G0_1_0_2_0_1_1_0_0 + 2.8444444444445*G0_1_0_2_0_1_2_0_1 - 2.8444444444445*G0_1_0_2_0_1_3_1_0 - 2.8444444444445*G0_1_0_2_0_1_3_1_1 + 2.8444444444445*G0_1_0_2_0_1_4_1_0 + 2.8444444444445*G0_1_0_2_0_1_5_1_1 + 2.8444444444445*G0_1_0_3_1_0_0_0_0 + 2.8444444444445*G0_1_0_3_1_0_0_0_1 - 2.8444444444445*G0_1_0_3_1_0_1_0_0 - 2.8444444444445*G0_1_0_3_1_0_2_0_1 + 2.8444444444445*G0_1_0_3_1_0_3_1_0 + 2.8444444444445*G0_1_0_3_1_0_3_1_1 - 2.8444444444445*G0_1_0_3_1_0_4_1_0 - 2.8444444444445*G0_1_0_3_1_0_5_1_1 + 2.8444444444445*G0_1_0_3_1_1_0_0_0 + 2.8444444444445*G0_1_0_3_1_1_0_0_1 - 2.8444444444445*G0_1_0_3_1_1_1_0_0 - 2.8444444444445*G0_1_0_3_1_1_2_0_1 + 2.8444444444445*G0_1_0_3_1_1_3_1_0 + 2.8444444444445*G0_1_0_3_1_1_3_1_1 - 2.8444444444445*G0_1_0_3_1_1_4_1_0 - 2.8444444444445*G0_1_0_3_1_1_5_1_1 - 2.8444444444445*G0_1_0_4_1_0_0_0_0 - 2.8444444444445*G0_1_0_4_1_0_0_0_1 + 2.8444444444445*G0_1_0_4_1_0_1_0_0 + 2.8444444444445*G0_1_0_4_1_0_2_0_1 - 2.8444444444445*G0_1_0_4_1_0_3_1_0 - 2.8444444444445*G0_1_0_4_1_0_3_1_1 + 2.8444444444445*G0_1_0_4_1_0_4_1_0 + 2.8444444444445*G0_1_0_4_1_0_5_1_1 - 2.8444444444445*G0_1_0_5_1_1_0_0_0 - 2.8444444444445*G0_1_0_5_1_1_0_0_1 + 2.8444444444445*G0_1_0_5_1_1_1_0_0 + 2.8444444444445*G0_1_0_5_1_1_2_0_1 - 2.8444444444445*G0_1_0_5_1_1_3_1_0 - 2.8444444444445*G0_1_0_5_1_1_3_1_1 + 2.8444444444445*G0_1_0_5_1_1_4_1_0 + 2.8444444444445*G0_1_0_5_1_1_5_1_1 + 5.688888888889*G0_1_1_0_0_0_0_0_0 + 5.688888888889*G0_1_1_0_0_0_0_0_1 - 5.688888888889*G0_1_1_0_0_0_1_0_0 - 5.688888888889*G0_1_1_0_0_0_2_0_1 + 5.688888888889*G0_1_1_0_0_0_3_1_0 + 5.688888888889*G0_1_1_0_0_0_3_1_1 - 5.688888888889*G0_1_1_0_0_0_4_1_0 - 5.688888888889*G0_1_1_0_0_0_5_1_1 + 5.688888888889*G0_1_1_0_0_1_0_0_0 + 5.688888888889*G0_1_1_0_0_1_0_0_1 - 5.688888888889*G0_1_1_0_0_1_1_0_0 - 5.688888888889*G0_1_1_0_0_1_2_0_1 + 5.688888888889*G0_1_1_0_0_1_3_1_0 + 5.688888888889*G0_1_1_0_0_1_3_1_1 - 5.688888888889*G0_1_1_0_0_1_4_1_0 - 5.688888888889*G0_1_1_0_0_1_5_1_1 - 5.688888888889*G0_1_1_1_0_0_0_0_0 - 5.688888888889*G0_1_1_1_0_0_0_0_1 + 5.688888888889*G0_1_1_1_0_0_1_0_0 + 5.688888888889*G0_1_1_1_0_0_2_0_1 - 5.688888888889*G0_1_1_1_0_0_3_1_0 - 5.688888888889*G0_1_1_1_0_0_3_1_1 + 5.688888888889*G0_1_1_1_0_0_4_1_0 + 5.688888888889*G0_1_1_1_0_0_5_1_1 - 5.688888888889*G0_1_1_2_0_1_0_0_0 - 5.688888888889*G0_1_1_2_0_1_0_0_1 + 5.688888888889*G0_1_1_2_0_1_1_0_0 + 5.688888888889*G0_1_1_2_0_1_2_0_1 - 5.688888888889*G0_1_1_2_0_1_3_1_0 - 5.688888888889*G0_1_1_2_0_1_3_1_1 + 5.688888888889*G0_1_1_2_0_1_4_1_0 + 5.688888888889*G0_1_1_2_0_1_5_1_1 + 5.688888888889*G0_1_1_3_1_0_0_0_0 + 5.688888888889*G0_1_1_3_1_0_0_0_1 - 5.688888888889*G0_1_1_3_1_0_1_0_0 - 5.688888888889*G0_1_1_3_1_0_2_0_1 + 5.688888888889*G0_1_1_3_1_0_3_1_0 + 5.688888888889*G0_1_1_3_1_0_3_1_1 - 5.688888888889*G0_1_1_3_1_0_4_1_0 - 5.688888888889*G0_1_1_3_1_0_5_1_1 + 5.688888888889*G0_1_1_3_1_1_0_0_0 + 5.688888888889*G0_1_1_3_1_1_0_0_1 - 5.688888888889*G0_1_1_3_1_1_1_0_0 - 5.688888888889*G0_1_1_3_1_1_2_0_1 + 5.688888888889*G0_1_1_3_1_1_3_1_0 + 5.688888888889*G0_1_1_3_1_1_3_1_1 - 5.688888888889*G0_1_1_3_1_1_4_1_0 - 5.688888888889*G0_1_1_3_1_1_5_1_1 - 5.688888888889*G0_1_1_4_1_0_0_0_0 - 5.688888888889*G0_1_1_4_1_0_0_0_1 + 5.688888888889*G0_1_1_4_1_0_1_0_0 + 5.688888888889*G0_1_1_4_1_0_2_0_1 - 5.688888888889*G0_1_1_4_1_0_3_1_0 - 5.688888888889*G0_1_1_4_1_0_3_1_1 + 5.688888888889*G0_1_1_4_1_0_4_1_0 + 5.688888888889*G0_1_1_4_1_0_5_1_1 - 5.688888888889*G0_1_1_5_1_1_0_0_0 - 5.688888888889*G0_1_1_5_1_1_0_0_1 + 5.688888888889*G0_1_1_5_1_1_1_0_0 + 5.688888888889*G0_1_1_5_1_1_2_0_1 - 5.688888888889*G0_1_1_5_1_1_3_1_0 - 5.688888888889*G0_1_1_5_1_1_3_1_1 + 5.688888888889*G0_1_1_5_1_1_4_1_0 + 5.688888888889*G0_1_1_5_1_1_5_1_1; + A[78] = 0.0; + A[803] = A[716]; + A[816] = 0.0; + A[45] = 0.0; + A[841] = 0.0; + A[72] = A[887]; + A[874] = 0.0; + A[107] = 0.0; + A[487] = 0.0; + A[516] = 0.0; + A[225] = 0.0; + A[545] = 0.0; + A[509] = A[421]; + A[638] = 0.0; + A[534] = -0.500000000000032*A[887]; + A[92] = -A[534] + 0.203174603174604*G0_0_1_0_0_0_0_0_0 + 0.203174603174604*G0_0_1_0_0_0_0_0_1 - 0.203174603174604*G0_0_1_0_0_0_1_0_0 - 0.203174603174604*G0_0_1_0_0_0_2_0_1 + 0.203174603174604*G0_0_1_0_0_0_3_1_0 + 0.203174603174604*G0_0_1_0_0_0_3_1_1 - 0.203174603174604*G0_0_1_0_0_0_4_1_0 - 0.203174603174604*G0_0_1_0_0_0_5_1_1 + 0.203174603174604*G0_0_1_0_0_1_0_0_0 + 0.203174603174604*G0_0_1_0_0_1_0_0_1 - 0.203174603174604*G0_0_1_0_0_1_1_0_0 - 0.203174603174604*G0_0_1_0_0_1_2_0_1 + 0.203174603174604*G0_0_1_0_0_1_3_1_0 + 0.203174603174604*G0_0_1_0_0_1_3_1_1 - 0.203174603174604*G0_0_1_0_0_1_4_1_0 - 0.203174603174604*G0_0_1_0_0_1_5_1_1 - 0.203174603174604*G0_0_1_1_0_0_0_0_0 - 0.203174603174604*G0_0_1_1_0_0_0_0_1 + 0.203174603174604*G0_0_1_1_0_0_1_0_0 + 0.203174603174604*G0_0_1_1_0_0_2_0_1 - 0.203174603174604*G0_0_1_1_0_0_3_1_0 - 0.203174603174604*G0_0_1_1_0_0_3_1_1 + 0.203174603174604*G0_0_1_1_0_0_4_1_0 + 0.203174603174604*G0_0_1_1_0_0_5_1_1 - 0.203174603174604*G0_0_1_2_0_1_0_0_0 - 0.203174603174604*G0_0_1_2_0_1_0_0_1 + 0.203174603174604*G0_0_1_2_0_1_1_0_0 + 0.203174603174604*G0_0_1_2_0_1_2_0_1 - 0.203174603174604*G0_0_1_2_0_1_3_1_0 - 0.203174603174604*G0_0_1_2_0_1_3_1_1 + 0.203174603174604*G0_0_1_2_0_1_4_1_0 + 0.203174603174604*G0_0_1_2_0_1_5_1_1 + 0.203174603174604*G0_0_1_3_1_0_0_0_0 + 0.203174603174604*G0_0_1_3_1_0_0_0_1 - 0.203174603174604*G0_0_1_3_1_0_1_0_0 - 0.203174603174604*G0_0_1_3_1_0_2_0_1 + 0.203174603174604*G0_0_1_3_1_0_3_1_0 + 0.203174603174604*G0_0_1_3_1_0_3_1_1 - 0.203174603174604*G0_0_1_3_1_0_4_1_0 - 0.203174603174604*G0_0_1_3_1_0_5_1_1 + 0.203174603174604*G0_0_1_3_1_1_0_0_0 + 0.203174603174604*G0_0_1_3_1_1_0_0_1 - 0.203174603174604*G0_0_1_3_1_1_1_0_0 - 0.203174603174604*G0_0_1_3_1_1_2_0_1 + 0.203174603174604*G0_0_1_3_1_1_3_1_0 + 0.203174603174604*G0_0_1_3_1_1_3_1_1 - 0.203174603174604*G0_0_1_3_1_1_4_1_0 - 0.203174603174604*G0_0_1_3_1_1_5_1_1 - 0.203174603174604*G0_0_1_4_1_0_0_0_0 - 0.203174603174604*G0_0_1_4_1_0_0_0_1 + 0.203174603174604*G0_0_1_4_1_0_1_0_0 + 0.203174603174604*G0_0_1_4_1_0_2_0_1 - 0.203174603174604*G0_0_1_4_1_0_3_1_0 - 0.203174603174604*G0_0_1_4_1_0_3_1_1 + 0.203174603174604*G0_0_1_4_1_0_4_1_0 + 0.203174603174604*G0_0_1_4_1_0_5_1_1 - 0.203174603174604*G0_0_1_5_1_1_0_0_0 - 0.203174603174604*G0_0_1_5_1_1_0_0_1 + 0.203174603174604*G0_0_1_5_1_1_1_0_0 + 0.203174603174604*G0_0_1_5_1_1_2_0_1 - 0.203174603174604*G0_0_1_5_1_1_3_1_0 - 0.203174603174604*G0_0_1_5_1_1_3_1_1 + 0.203174603174604*G0_0_1_5_1_1_4_1_0 + 0.203174603174604*G0_0_1_5_1_1_5_1_1; + A[667] = 0.0; + A[696] = 0.0; + A[265] = 0.0; + A[290] = 0.0; + A[439] = 0.0; + A[319] = 0.0; + A[775] = 2.9587301587302*G0_0_0_0_0_0_0_0_0 + 2.9587301587302*G0_0_0_0_0_0_0_0_1 - 2.9587301587302*G0_0_0_0_0_0_1_0_0 - 2.9587301587302*G0_0_0_0_0_0_2_0_1 + 2.9587301587302*G0_0_0_0_0_0_3_1_0 + 2.9587301587302*G0_0_0_0_0_0_3_1_1 - 2.9587301587302*G0_0_0_0_0_0_4_1_0 - 2.9587301587302*G0_0_0_0_0_0_5_1_1 + 2.9587301587302*G0_0_0_0_0_1_0_0_0 + 2.9587301587302*G0_0_0_0_0_1_0_0_1 - 2.9587301587302*G0_0_0_0_0_1_1_0_0 - 2.9587301587302*G0_0_0_0_0_1_2_0_1 + 2.9587301587302*G0_0_0_0_0_1_3_1_0 + 2.9587301587302*G0_0_0_0_0_1_3_1_1 - 2.9587301587302*G0_0_0_0_0_1_4_1_0 - 2.9587301587302*G0_0_0_0_0_1_5_1_1 - 2.9587301587302*G0_0_0_1_0_0_0_0_0 - 2.9587301587302*G0_0_0_1_0_0_0_0_1 + 2.9587301587302*G0_0_0_1_0_0_1_0_0 + 2.9587301587302*G0_0_0_1_0_0_2_0_1 - 2.9587301587302*G0_0_0_1_0_0_3_1_0 - 2.9587301587302*G0_0_0_1_0_0_3_1_1 + 2.9587301587302*G0_0_0_1_0_0_4_1_0 + 2.9587301587302*G0_0_0_1_0_0_5_1_1 - 2.9587301587302*G0_0_0_2_0_1_0_0_0 - 2.9587301587302*G0_0_0_2_0_1_0_0_1 + 2.9587301587302*G0_0_0_2_0_1_1_0_0 + 2.9587301587302*G0_0_0_2_0_1_2_0_1 - 2.9587301587302*G0_0_0_2_0_1_3_1_0 - 2.9587301587302*G0_0_0_2_0_1_3_1_1 + 2.9587301587302*G0_0_0_2_0_1_4_1_0 + 2.9587301587302*G0_0_0_2_0_1_5_1_1 + 2.9587301587302*G0_0_0_3_1_0_0_0_0 + 2.9587301587302*G0_0_0_3_1_0_0_0_1 - 2.9587301587302*G0_0_0_3_1_0_1_0_0 - 2.9587301587302*G0_0_0_3_1_0_2_0_1 + 2.9587301587302*G0_0_0_3_1_0_3_1_0 + 2.9587301587302*G0_0_0_3_1_0_3_1_1 - 2.9587301587302*G0_0_0_3_1_0_4_1_0 - 2.9587301587302*G0_0_0_3_1_0_5_1_1 + 2.9587301587302*G0_0_0_3_1_1_0_0_0 + 2.9587301587302*G0_0_0_3_1_1_0_0_1 - 2.9587301587302*G0_0_0_3_1_1_1_0_0 - 2.9587301587302*G0_0_0_3_1_1_2_0_1 + 2.9587301587302*G0_0_0_3_1_1_3_1_0 + 2.9587301587302*G0_0_0_3_1_1_3_1_1 - 2.9587301587302*G0_0_0_3_1_1_4_1_0 - 2.9587301587302*G0_0_0_3_1_1_5_1_1 - 2.9587301587302*G0_0_0_4_1_0_0_0_0 - 2.9587301587302*G0_0_0_4_1_0_0_0_1 + 2.9587301587302*G0_0_0_4_1_0_1_0_0 + 2.9587301587302*G0_0_0_4_1_0_2_0_1 - 2.9587301587302*G0_0_0_4_1_0_3_1_0 - 2.9587301587302*G0_0_0_4_1_0_3_1_1 + 2.9587301587302*G0_0_0_4_1_0_4_1_0 + 2.9587301587302*G0_0_0_4_1_0_5_1_1 - 2.9587301587302*G0_0_0_5_1_1_0_0_0 - 2.9587301587302*G0_0_0_5_1_1_0_0_1 + 2.9587301587302*G0_0_0_5_1_1_1_0_0 + 2.9587301587302*G0_0_0_5_1_1_2_0_1 - 2.9587301587302*G0_0_0_5_1_1_3_1_0 - 2.9587301587302*G0_0_0_5_1_1_3_1_1 + 2.9587301587302*G0_0_0_5_1_1_4_1_0 + 2.9587301587302*G0_0_0_5_1_1_5_1_1 + 1.4793650793651*G0_0_1_0_0_0_0_0_0 + 1.4793650793651*G0_0_1_0_0_0_0_0_1 - 1.4793650793651*G0_0_1_0_0_0_1_0_0 - 1.4793650793651*G0_0_1_0_0_0_2_0_1 + 1.4793650793651*G0_0_1_0_0_0_3_1_0 + 1.4793650793651*G0_0_1_0_0_0_3_1_1 - 1.4793650793651*G0_0_1_0_0_0_4_1_0 - 1.4793650793651*G0_0_1_0_0_0_5_1_1 + 1.4793650793651*G0_0_1_0_0_1_0_0_0 + 1.4793650793651*G0_0_1_0_0_1_0_0_1 - 1.4793650793651*G0_0_1_0_0_1_1_0_0 - 1.4793650793651*G0_0_1_0_0_1_2_0_1 + 1.4793650793651*G0_0_1_0_0_1_3_1_0 + 1.4793650793651*G0_0_1_0_0_1_3_1_1 - 1.4793650793651*G0_0_1_0_0_1_4_1_0 - 1.4793650793651*G0_0_1_0_0_1_5_1_1 - 1.4793650793651*G0_0_1_1_0_0_0_0_0 - 1.4793650793651*G0_0_1_1_0_0_0_0_1 + 1.4793650793651*G0_0_1_1_0_0_1_0_0 + 1.4793650793651*G0_0_1_1_0_0_2_0_1 - 1.4793650793651*G0_0_1_1_0_0_3_1_0 - 1.4793650793651*G0_0_1_1_0_0_3_1_1 + 1.4793650793651*G0_0_1_1_0_0_4_1_0 + 1.4793650793651*G0_0_1_1_0_0_5_1_1 - 1.4793650793651*G0_0_1_2_0_1_0_0_0 - 1.4793650793651*G0_0_1_2_0_1_0_0_1 + 1.4793650793651*G0_0_1_2_0_1_1_0_0 + 1.4793650793651*G0_0_1_2_0_1_2_0_1 - 1.4793650793651*G0_0_1_2_0_1_3_1_0 - 1.4793650793651*G0_0_1_2_0_1_3_1_1 + 1.4793650793651*G0_0_1_2_0_1_4_1_0 + 1.4793650793651*G0_0_1_2_0_1_5_1_1 + 1.4793650793651*G0_0_1_3_1_0_0_0_0 + 1.4793650793651*G0_0_1_3_1_0_0_0_1 - 1.4793650793651*G0_0_1_3_1_0_1_0_0 - 1.4793650793651*G0_0_1_3_1_0_2_0_1 + 1.4793650793651*G0_0_1_3_1_0_3_1_0 + 1.4793650793651*G0_0_1_3_1_0_3_1_1 - 1.4793650793651*G0_0_1_3_1_0_4_1_0 - 1.4793650793651*G0_0_1_3_1_0_5_1_1 + 1.4793650793651*G0_0_1_3_1_1_0_0_0 + 1.4793650793651*G0_0_1_3_1_1_0_0_1 - 1.4793650793651*G0_0_1_3_1_1_1_0_0 - 1.4793650793651*G0_0_1_3_1_1_2_0_1 + 1.4793650793651*G0_0_1_3_1_1_3_1_0 + 1.4793650793651*G0_0_1_3_1_1_3_1_1 - 1.4793650793651*G0_0_1_3_1_1_4_1_0 - 1.4793650793651*G0_0_1_3_1_1_5_1_1 - 1.4793650793651*G0_0_1_4_1_0_0_0_0 - 1.4793650793651*G0_0_1_4_1_0_0_0_1 + 1.4793650793651*G0_0_1_4_1_0_1_0_0 + 1.4793650793651*G0_0_1_4_1_0_2_0_1 - 1.4793650793651*G0_0_1_4_1_0_3_1_0 - 1.4793650793651*G0_0_1_4_1_0_3_1_1 + 1.4793650793651*G0_0_1_4_1_0_4_1_0 + 1.4793650793651*G0_0_1_4_1_0_5_1_1 - 1.4793650793651*G0_0_1_5_1_1_0_0_0 - 1.4793650793651*G0_0_1_5_1_1_0_0_1 + 1.4793650793651*G0_0_1_5_1_1_1_0_0 + 1.4793650793651*G0_0_1_5_1_1_2_0_1 - 1.4793650793651*G0_0_1_5_1_1_3_1_0 - 1.4793650793651*G0_0_1_5_1_1_3_1_1 + 1.4793650793651*G0_0_1_5_1_1_4_1_0 + 1.4793650793651*G0_0_1_5_1_1_5_1_1 + 1.4793650793651*G0_1_0_0_0_0_0_0_0 + 1.4793650793651*G0_1_0_0_0_0_0_0_1 - 1.4793650793651*G0_1_0_0_0_0_1_0_0 - 1.4793650793651*G0_1_0_0_0_0_2_0_1 + 1.4793650793651*G0_1_0_0_0_0_3_1_0 + 1.4793650793651*G0_1_0_0_0_0_3_1_1 - 1.4793650793651*G0_1_0_0_0_0_4_1_0 - 1.4793650793651*G0_1_0_0_0_0_5_1_1 + 1.4793650793651*G0_1_0_0_0_1_0_0_0 + 1.4793650793651*G0_1_0_0_0_1_0_0_1 - 1.4793650793651*G0_1_0_0_0_1_1_0_0 - 1.4793650793651*G0_1_0_0_0_1_2_0_1 + 1.4793650793651*G0_1_0_0_0_1_3_1_0 + 1.4793650793651*G0_1_0_0_0_1_3_1_1 - 1.4793650793651*G0_1_0_0_0_1_4_1_0 - 1.4793650793651*G0_1_0_0_0_1_5_1_1 - 1.4793650793651*G0_1_0_1_0_0_0_0_0 - 1.4793650793651*G0_1_0_1_0_0_0_0_1 + 1.4793650793651*G0_1_0_1_0_0_1_0_0 + 1.4793650793651*G0_1_0_1_0_0_2_0_1 - 1.4793650793651*G0_1_0_1_0_0_3_1_0 - 1.4793650793651*G0_1_0_1_0_0_3_1_1 + 1.4793650793651*G0_1_0_1_0_0_4_1_0 + 1.4793650793651*G0_1_0_1_0_0_5_1_1 - 1.4793650793651*G0_1_0_2_0_1_0_0_0 - 1.4793650793651*G0_1_0_2_0_1_0_0_1 + 1.4793650793651*G0_1_0_2_0_1_1_0_0 + 1.4793650793651*G0_1_0_2_0_1_2_0_1 - 1.4793650793651*G0_1_0_2_0_1_3_1_0 - 1.4793650793651*G0_1_0_2_0_1_3_1_1 + 1.4793650793651*G0_1_0_2_0_1_4_1_0 + 1.4793650793651*G0_1_0_2_0_1_5_1_1 + 1.4793650793651*G0_1_0_3_1_0_0_0_0 + 1.4793650793651*G0_1_0_3_1_0_0_0_1 - 1.4793650793651*G0_1_0_3_1_0_1_0_0 - 1.4793650793651*G0_1_0_3_1_0_2_0_1 + 1.4793650793651*G0_1_0_3_1_0_3_1_0 + 1.4793650793651*G0_1_0_3_1_0_3_1_1 - 1.4793650793651*G0_1_0_3_1_0_4_1_0 - 1.4793650793651*G0_1_0_3_1_0_5_1_1 + 1.4793650793651*G0_1_0_3_1_1_0_0_0 + 1.4793650793651*G0_1_0_3_1_1_0_0_1 - 1.4793650793651*G0_1_0_3_1_1_1_0_0 - 1.4793650793651*G0_1_0_3_1_1_2_0_1 + 1.4793650793651*G0_1_0_3_1_1_3_1_0 + 1.4793650793651*G0_1_0_3_1_1_3_1_1 - 1.4793650793651*G0_1_0_3_1_1_4_1_0 - 1.4793650793651*G0_1_0_3_1_1_5_1_1 - 1.4793650793651*G0_1_0_4_1_0_0_0_0 - 1.4793650793651*G0_1_0_4_1_0_0_0_1 + 1.4793650793651*G0_1_0_4_1_0_1_0_0 + 1.4793650793651*G0_1_0_4_1_0_2_0_1 - 1.4793650793651*G0_1_0_4_1_0_3_1_0 - 1.4793650793651*G0_1_0_4_1_0_3_1_1 + 1.4793650793651*G0_1_0_4_1_0_4_1_0 + 1.4793650793651*G0_1_0_4_1_0_5_1_1 - 1.4793650793651*G0_1_0_5_1_1_0_0_0 - 1.4793650793651*G0_1_0_5_1_1_0_0_1 + 1.4793650793651*G0_1_0_5_1_1_1_0_0 + 1.4793650793651*G0_1_0_5_1_1_2_0_1 - 1.4793650793651*G0_1_0_5_1_1_3_1_0 - 1.4793650793651*G0_1_0_5_1_1_3_1_1 + 1.4793650793651*G0_1_0_5_1_1_4_1_0 + 1.4793650793651*G0_1_0_5_1_1_5_1_1 + 2.45079365079369*G0_1_1_0_0_0_0_0_0 + 2.45079365079369*G0_1_1_0_0_0_0_0_1 - 2.45079365079369*G0_1_1_0_0_0_1_0_0 - 2.45079365079369*G0_1_1_0_0_0_2_0_1 + 2.45079365079369*G0_1_1_0_0_0_3_1_0 + 2.45079365079369*G0_1_1_0_0_0_3_1_1 - 2.45079365079369*G0_1_1_0_0_0_4_1_0 - 2.45079365079369*G0_1_1_0_0_0_5_1_1 + 2.45079365079369*G0_1_1_0_0_1_0_0_0 + 2.45079365079369*G0_1_1_0_0_1_0_0_1 - 2.45079365079369*G0_1_1_0_0_1_1_0_0 - 2.45079365079369*G0_1_1_0_0_1_2_0_1 + 2.45079365079369*G0_1_1_0_0_1_3_1_0 + 2.45079365079369*G0_1_1_0_0_1_3_1_1 - 2.45079365079369*G0_1_1_0_0_1_4_1_0 - 2.45079365079369*G0_1_1_0_0_1_5_1_1 - 2.45079365079369*G0_1_1_1_0_0_0_0_0 - 2.45079365079369*G0_1_1_1_0_0_0_0_1 + 2.45079365079369*G0_1_1_1_0_0_1_0_0 + 2.45079365079369*G0_1_1_1_0_0_2_0_1 - 2.45079365079369*G0_1_1_1_0_0_3_1_0 - 2.45079365079369*G0_1_1_1_0_0_3_1_1 + 2.45079365079369*G0_1_1_1_0_0_4_1_0 + 2.45079365079369*G0_1_1_1_0_0_5_1_1 - 2.45079365079369*G0_1_1_2_0_1_0_0_0 - 2.45079365079369*G0_1_1_2_0_1_0_0_1 + 2.45079365079369*G0_1_1_2_0_1_1_0_0 + 2.45079365079369*G0_1_1_2_0_1_2_0_1 - 2.45079365079369*G0_1_1_2_0_1_3_1_0 - 2.45079365079369*G0_1_1_2_0_1_3_1_1 + 2.45079365079369*G0_1_1_2_0_1_4_1_0 + 2.45079365079369*G0_1_1_2_0_1_5_1_1 + 2.45079365079369*G0_1_1_3_1_0_0_0_0 + 2.45079365079369*G0_1_1_3_1_0_0_0_1 - 2.45079365079369*G0_1_1_3_1_0_1_0_0 - 2.45079365079369*G0_1_1_3_1_0_2_0_1 + 2.45079365079369*G0_1_1_3_1_0_3_1_0 + 2.45079365079369*G0_1_1_3_1_0_3_1_1 - 2.45079365079369*G0_1_1_3_1_0_4_1_0 - 2.45079365079369*G0_1_1_3_1_0_5_1_1 + 2.45079365079369*G0_1_1_3_1_1_0_0_0 + 2.45079365079369*G0_1_1_3_1_1_0_0_1 - 2.45079365079369*G0_1_1_3_1_1_1_0_0 - 2.45079365079369*G0_1_1_3_1_1_2_0_1 + 2.45079365079369*G0_1_1_3_1_1_3_1_0 + 2.45079365079369*G0_1_1_3_1_1_3_1_1 - 2.45079365079369*G0_1_1_3_1_1_4_1_0 - 2.45079365079369*G0_1_1_3_1_1_5_1_1 - 2.45079365079369*G0_1_1_4_1_0_0_0_0 - 2.45079365079369*G0_1_1_4_1_0_0_0_1 + 2.45079365079369*G0_1_1_4_1_0_1_0_0 + 2.45079365079369*G0_1_1_4_1_0_2_0_1 - 2.45079365079369*G0_1_1_4_1_0_3_1_0 - 2.45079365079369*G0_1_1_4_1_0_3_1_1 + 2.45079365079369*G0_1_1_4_1_0_4_1_0 + 2.45079365079369*G0_1_1_4_1_0_5_1_1 - 2.45079365079369*G0_1_1_5_1_1_0_0_0 - 2.45079365079369*G0_1_1_5_1_1_0_0_1 + 2.45079365079369*G0_1_1_5_1_1_1_0_0 + 2.45079365079369*G0_1_1_5_1_1_2_0_1 - 2.45079365079369*G0_1_1_5_1_1_3_1_0 - 2.45079365079369*G0_1_1_5_1_1_3_1_1 + 2.45079365079369*G0_1_1_5_1_1_4_1_0 + 2.45079365079369*G0_1_1_5_1_1_5_1_1; + A[460] = 0.0; + A[356] = 0.0; + A[5] = -A[213] - 0.110052910052919*G0_0_0_0_0_0_0_0_0 - 0.110052910052919*G0_0_0_0_0_0_0_0_1 + 0.110052910052919*G0_0_0_0_0_0_1_0_0 + 0.110052910052919*G0_0_0_0_0_0_2_0_1 - 0.110052910052919*G0_0_0_0_0_0_3_1_0 - 0.110052910052919*G0_0_0_0_0_0_3_1_1 + 0.110052910052919*G0_0_0_0_0_0_4_1_0 + 0.110052910052919*G0_0_0_0_0_0_5_1_1 - 0.110052910052919*G0_0_0_0_0_1_0_0_0 - 0.110052910052919*G0_0_0_0_0_1_0_0_1 + 0.110052910052919*G0_0_0_0_0_1_1_0_0 + 0.110052910052919*G0_0_0_0_0_1_2_0_1 - 0.110052910052919*G0_0_0_0_0_1_3_1_0 - 0.110052910052919*G0_0_0_0_0_1_3_1_1 + 0.110052910052919*G0_0_0_0_0_1_4_1_0 + 0.110052910052919*G0_0_0_0_0_1_5_1_1 + 0.110052910052919*G0_0_0_1_0_0_0_0_0 + 0.110052910052919*G0_0_0_1_0_0_0_0_1 - 0.110052910052919*G0_0_0_1_0_0_1_0_0 - 0.110052910052919*G0_0_0_1_0_0_2_0_1 + 0.110052910052919*G0_0_0_1_0_0_3_1_0 + 0.110052910052919*G0_0_0_1_0_0_3_1_1 - 0.110052910052919*G0_0_0_1_0_0_4_1_0 - 0.110052910052919*G0_0_0_1_0_0_5_1_1 + 0.110052910052919*G0_0_0_2_0_1_0_0_0 + 0.110052910052919*G0_0_0_2_0_1_0_0_1 - 0.110052910052919*G0_0_0_2_0_1_1_0_0 - 0.110052910052919*G0_0_0_2_0_1_2_0_1 + 0.110052910052919*G0_0_0_2_0_1_3_1_0 + 0.110052910052919*G0_0_0_2_0_1_3_1_1 - 0.110052910052919*G0_0_0_2_0_1_4_1_0 - 0.110052910052919*G0_0_0_2_0_1_5_1_1 - 0.110052910052919*G0_0_0_3_1_0_0_0_0 - 0.110052910052919*G0_0_0_3_1_0_0_0_1 + 0.110052910052919*G0_0_0_3_1_0_1_0_0 + 0.110052910052919*G0_0_0_3_1_0_2_0_1 - 0.110052910052919*G0_0_0_3_1_0_3_1_0 - 0.110052910052919*G0_0_0_3_1_0_3_1_1 + 0.110052910052919*G0_0_0_3_1_0_4_1_0 + 0.110052910052919*G0_0_0_3_1_0_5_1_1 - 0.110052910052919*G0_0_0_3_1_1_0_0_0 - 0.110052910052919*G0_0_0_3_1_1_0_0_1 + 0.110052910052919*G0_0_0_3_1_1_1_0_0 + 0.110052910052919*G0_0_0_3_1_1_2_0_1 - 0.110052910052919*G0_0_0_3_1_1_3_1_0 - 0.110052910052919*G0_0_0_3_1_1_3_1_1 + 0.110052910052919*G0_0_0_3_1_1_4_1_0 + 0.110052910052919*G0_0_0_3_1_1_5_1_1 + 0.110052910052919*G0_0_0_4_1_0_0_0_0 + 0.110052910052919*G0_0_0_4_1_0_0_0_1 - 0.110052910052919*G0_0_0_4_1_0_1_0_0 - 0.110052910052919*G0_0_0_4_1_0_2_0_1 + 0.110052910052919*G0_0_0_4_1_0_3_1_0 + 0.110052910052919*G0_0_0_4_1_0_3_1_1 - 0.110052910052919*G0_0_0_4_1_0_4_1_0 - 0.110052910052919*G0_0_0_4_1_0_5_1_1 + 0.110052910052919*G0_0_0_5_1_1_0_0_0 + 0.110052910052919*G0_0_0_5_1_1_0_0_1 - 0.110052910052919*G0_0_0_5_1_1_1_0_0 - 0.110052910052919*G0_0_0_5_1_1_2_0_1 + 0.110052910052919*G0_0_0_5_1_1_3_1_0 + 0.110052910052919*G0_0_0_5_1_1_3_1_1 - 0.110052910052919*G0_0_0_5_1_1_4_1_0 - 0.110052910052919*G0_0_0_5_1_1_5_1_1 + 0.0423280423280432*G0_1_1_0_0_0_0_0_0 + 0.0423280423280432*G0_1_1_0_0_0_0_0_1 - 0.0423280423280432*G0_1_1_0_0_0_1_0_0 - 0.0423280423280432*G0_1_1_0_0_0_2_0_1 + 0.0423280423280432*G0_1_1_0_0_0_3_1_0 + 0.0423280423280432*G0_1_1_0_0_0_3_1_1 - 0.0423280423280432*G0_1_1_0_0_0_4_1_0 - 0.0423280423280432*G0_1_1_0_0_0_5_1_1 + 0.0423280423280432*G0_1_1_0_0_1_0_0_0 + 0.0423280423280432*G0_1_1_0_0_1_0_0_1 - 0.0423280423280432*G0_1_1_0_0_1_1_0_0 - 0.0423280423280432*G0_1_1_0_0_1_2_0_1 + 0.0423280423280432*G0_1_1_0_0_1_3_1_0 + 0.0423280423280432*G0_1_1_0_0_1_3_1_1 - 0.0423280423280432*G0_1_1_0_0_1_4_1_0 - 0.0423280423280432*G0_1_1_0_0_1_5_1_1 - 0.0423280423280432*G0_1_1_1_0_0_0_0_0 - 0.0423280423280432*G0_1_1_1_0_0_0_0_1 + 0.0423280423280432*G0_1_1_1_0_0_1_0_0 + 0.0423280423280432*G0_1_1_1_0_0_2_0_1 - 0.0423280423280432*G0_1_1_1_0_0_3_1_0 - 0.0423280423280432*G0_1_1_1_0_0_3_1_1 + 0.0423280423280432*G0_1_1_1_0_0_4_1_0 + 0.0423280423280432*G0_1_1_1_0_0_5_1_1 - 0.0423280423280432*G0_1_1_2_0_1_0_0_0 - 0.0423280423280432*G0_1_1_2_0_1_0_0_1 + 0.0423280423280432*G0_1_1_2_0_1_1_0_0 + 0.0423280423280432*G0_1_1_2_0_1_2_0_1 - 0.0423280423280432*G0_1_1_2_0_1_3_1_0 - 0.0423280423280432*G0_1_1_2_0_1_3_1_1 + 0.0423280423280432*G0_1_1_2_0_1_4_1_0 + 0.0423280423280432*G0_1_1_2_0_1_5_1_1 + 0.0423280423280432*G0_1_1_3_1_0_0_0_0 + 0.0423280423280432*G0_1_1_3_1_0_0_0_1 - 0.0423280423280432*G0_1_1_3_1_0_1_0_0 - 0.0423280423280432*G0_1_1_3_1_0_2_0_1 + 0.0423280423280432*G0_1_1_3_1_0_3_1_0 + 0.0423280423280432*G0_1_1_3_1_0_3_1_1 - 0.0423280423280432*G0_1_1_3_1_0_4_1_0 - 0.0423280423280432*G0_1_1_3_1_0_5_1_1 + 0.0423280423280432*G0_1_1_3_1_1_0_0_0 + 0.0423280423280432*G0_1_1_3_1_1_0_0_1 - 0.0423280423280432*G0_1_1_3_1_1_1_0_0 - 0.0423280423280432*G0_1_1_3_1_1_2_0_1 + 0.0423280423280432*G0_1_1_3_1_1_3_1_0 + 0.0423280423280432*G0_1_1_3_1_1_3_1_1 - 0.0423280423280432*G0_1_1_3_1_1_4_1_0 - 0.0423280423280432*G0_1_1_3_1_1_5_1_1 - 0.0423280423280432*G0_1_1_4_1_0_0_0_0 - 0.0423280423280432*G0_1_1_4_1_0_0_0_1 + 0.0423280423280432*G0_1_1_4_1_0_1_0_0 + 0.0423280423280432*G0_1_1_4_1_0_2_0_1 - 0.0423280423280432*G0_1_1_4_1_0_3_1_0 - 0.0423280423280432*G0_1_1_4_1_0_3_1_1 + 0.0423280423280432*G0_1_1_4_1_0_4_1_0 + 0.0423280423280432*G0_1_1_4_1_0_5_1_1 - 0.0423280423280432*G0_1_1_5_1_1_0_0_0 - 0.0423280423280432*G0_1_1_5_1_1_0_0_1 + 0.0423280423280432*G0_1_1_5_1_1_1_0_0 + 0.0423280423280432*G0_1_1_5_1_1_2_0_1 - 0.0423280423280432*G0_1_1_5_1_1_3_1_0 - 0.0423280423280432*G0_1_1_5_1_1_3_1_1 + 0.0423280423280432*G0_1_1_5_1_1_4_1_0 + 0.0423280423280432*G0_1_1_5_1_1_5_1_1; + A[765] = A[5] + 0.42539682539683*G0_0_0_0_0_0_0_0_0 + 0.42539682539683*G0_0_0_0_0_0_0_0_1 - 0.42539682539683*G0_0_0_0_0_0_1_0_0 - 0.42539682539683*G0_0_0_0_0_0_2_0_1 + 0.42539682539683*G0_0_0_0_0_0_3_1_0 + 0.42539682539683*G0_0_0_0_0_0_3_1_1 - 0.42539682539683*G0_0_0_0_0_0_4_1_0 - 0.42539682539683*G0_0_0_0_0_0_5_1_1 + 0.42539682539683*G0_0_0_0_0_1_0_0_0 + 0.42539682539683*G0_0_0_0_0_1_0_0_1 - 0.42539682539683*G0_0_0_0_0_1_1_0_0 - 0.42539682539683*G0_0_0_0_0_1_2_0_1 + 0.42539682539683*G0_0_0_0_0_1_3_1_0 + 0.42539682539683*G0_0_0_0_0_1_3_1_1 - 0.42539682539683*G0_0_0_0_0_1_4_1_0 - 0.42539682539683*G0_0_0_0_0_1_5_1_1 - 0.42539682539683*G0_0_0_1_0_0_0_0_0 - 0.42539682539683*G0_0_0_1_0_0_0_0_1 + 0.42539682539683*G0_0_0_1_0_0_1_0_0 + 0.42539682539683*G0_0_0_1_0_0_2_0_1 - 0.42539682539683*G0_0_0_1_0_0_3_1_0 - 0.42539682539683*G0_0_0_1_0_0_3_1_1 + 0.42539682539683*G0_0_0_1_0_0_4_1_0 + 0.42539682539683*G0_0_0_1_0_0_5_1_1 - 0.42539682539683*G0_0_0_2_0_1_0_0_0 - 0.42539682539683*G0_0_0_2_0_1_0_0_1 + 0.42539682539683*G0_0_0_2_0_1_1_0_0 + 0.42539682539683*G0_0_0_2_0_1_2_0_1 - 0.42539682539683*G0_0_0_2_0_1_3_1_0 - 0.42539682539683*G0_0_0_2_0_1_3_1_1 + 0.42539682539683*G0_0_0_2_0_1_4_1_0 + 0.42539682539683*G0_0_0_2_0_1_5_1_1 + 0.42539682539683*G0_0_0_3_1_0_0_0_0 + 0.42539682539683*G0_0_0_3_1_0_0_0_1 - 0.42539682539683*G0_0_0_3_1_0_1_0_0 - 0.42539682539683*G0_0_0_3_1_0_2_0_1 + 0.42539682539683*G0_0_0_3_1_0_3_1_0 + 0.42539682539683*G0_0_0_3_1_0_3_1_1 - 0.42539682539683*G0_0_0_3_1_0_4_1_0 - 0.42539682539683*G0_0_0_3_1_0_5_1_1 + 0.42539682539683*G0_0_0_3_1_1_0_0_0 + 0.42539682539683*G0_0_0_3_1_1_0_0_1 - 0.42539682539683*G0_0_0_3_1_1_1_0_0 - 0.42539682539683*G0_0_0_3_1_1_2_0_1 + 0.42539682539683*G0_0_0_3_1_1_3_1_0 + 0.42539682539683*G0_0_0_3_1_1_3_1_1 - 0.42539682539683*G0_0_0_3_1_1_4_1_0 - 0.42539682539683*G0_0_0_3_1_1_5_1_1 - 0.42539682539683*G0_0_0_4_1_0_0_0_0 - 0.42539682539683*G0_0_0_4_1_0_0_0_1 + 0.42539682539683*G0_0_0_4_1_0_1_0_0 + 0.42539682539683*G0_0_0_4_1_0_2_0_1 - 0.42539682539683*G0_0_0_4_1_0_3_1_0 - 0.42539682539683*G0_0_0_4_1_0_3_1_1 + 0.42539682539683*G0_0_0_4_1_0_4_1_0 + 0.42539682539683*G0_0_0_4_1_0_5_1_1 - 0.42539682539683*G0_0_0_5_1_1_0_0_0 - 0.42539682539683*G0_0_0_5_1_1_0_0_1 + 0.42539682539683*G0_0_0_5_1_1_1_0_0 + 0.42539682539683*G0_0_0_5_1_1_2_0_1 - 0.42539682539683*G0_0_0_5_1_1_3_1_0 - 0.42539682539683*G0_0_0_5_1_1_3_1_1 + 0.42539682539683*G0_0_0_5_1_1_4_1_0 + 0.42539682539683*G0_0_0_5_1_1_5_1_1 + 0.425396825396828*G0_0_1_0_0_0_0_0_0 + 0.425396825396828*G0_0_1_0_0_0_0_0_1 - 0.425396825396828*G0_0_1_0_0_0_1_0_0 - 0.425396825396828*G0_0_1_0_0_0_2_0_1 + 0.425396825396828*G0_0_1_0_0_0_3_1_0 + 0.425396825396828*G0_0_1_0_0_0_3_1_1 - 0.425396825396828*G0_0_1_0_0_0_4_1_0 - 0.425396825396828*G0_0_1_0_0_0_5_1_1 + 0.425396825396828*G0_0_1_0_0_1_0_0_0 + 0.425396825396828*G0_0_1_0_0_1_0_0_1 - 0.425396825396828*G0_0_1_0_0_1_1_0_0 - 0.425396825396828*G0_0_1_0_0_1_2_0_1 + 0.425396825396828*G0_0_1_0_0_1_3_1_0 + 0.425396825396828*G0_0_1_0_0_1_3_1_1 - 0.425396825396828*G0_0_1_0_0_1_4_1_0 - 0.425396825396828*G0_0_1_0_0_1_5_1_1 - 0.425396825396828*G0_0_1_1_0_0_0_0_0 - 0.425396825396828*G0_0_1_1_0_0_0_0_1 + 0.425396825396828*G0_0_1_1_0_0_1_0_0 + 0.425396825396828*G0_0_1_1_0_0_2_0_1 - 0.425396825396828*G0_0_1_1_0_0_3_1_0 - 0.425396825396828*G0_0_1_1_0_0_3_1_1 + 0.425396825396828*G0_0_1_1_0_0_4_1_0 + 0.425396825396828*G0_0_1_1_0_0_5_1_1 - 0.425396825396828*G0_0_1_2_0_1_0_0_0 - 0.425396825396828*G0_0_1_2_0_1_0_0_1 + 0.425396825396828*G0_0_1_2_0_1_1_0_0 + 0.425396825396828*G0_0_1_2_0_1_2_0_1 - 0.425396825396828*G0_0_1_2_0_1_3_1_0 - 0.425396825396828*G0_0_1_2_0_1_3_1_1 + 0.425396825396828*G0_0_1_2_0_1_4_1_0 + 0.425396825396828*G0_0_1_2_0_1_5_1_1 + 0.425396825396828*G0_0_1_3_1_0_0_0_0 + 0.425396825396828*G0_0_1_3_1_0_0_0_1 - 0.425396825396828*G0_0_1_3_1_0_1_0_0 - 0.425396825396828*G0_0_1_3_1_0_2_0_1 + 0.425396825396828*G0_0_1_3_1_0_3_1_0 + 0.425396825396828*G0_0_1_3_1_0_3_1_1 - 0.425396825396828*G0_0_1_3_1_0_4_1_0 - 0.425396825396828*G0_0_1_3_1_0_5_1_1 + 0.425396825396828*G0_0_1_3_1_1_0_0_0 + 0.425396825396828*G0_0_1_3_1_1_0_0_1 - 0.425396825396828*G0_0_1_3_1_1_1_0_0 - 0.425396825396828*G0_0_1_3_1_1_2_0_1 + 0.425396825396828*G0_0_1_3_1_1_3_1_0 + 0.425396825396828*G0_0_1_3_1_1_3_1_1 - 0.425396825396828*G0_0_1_3_1_1_4_1_0 - 0.425396825396828*G0_0_1_3_1_1_5_1_1 - 0.425396825396828*G0_0_1_4_1_0_0_0_0 - 0.425396825396828*G0_0_1_4_1_0_0_0_1 + 0.425396825396828*G0_0_1_4_1_0_1_0_0 + 0.425396825396828*G0_0_1_4_1_0_2_0_1 - 0.425396825396828*G0_0_1_4_1_0_3_1_0 - 0.425396825396828*G0_0_1_4_1_0_3_1_1 + 0.425396825396828*G0_0_1_4_1_0_4_1_0 + 0.425396825396828*G0_0_1_4_1_0_5_1_1 - 0.425396825396828*G0_0_1_5_1_1_0_0_0 - 0.425396825396828*G0_0_1_5_1_1_0_0_1 + 0.425396825396828*G0_0_1_5_1_1_1_0_0 + 0.425396825396828*G0_0_1_5_1_1_2_0_1 - 0.425396825396828*G0_0_1_5_1_1_3_1_0 - 0.425396825396828*G0_0_1_5_1_1_3_1_1 + 0.425396825396828*G0_0_1_5_1_1_4_1_0 + 0.425396825396828*G0_0_1_5_1_1_5_1_1; + A[14] = -2.00000000000004*A[5]; + A[722] = 0.0; + A[389] = 0.0; + A[753] = 0.0; + A[160] = A[625]; + A[899] = A[403]; + A[112] = 0.0; + A[181] = -0.499999999999998*A[421]; + A[151] = -A[181] + 0.203174603174606*G0_1_0_0_0_0_0_0_0 + 0.203174603174606*G0_1_0_0_0_0_0_0_1 - 0.203174603174606*G0_1_0_0_0_0_1_0_0 - 0.203174603174606*G0_1_0_0_0_0_2_0_1 + 0.203174603174606*G0_1_0_0_0_0_3_1_0 + 0.203174603174606*G0_1_0_0_0_0_3_1_1 - 0.203174603174606*G0_1_0_0_0_0_4_1_0 - 0.203174603174606*G0_1_0_0_0_0_5_1_1 + 0.203174603174606*G0_1_0_0_0_1_0_0_0 + 0.203174603174606*G0_1_0_0_0_1_0_0_1 - 0.203174603174606*G0_1_0_0_0_1_1_0_0 - 0.203174603174606*G0_1_0_0_0_1_2_0_1 + 0.203174603174606*G0_1_0_0_0_1_3_1_0 + 0.203174603174606*G0_1_0_0_0_1_3_1_1 - 0.203174603174606*G0_1_0_0_0_1_4_1_0 - 0.203174603174606*G0_1_0_0_0_1_5_1_1 - 0.203174603174606*G0_1_0_1_0_0_0_0_0 - 0.203174603174606*G0_1_0_1_0_0_0_0_1 + 0.203174603174606*G0_1_0_1_0_0_1_0_0 + 0.203174603174606*G0_1_0_1_0_0_2_0_1 - 0.203174603174606*G0_1_0_1_0_0_3_1_0 - 0.203174603174606*G0_1_0_1_0_0_3_1_1 + 0.203174603174606*G0_1_0_1_0_0_4_1_0 + 0.203174603174606*G0_1_0_1_0_0_5_1_1 - 0.203174603174606*G0_1_0_2_0_1_0_0_0 - 0.203174603174606*G0_1_0_2_0_1_0_0_1 + 0.203174603174606*G0_1_0_2_0_1_1_0_0 + 0.203174603174606*G0_1_0_2_0_1_2_0_1 - 0.203174603174606*G0_1_0_2_0_1_3_1_0 - 0.203174603174606*G0_1_0_2_0_1_3_1_1 + 0.203174603174606*G0_1_0_2_0_1_4_1_0 + 0.203174603174606*G0_1_0_2_0_1_5_1_1 + 0.203174603174606*G0_1_0_3_1_0_0_0_0 + 0.203174603174606*G0_1_0_3_1_0_0_0_1 - 0.203174603174606*G0_1_0_3_1_0_1_0_0 - 0.203174603174606*G0_1_0_3_1_0_2_0_1 + 0.203174603174606*G0_1_0_3_1_0_3_1_0 + 0.203174603174606*G0_1_0_3_1_0_3_1_1 - 0.203174603174606*G0_1_0_3_1_0_4_1_0 - 0.203174603174606*G0_1_0_3_1_0_5_1_1 + 0.203174603174606*G0_1_0_3_1_1_0_0_0 + 0.203174603174606*G0_1_0_3_1_1_0_0_1 - 0.203174603174606*G0_1_0_3_1_1_1_0_0 - 0.203174603174606*G0_1_0_3_1_1_2_0_1 + 0.203174603174606*G0_1_0_3_1_1_3_1_0 + 0.203174603174606*G0_1_0_3_1_1_3_1_1 - 0.203174603174606*G0_1_0_3_1_1_4_1_0 - 0.203174603174606*G0_1_0_3_1_1_5_1_1 - 0.203174603174606*G0_1_0_4_1_0_0_0_0 - 0.203174603174606*G0_1_0_4_1_0_0_0_1 + 0.203174603174606*G0_1_0_4_1_0_1_0_0 + 0.203174603174606*G0_1_0_4_1_0_2_0_1 - 0.203174603174606*G0_1_0_4_1_0_3_1_0 - 0.203174603174606*G0_1_0_4_1_0_3_1_1 + 0.203174603174606*G0_1_0_4_1_0_4_1_0 + 0.203174603174606*G0_1_0_4_1_0_5_1_1 - 0.203174603174606*G0_1_0_5_1_1_0_0_0 - 0.203174603174606*G0_1_0_5_1_1_0_0_1 + 0.203174603174606*G0_1_0_5_1_1_1_0_0 + 0.203174603174606*G0_1_0_5_1_1_2_0_1 - 0.203174603174606*G0_1_0_5_1_1_3_1_0 - 0.203174603174606*G0_1_0_5_1_1_3_1_1 + 0.203174603174606*G0_1_0_5_1_1_4_1_0 + 0.203174603174606*G0_1_0_5_1_1_5_1_1; + A[137] = 0.0; + A[214] = A[679]; + A[170] = 0.0; + A[500] = -A[181] + 0.203174603174605*G0_0_1_0_0_0_0_0_0 + 0.203174603174605*G0_0_1_0_0_0_0_0_1 - 0.203174603174605*G0_0_1_0_0_0_1_0_0 - 0.203174603174605*G0_0_1_0_0_0_2_0_1 + 0.203174603174605*G0_0_1_0_0_0_3_1_0 + 0.203174603174605*G0_0_1_0_0_0_3_1_1 - 0.203174603174605*G0_0_1_0_0_0_4_1_0 - 0.203174603174605*G0_0_1_0_0_0_5_1_1 + 0.203174603174605*G0_0_1_0_0_1_0_0_0 + 0.203174603174605*G0_0_1_0_0_1_0_0_1 - 0.203174603174605*G0_0_1_0_0_1_1_0_0 - 0.203174603174605*G0_0_1_0_0_1_2_0_1 + 0.203174603174605*G0_0_1_0_0_1_3_1_0 + 0.203174603174605*G0_0_1_0_0_1_3_1_1 - 0.203174603174605*G0_0_1_0_0_1_4_1_0 - 0.203174603174605*G0_0_1_0_0_1_5_1_1 - 0.203174603174605*G0_0_1_1_0_0_0_0_0 - 0.203174603174605*G0_0_1_1_0_0_0_0_1 + 0.203174603174605*G0_0_1_1_0_0_1_0_0 + 0.203174603174605*G0_0_1_1_0_0_2_0_1 - 0.203174603174605*G0_0_1_1_0_0_3_1_0 - 0.203174603174605*G0_0_1_1_0_0_3_1_1 + 0.203174603174605*G0_0_1_1_0_0_4_1_0 + 0.203174603174605*G0_0_1_1_0_0_5_1_1 - 0.203174603174605*G0_0_1_2_0_1_0_0_0 - 0.203174603174605*G0_0_1_2_0_1_0_0_1 + 0.203174603174605*G0_0_1_2_0_1_1_0_0 + 0.203174603174605*G0_0_1_2_0_1_2_0_1 - 0.203174603174605*G0_0_1_2_0_1_3_1_0 - 0.203174603174605*G0_0_1_2_0_1_3_1_1 + 0.203174603174605*G0_0_1_2_0_1_4_1_0 + 0.203174603174605*G0_0_1_2_0_1_5_1_1 + 0.203174603174605*G0_0_1_3_1_0_0_0_0 + 0.203174603174605*G0_0_1_3_1_0_0_0_1 - 0.203174603174605*G0_0_1_3_1_0_1_0_0 - 0.203174603174605*G0_0_1_3_1_0_2_0_1 + 0.203174603174605*G0_0_1_3_1_0_3_1_0 + 0.203174603174605*G0_0_1_3_1_0_3_1_1 - 0.203174603174605*G0_0_1_3_1_0_4_1_0 - 0.203174603174605*G0_0_1_3_1_0_5_1_1 + 0.203174603174605*G0_0_1_3_1_1_0_0_0 + 0.203174603174605*G0_0_1_3_1_1_0_0_1 - 0.203174603174605*G0_0_1_3_1_1_1_0_0 - 0.203174603174605*G0_0_1_3_1_1_2_0_1 + 0.203174603174605*G0_0_1_3_1_1_3_1_0 + 0.203174603174605*G0_0_1_3_1_1_3_1_1 - 0.203174603174605*G0_0_1_3_1_1_4_1_0 - 0.203174603174605*G0_0_1_3_1_1_5_1_1 - 0.203174603174605*G0_0_1_4_1_0_0_0_0 - 0.203174603174605*G0_0_1_4_1_0_0_0_1 + 0.203174603174605*G0_0_1_4_1_0_1_0_0 + 0.203174603174605*G0_0_1_4_1_0_2_0_1 - 0.203174603174605*G0_0_1_4_1_0_3_1_0 - 0.203174603174605*G0_0_1_4_1_0_3_1_1 + 0.203174603174605*G0_0_1_4_1_0_4_1_0 + 0.203174603174605*G0_0_1_4_1_0_5_1_1 - 0.203174603174605*G0_0_1_5_1_1_0_0_0 - 0.203174603174605*G0_0_1_5_1_1_0_0_1 + 0.203174603174605*G0_0_1_5_1_1_1_0_0 + 0.203174603174605*G0_0_1_5_1_1_2_0_1 - 0.203174603174605*G0_0_1_5_1_1_3_1_0 - 0.203174603174605*G0_0_1_5_1_1_3_1_1 + 0.203174603174605*G0_0_1_5_1_1_4_1_0 + 0.203174603174605*G0_0_1_5_1_1_5_1_1; + A[207] = 0.0; + A[647] = -A[92] - 0.287830687830693*G0_1_1_0_0_0_0_0_0 - 0.287830687830693*G0_1_1_0_0_0_0_0_1 + 0.287830687830693*G0_1_1_0_0_0_1_0_0 + 0.287830687830693*G0_1_1_0_0_0_2_0_1 - 0.287830687830693*G0_1_1_0_0_0_3_1_0 - 0.287830687830693*G0_1_1_0_0_0_3_1_1 + 0.287830687830693*G0_1_1_0_0_0_4_1_0 + 0.287830687830693*G0_1_1_0_0_0_5_1_1 - 0.287830687830693*G0_1_1_0_0_1_0_0_0 - 0.287830687830693*G0_1_1_0_0_1_0_0_1 + 0.287830687830693*G0_1_1_0_0_1_1_0_0 + 0.287830687830693*G0_1_1_0_0_1_2_0_1 - 0.287830687830693*G0_1_1_0_0_1_3_1_0 - 0.287830687830693*G0_1_1_0_0_1_3_1_1 + 0.287830687830693*G0_1_1_0_0_1_4_1_0 + 0.287830687830693*G0_1_1_0_0_1_5_1_1 + 0.287830687830693*G0_1_1_1_0_0_0_0_0 + 0.287830687830693*G0_1_1_1_0_0_0_0_1 - 0.287830687830693*G0_1_1_1_0_0_1_0_0 - 0.287830687830693*G0_1_1_1_0_0_2_0_1 + 0.287830687830693*G0_1_1_1_0_0_3_1_0 + 0.287830687830693*G0_1_1_1_0_0_3_1_1 - 0.287830687830693*G0_1_1_1_0_0_4_1_0 - 0.287830687830693*G0_1_1_1_0_0_5_1_1 + 0.287830687830693*G0_1_1_2_0_1_0_0_0 + 0.287830687830693*G0_1_1_2_0_1_0_0_1 - 0.287830687830693*G0_1_1_2_0_1_1_0_0 - 0.287830687830693*G0_1_1_2_0_1_2_0_1 + 0.287830687830693*G0_1_1_2_0_1_3_1_0 + 0.287830687830693*G0_1_1_2_0_1_3_1_1 - 0.287830687830693*G0_1_1_2_0_1_4_1_0 - 0.287830687830693*G0_1_1_2_0_1_5_1_1 - 0.287830687830693*G0_1_1_3_1_0_0_0_0 - 0.287830687830693*G0_1_1_3_1_0_0_0_1 + 0.287830687830693*G0_1_1_3_1_0_1_0_0 + 0.287830687830693*G0_1_1_3_1_0_2_0_1 - 0.287830687830693*G0_1_1_3_1_0_3_1_0 - 0.287830687830693*G0_1_1_3_1_0_3_1_1 + 0.287830687830693*G0_1_1_3_1_0_4_1_0 + 0.287830687830693*G0_1_1_3_1_0_5_1_1 - 0.287830687830693*G0_1_1_3_1_1_0_0_0 - 0.287830687830693*G0_1_1_3_1_1_0_0_1 + 0.287830687830693*G0_1_1_3_1_1_1_0_0 + 0.287830687830693*G0_1_1_3_1_1_2_0_1 - 0.287830687830693*G0_1_1_3_1_1_3_1_0 - 0.287830687830693*G0_1_1_3_1_1_3_1_1 + 0.287830687830693*G0_1_1_3_1_1_4_1_0 + 0.287830687830693*G0_1_1_3_1_1_5_1_1 + 0.287830687830693*G0_1_1_4_1_0_0_0_0 + 0.287830687830693*G0_1_1_4_1_0_0_0_1 - 0.287830687830693*G0_1_1_4_1_0_1_0_0 - 0.287830687830693*G0_1_1_4_1_0_2_0_1 + 0.287830687830693*G0_1_1_4_1_0_3_1_0 + 0.287830687830693*G0_1_1_4_1_0_3_1_1 - 0.287830687830693*G0_1_1_4_1_0_4_1_0 - 0.287830687830693*G0_1_1_4_1_0_5_1_1 + 0.287830687830693*G0_1_1_5_1_1_0_0_0 + 0.287830687830693*G0_1_1_5_1_1_0_0_1 - 0.287830687830693*G0_1_1_5_1_1_1_0_0 - 0.287830687830693*G0_1_1_5_1_1_2_0_1 + 0.287830687830693*G0_1_1_5_1_1_3_1_0 + 0.287830687830693*G0_1_1_5_1_1_3_1_1 - 0.287830687830693*G0_1_1_5_1_1_4_1_0 - 0.287830687830693*G0_1_1_5_1_1_5_1_1; + A[571] = 0.0; + A[527] = -4.4062500000001*A[887]; + A[562] = A[213]; + A[240] = -A[5] - 0.203174603174604*G0_1_0_0_0_0_0_0_0 - 0.203174603174604*G0_1_0_0_0_0_0_0_1 + 0.203174603174604*G0_1_0_0_0_0_1_0_0 + 0.203174603174604*G0_1_0_0_0_0_2_0_1 - 0.203174603174604*G0_1_0_0_0_0_3_1_0 - 0.203174603174604*G0_1_0_0_0_0_3_1_1 + 0.203174603174604*G0_1_0_0_0_0_4_1_0 + 0.203174603174604*G0_1_0_0_0_0_5_1_1 - 0.203174603174604*G0_1_0_0_0_1_0_0_0 - 0.203174603174604*G0_1_0_0_0_1_0_0_1 + 0.203174603174604*G0_1_0_0_0_1_1_0_0 + 0.203174603174604*G0_1_0_0_0_1_2_0_1 - 0.203174603174604*G0_1_0_0_0_1_3_1_0 - 0.203174603174604*G0_1_0_0_0_1_3_1_1 + 0.203174603174604*G0_1_0_0_0_1_4_1_0 + 0.203174603174604*G0_1_0_0_0_1_5_1_1 + 0.203174603174604*G0_1_0_1_0_0_0_0_0 + 0.203174603174604*G0_1_0_1_0_0_0_0_1 - 0.203174603174604*G0_1_0_1_0_0_1_0_0 - 0.203174603174604*G0_1_0_1_0_0_2_0_1 + 0.203174603174604*G0_1_0_1_0_0_3_1_0 + 0.203174603174604*G0_1_0_1_0_0_3_1_1 - 0.203174603174604*G0_1_0_1_0_0_4_1_0 - 0.203174603174604*G0_1_0_1_0_0_5_1_1 + 0.203174603174604*G0_1_0_2_0_1_0_0_0 + 0.203174603174604*G0_1_0_2_0_1_0_0_1 - 0.203174603174604*G0_1_0_2_0_1_1_0_0 - 0.203174603174604*G0_1_0_2_0_1_2_0_1 + 0.203174603174604*G0_1_0_2_0_1_3_1_0 + 0.203174603174604*G0_1_0_2_0_1_3_1_1 - 0.203174603174604*G0_1_0_2_0_1_4_1_0 - 0.203174603174604*G0_1_0_2_0_1_5_1_1 - 0.203174603174604*G0_1_0_3_1_0_0_0_0 - 0.203174603174604*G0_1_0_3_1_0_0_0_1 + 0.203174603174604*G0_1_0_3_1_0_1_0_0 + 0.203174603174604*G0_1_0_3_1_0_2_0_1 - 0.203174603174604*G0_1_0_3_1_0_3_1_0 - 0.203174603174604*G0_1_0_3_1_0_3_1_1 + 0.203174603174604*G0_1_0_3_1_0_4_1_0 + 0.203174603174604*G0_1_0_3_1_0_5_1_1 - 0.203174603174604*G0_1_0_3_1_1_0_0_0 - 0.203174603174604*G0_1_0_3_1_1_0_0_1 + 0.203174603174604*G0_1_0_3_1_1_1_0_0 + 0.203174603174604*G0_1_0_3_1_1_2_0_1 - 0.203174603174604*G0_1_0_3_1_1_3_1_0 - 0.203174603174604*G0_1_0_3_1_1_3_1_1 + 0.203174603174604*G0_1_0_3_1_1_4_1_0 + 0.203174603174604*G0_1_0_3_1_1_5_1_1 + 0.203174603174604*G0_1_0_4_1_0_0_0_0 + 0.203174603174604*G0_1_0_4_1_0_0_0_1 - 0.203174603174604*G0_1_0_4_1_0_1_0_0 - 0.203174603174604*G0_1_0_4_1_0_2_0_1 + 0.203174603174604*G0_1_0_4_1_0_3_1_0 + 0.203174603174604*G0_1_0_4_1_0_3_1_1 - 0.203174603174604*G0_1_0_4_1_0_4_1_0 - 0.203174603174604*G0_1_0_4_1_0_5_1_1 + 0.203174603174604*G0_1_0_5_1_1_0_0_0 + 0.203174603174604*G0_1_0_5_1_1_0_0_1 - 0.203174603174604*G0_1_0_5_1_1_1_0_0 - 0.203174603174604*G0_1_0_5_1_1_2_0_1 + 0.203174603174604*G0_1_0_5_1_1_3_1_0 + 0.203174603174604*G0_1_0_5_1_1_3_1_1 - 0.203174603174604*G0_1_0_5_1_1_4_1_0 - 0.203174603174604*G0_1_0_5_1_1_5_1_1 - 0.203174603174604*G0_1_1_0_0_0_0_0_0 - 0.203174603174604*G0_1_1_0_0_0_0_0_1 + 0.203174603174604*G0_1_1_0_0_0_1_0_0 + 0.203174603174604*G0_1_1_0_0_0_2_0_1 - 0.203174603174604*G0_1_1_0_0_0_3_1_0 - 0.203174603174604*G0_1_1_0_0_0_3_1_1 + 0.203174603174604*G0_1_1_0_0_0_4_1_0 + 0.203174603174604*G0_1_1_0_0_0_5_1_1 - 0.203174603174604*G0_1_1_0_0_1_0_0_0 - 0.203174603174604*G0_1_1_0_0_1_0_0_1 + 0.203174603174604*G0_1_1_0_0_1_1_0_0 + 0.203174603174604*G0_1_1_0_0_1_2_0_1 - 0.203174603174604*G0_1_1_0_0_1_3_1_0 - 0.203174603174604*G0_1_1_0_0_1_3_1_1 + 0.203174603174604*G0_1_1_0_0_1_4_1_0 + 0.203174603174604*G0_1_1_0_0_1_5_1_1 + 0.203174603174604*G0_1_1_1_0_0_0_0_0 + 0.203174603174604*G0_1_1_1_0_0_0_0_1 - 0.203174603174604*G0_1_1_1_0_0_1_0_0 - 0.203174603174604*G0_1_1_1_0_0_2_0_1 + 0.203174603174604*G0_1_1_1_0_0_3_1_0 + 0.203174603174604*G0_1_1_1_0_0_3_1_1 - 0.203174603174604*G0_1_1_1_0_0_4_1_0 - 0.203174603174604*G0_1_1_1_0_0_5_1_1 + 0.203174603174604*G0_1_1_2_0_1_0_0_0 + 0.203174603174604*G0_1_1_2_0_1_0_0_1 - 0.203174603174604*G0_1_1_2_0_1_1_0_0 - 0.203174603174604*G0_1_1_2_0_1_2_0_1 + 0.203174603174604*G0_1_1_2_0_1_3_1_0 + 0.203174603174604*G0_1_1_2_0_1_3_1_1 - 0.203174603174604*G0_1_1_2_0_1_4_1_0 - 0.203174603174604*G0_1_1_2_0_1_5_1_1 - 0.203174603174604*G0_1_1_3_1_0_0_0_0 - 0.203174603174604*G0_1_1_3_1_0_0_0_1 + 0.203174603174604*G0_1_1_3_1_0_1_0_0 + 0.203174603174604*G0_1_1_3_1_0_2_0_1 - 0.203174603174604*G0_1_1_3_1_0_3_1_0 - 0.203174603174604*G0_1_1_3_1_0_3_1_1 + 0.203174603174604*G0_1_1_3_1_0_4_1_0 + 0.203174603174604*G0_1_1_3_1_0_5_1_1 - 0.203174603174604*G0_1_1_3_1_1_0_0_0 - 0.203174603174604*G0_1_1_3_1_1_0_0_1 + 0.203174603174604*G0_1_1_3_1_1_1_0_0 + 0.203174603174604*G0_1_1_3_1_1_2_0_1 - 0.203174603174604*G0_1_1_3_1_1_3_1_0 - 0.203174603174604*G0_1_1_3_1_1_3_1_1 + 0.203174603174604*G0_1_1_3_1_1_4_1_0 + 0.203174603174604*G0_1_1_3_1_1_5_1_1 + 0.203174603174604*G0_1_1_4_1_0_0_0_0 + 0.203174603174604*G0_1_1_4_1_0_0_0_1 - 0.203174603174604*G0_1_1_4_1_0_1_0_0 - 0.203174603174604*G0_1_1_4_1_0_2_0_1 + 0.203174603174604*G0_1_1_4_1_0_3_1_0 + 0.203174603174604*G0_1_1_4_1_0_3_1_1 - 0.203174603174604*G0_1_1_4_1_0_4_1_0 - 0.203174603174604*G0_1_1_4_1_0_5_1_1 + 0.203174603174604*G0_1_1_5_1_1_0_0_0 + 0.203174603174604*G0_1_1_5_1_1_0_0_1 - 0.203174603174604*G0_1_1_5_1_1_1_0_0 - 0.203174603174604*G0_1_1_5_1_1_2_0_1 + 0.203174603174604*G0_1_1_5_1_1_3_1_0 + 0.203174603174604*G0_1_1_5_1_1_3_1_1 - 0.203174603174604*G0_1_1_5_1_1_4_1_0 - 0.203174603174604*G0_1_1_5_1_1_5_1_1; + A[299] = 0.0; + A[446] = 0.0; + A[326] = 0.0; + A[469] = A[5]; + A[349] = 0.0; + A[28] = 0.0; + A[729] = 0.0; + A[380] = 0.0; + A[55] = 0.0; + A[754] = 0.0; + A[415] = 0.0; + A[783] = 0.0; + A[820] = 0.0; + A[144] = 0.0; + A[853] = 0.0; + A[179] = 0.0; + A[491] = 0.0; + A[198] = 0.0; + A[656] = A[716] - 0.135449735449742*G0_0_0_0_0_0_0_0_0 - 0.135449735449742*G0_0_0_0_0_0_0_0_1 + 0.135449735449742*G0_0_0_0_0_0_1_0_0 + 0.135449735449742*G0_0_0_0_0_0_2_0_1 - 0.135449735449742*G0_0_0_0_0_0_3_1_0 - 0.135449735449742*G0_0_0_0_0_0_3_1_1 + 0.135449735449742*G0_0_0_0_0_0_4_1_0 + 0.135449735449742*G0_0_0_0_0_0_5_1_1 - 0.135449735449742*G0_0_0_0_0_1_0_0_0 - 0.135449735449742*G0_0_0_0_0_1_0_0_1 + 0.135449735449742*G0_0_0_0_0_1_1_0_0 + 0.135449735449742*G0_0_0_0_0_1_2_0_1 - 0.135449735449742*G0_0_0_0_0_1_3_1_0 - 0.135449735449742*G0_0_0_0_0_1_3_1_1 + 0.135449735449742*G0_0_0_0_0_1_4_1_0 + 0.135449735449742*G0_0_0_0_0_1_5_1_1 + 0.135449735449742*G0_0_0_1_0_0_0_0_0 + 0.135449735449742*G0_0_0_1_0_0_0_0_1 - 0.135449735449742*G0_0_0_1_0_0_1_0_0 - 0.135449735449742*G0_0_0_1_0_0_2_0_1 + 0.135449735449742*G0_0_0_1_0_0_3_1_0 + 0.135449735449742*G0_0_0_1_0_0_3_1_1 - 0.135449735449742*G0_0_0_1_0_0_4_1_0 - 0.135449735449742*G0_0_0_1_0_0_5_1_1 + 0.135449735449742*G0_0_0_2_0_1_0_0_0 + 0.135449735449742*G0_0_0_2_0_1_0_0_1 - 0.135449735449742*G0_0_0_2_0_1_1_0_0 - 0.135449735449742*G0_0_0_2_0_1_2_0_1 + 0.135449735449742*G0_0_0_2_0_1_3_1_0 + 0.135449735449742*G0_0_0_2_0_1_3_1_1 - 0.135449735449742*G0_0_0_2_0_1_4_1_0 - 0.135449735449742*G0_0_0_2_0_1_5_1_1 - 0.135449735449742*G0_0_0_3_1_0_0_0_0 - 0.135449735449742*G0_0_0_3_1_0_0_0_1 + 0.135449735449742*G0_0_0_3_1_0_1_0_0 + 0.135449735449742*G0_0_0_3_1_0_2_0_1 - 0.135449735449742*G0_0_0_3_1_0_3_1_0 - 0.135449735449742*G0_0_0_3_1_0_3_1_1 + 0.135449735449742*G0_0_0_3_1_0_4_1_0 + 0.135449735449742*G0_0_0_3_1_0_5_1_1 - 0.135449735449742*G0_0_0_3_1_1_0_0_0 - 0.135449735449742*G0_0_0_3_1_1_0_0_1 + 0.135449735449742*G0_0_0_3_1_1_1_0_0 + 0.135449735449742*G0_0_0_3_1_1_2_0_1 - 0.135449735449742*G0_0_0_3_1_1_3_1_0 - 0.135449735449742*G0_0_0_3_1_1_3_1_1 + 0.135449735449742*G0_0_0_3_1_1_4_1_0 + 0.135449735449742*G0_0_0_3_1_1_5_1_1 + 0.135449735449742*G0_0_0_4_1_0_0_0_0 + 0.135449735449742*G0_0_0_4_1_0_0_0_1 - 0.135449735449742*G0_0_0_4_1_0_1_0_0 - 0.135449735449742*G0_0_0_4_1_0_2_0_1 + 0.135449735449742*G0_0_0_4_1_0_3_1_0 + 0.135449735449742*G0_0_0_4_1_0_3_1_1 - 0.135449735449742*G0_0_0_4_1_0_4_1_0 - 0.135449735449742*G0_0_0_4_1_0_5_1_1 + 0.135449735449742*G0_0_0_5_1_1_0_0_0 + 0.135449735449742*G0_0_0_5_1_1_0_0_1 - 0.135449735449742*G0_0_0_5_1_1_1_0_0 - 0.135449735449742*G0_0_0_5_1_1_2_0_1 + 0.135449735449742*G0_0_0_5_1_1_3_1_0 + 0.135449735449742*G0_0_0_5_1_1_3_1_1 - 0.135449735449742*G0_0_0_5_1_1_4_1_0 - 0.135449735449742*G0_0_0_5_1_1_5_1_1; + A[741] = A[656] + 0.812698412698418*G0_0_1_0_0_0_0_0_0 + 0.812698412698418*G0_0_1_0_0_0_0_0_1 - 0.812698412698418*G0_0_1_0_0_0_1_0_0 - 0.812698412698418*G0_0_1_0_0_0_2_0_1 + 0.812698412698418*G0_0_1_0_0_0_3_1_0 + 0.812698412698418*G0_0_1_0_0_0_3_1_1 - 0.812698412698418*G0_0_1_0_0_0_4_1_0 - 0.812698412698418*G0_0_1_0_0_0_5_1_1 + 0.812698412698418*G0_0_1_0_0_1_0_0_0 + 0.812698412698418*G0_0_1_0_0_1_0_0_1 - 0.812698412698418*G0_0_1_0_0_1_1_0_0 - 0.812698412698418*G0_0_1_0_0_1_2_0_1 + 0.812698412698418*G0_0_1_0_0_1_3_1_0 + 0.812698412698418*G0_0_1_0_0_1_3_1_1 - 0.812698412698418*G0_0_1_0_0_1_4_1_0 - 0.812698412698418*G0_0_1_0_0_1_5_1_1 - 0.812698412698418*G0_0_1_1_0_0_0_0_0 - 0.812698412698418*G0_0_1_1_0_0_0_0_1 + 0.812698412698418*G0_0_1_1_0_0_1_0_0 + 0.812698412698418*G0_0_1_1_0_0_2_0_1 - 0.812698412698418*G0_0_1_1_0_0_3_1_0 - 0.812698412698418*G0_0_1_1_0_0_3_1_1 + 0.812698412698418*G0_0_1_1_0_0_4_1_0 + 0.812698412698418*G0_0_1_1_0_0_5_1_1 - 0.812698412698418*G0_0_1_2_0_1_0_0_0 - 0.812698412698418*G0_0_1_2_0_1_0_0_1 + 0.812698412698418*G0_0_1_2_0_1_1_0_0 + 0.812698412698418*G0_0_1_2_0_1_2_0_1 - 0.812698412698418*G0_0_1_2_0_1_3_1_0 - 0.812698412698418*G0_0_1_2_0_1_3_1_1 + 0.812698412698418*G0_0_1_2_0_1_4_1_0 + 0.812698412698418*G0_0_1_2_0_1_5_1_1 + 0.812698412698418*G0_0_1_3_1_0_0_0_0 + 0.812698412698418*G0_0_1_3_1_0_0_0_1 - 0.812698412698418*G0_0_1_3_1_0_1_0_0 - 0.812698412698418*G0_0_1_3_1_0_2_0_1 + 0.812698412698418*G0_0_1_3_1_0_3_1_0 + 0.812698412698418*G0_0_1_3_1_0_3_1_1 - 0.812698412698418*G0_0_1_3_1_0_4_1_0 - 0.812698412698418*G0_0_1_3_1_0_5_1_1 + 0.812698412698418*G0_0_1_3_1_1_0_0_0 + 0.812698412698418*G0_0_1_3_1_1_0_0_1 - 0.812698412698418*G0_0_1_3_1_1_1_0_0 - 0.812698412698418*G0_0_1_3_1_1_2_0_1 + 0.812698412698418*G0_0_1_3_1_1_3_1_0 + 0.812698412698418*G0_0_1_3_1_1_3_1_1 - 0.812698412698418*G0_0_1_3_1_1_4_1_0 - 0.812698412698418*G0_0_1_3_1_1_5_1_1 - 0.812698412698418*G0_0_1_4_1_0_0_0_0 - 0.812698412698418*G0_0_1_4_1_0_0_0_1 + 0.812698412698418*G0_0_1_4_1_0_1_0_0 + 0.812698412698418*G0_0_1_4_1_0_2_0_1 - 0.812698412698418*G0_0_1_4_1_0_3_1_0 - 0.812698412698418*G0_0_1_4_1_0_3_1_1 + 0.812698412698418*G0_0_1_4_1_0_4_1_0 + 0.812698412698418*G0_0_1_4_1_0_5_1_1 - 0.812698412698418*G0_0_1_5_1_1_0_0_0 - 0.812698412698418*G0_0_1_5_1_1_0_0_1 + 0.812698412698418*G0_0_1_5_1_1_1_0_0 + 0.812698412698418*G0_0_1_5_1_1_2_0_1 - 0.812698412698418*G0_0_1_5_1_1_3_1_0 - 0.812698412698418*G0_0_1_5_1_1_3_1_1 + 0.812698412698418*G0_0_1_5_1_1_4_1_0 + 0.812698412698418*G0_0_1_5_1_1_5_1_1 + 0.812698412698418*G0_1_0_0_0_0_0_0_0 + 0.812698412698418*G0_1_0_0_0_0_0_0_1 - 0.812698412698418*G0_1_0_0_0_0_1_0_0 - 0.812698412698418*G0_1_0_0_0_0_2_0_1 + 0.812698412698418*G0_1_0_0_0_0_3_1_0 + 0.812698412698418*G0_1_0_0_0_0_3_1_1 - 0.812698412698418*G0_1_0_0_0_0_4_1_0 - 0.812698412698418*G0_1_0_0_0_0_5_1_1 + 0.812698412698418*G0_1_0_0_0_1_0_0_0 + 0.812698412698418*G0_1_0_0_0_1_0_0_1 - 0.812698412698418*G0_1_0_0_0_1_1_0_0 - 0.812698412698418*G0_1_0_0_0_1_2_0_1 + 0.812698412698418*G0_1_0_0_0_1_3_1_0 + 0.812698412698418*G0_1_0_0_0_1_3_1_1 - 0.812698412698418*G0_1_0_0_0_1_4_1_0 - 0.812698412698418*G0_1_0_0_0_1_5_1_1 - 0.812698412698418*G0_1_0_1_0_0_0_0_0 - 0.812698412698418*G0_1_0_1_0_0_0_0_1 + 0.812698412698418*G0_1_0_1_0_0_1_0_0 + 0.812698412698418*G0_1_0_1_0_0_2_0_1 - 0.812698412698418*G0_1_0_1_0_0_3_1_0 - 0.812698412698418*G0_1_0_1_0_0_3_1_1 + 0.812698412698418*G0_1_0_1_0_0_4_1_0 + 0.812698412698418*G0_1_0_1_0_0_5_1_1 - 0.812698412698418*G0_1_0_2_0_1_0_0_0 - 0.812698412698418*G0_1_0_2_0_1_0_0_1 + 0.812698412698418*G0_1_0_2_0_1_1_0_0 + 0.812698412698418*G0_1_0_2_0_1_2_0_1 - 0.812698412698418*G0_1_0_2_0_1_3_1_0 - 0.812698412698418*G0_1_0_2_0_1_3_1_1 + 0.812698412698418*G0_1_0_2_0_1_4_1_0 + 0.812698412698418*G0_1_0_2_0_1_5_1_1 + 0.812698412698418*G0_1_0_3_1_0_0_0_0 + 0.812698412698418*G0_1_0_3_1_0_0_0_1 - 0.812698412698418*G0_1_0_3_1_0_1_0_0 - 0.812698412698418*G0_1_0_3_1_0_2_0_1 + 0.812698412698418*G0_1_0_3_1_0_3_1_0 + 0.812698412698418*G0_1_0_3_1_0_3_1_1 - 0.812698412698418*G0_1_0_3_1_0_4_1_0 - 0.812698412698418*G0_1_0_3_1_0_5_1_1 + 0.812698412698418*G0_1_0_3_1_1_0_0_0 + 0.812698412698418*G0_1_0_3_1_1_0_0_1 - 0.812698412698418*G0_1_0_3_1_1_1_0_0 - 0.812698412698418*G0_1_0_3_1_1_2_0_1 + 0.812698412698418*G0_1_0_3_1_1_3_1_0 + 0.812698412698418*G0_1_0_3_1_1_3_1_1 - 0.812698412698418*G0_1_0_3_1_1_4_1_0 - 0.812698412698418*G0_1_0_3_1_1_5_1_1 - 0.812698412698418*G0_1_0_4_1_0_0_0_0 - 0.812698412698418*G0_1_0_4_1_0_0_0_1 + 0.812698412698418*G0_1_0_4_1_0_1_0_0 + 0.812698412698418*G0_1_0_4_1_0_2_0_1 - 0.812698412698418*G0_1_0_4_1_0_3_1_0 - 0.812698412698418*G0_1_0_4_1_0_3_1_1 + 0.812698412698418*G0_1_0_4_1_0_4_1_0 + 0.812698412698418*G0_1_0_4_1_0_5_1_1 - 0.812698412698418*G0_1_0_5_1_1_0_0_0 - 0.812698412698418*G0_1_0_5_1_1_0_0_1 + 0.812698412698418*G0_1_0_5_1_1_1_0_0 + 0.812698412698418*G0_1_0_5_1_1_2_0_1 - 0.812698412698418*G0_1_0_5_1_1_3_1_0 - 0.812698412698418*G0_1_0_5_1_1_3_1_1 + 0.812698412698418*G0_1_0_5_1_1_4_1_0 + 0.812698412698418*G0_1_0_5_1_1_5_1_1 - 0.13544973544974*G0_1_1_0_0_0_0_0_0 - 0.13544973544974*G0_1_1_0_0_0_0_0_1 + 0.13544973544974*G0_1_1_0_0_0_1_0_0 + 0.13544973544974*G0_1_1_0_0_0_2_0_1 - 0.13544973544974*G0_1_1_0_0_0_3_1_0 - 0.13544973544974*G0_1_1_0_0_0_3_1_1 + 0.13544973544974*G0_1_1_0_0_0_4_1_0 + 0.13544973544974*G0_1_1_0_0_0_5_1_1 - 0.13544973544974*G0_1_1_0_0_1_0_0_0 - 0.13544973544974*G0_1_1_0_0_1_0_0_1 + 0.13544973544974*G0_1_1_0_0_1_1_0_0 + 0.13544973544974*G0_1_1_0_0_1_2_0_1 - 0.13544973544974*G0_1_1_0_0_1_3_1_0 - 0.13544973544974*G0_1_1_0_0_1_3_1_1 + 0.13544973544974*G0_1_1_0_0_1_4_1_0 + 0.13544973544974*G0_1_1_0_0_1_5_1_1 + 0.13544973544974*G0_1_1_1_0_0_0_0_0 + 0.13544973544974*G0_1_1_1_0_0_0_0_1 - 0.13544973544974*G0_1_1_1_0_0_1_0_0 - 0.13544973544974*G0_1_1_1_0_0_2_0_1 + 0.13544973544974*G0_1_1_1_0_0_3_1_0 + 0.13544973544974*G0_1_1_1_0_0_3_1_1 - 0.13544973544974*G0_1_1_1_0_0_4_1_0 - 0.13544973544974*G0_1_1_1_0_0_5_1_1 + 0.13544973544974*G0_1_1_2_0_1_0_0_0 + 0.13544973544974*G0_1_1_2_0_1_0_0_1 - 0.13544973544974*G0_1_1_2_0_1_1_0_0 - 0.13544973544974*G0_1_1_2_0_1_2_0_1 + 0.13544973544974*G0_1_1_2_0_1_3_1_0 + 0.13544973544974*G0_1_1_2_0_1_3_1_1 - 0.13544973544974*G0_1_1_2_0_1_4_1_0 - 0.13544973544974*G0_1_1_2_0_1_5_1_1 - 0.13544973544974*G0_1_1_3_1_0_0_0_0 - 0.13544973544974*G0_1_1_3_1_0_0_0_1 + 0.13544973544974*G0_1_1_3_1_0_1_0_0 + 0.13544973544974*G0_1_1_3_1_0_2_0_1 - 0.13544973544974*G0_1_1_3_1_0_3_1_0 - 0.13544973544974*G0_1_1_3_1_0_3_1_1 + 0.13544973544974*G0_1_1_3_1_0_4_1_0 + 0.13544973544974*G0_1_1_3_1_0_5_1_1 - 0.13544973544974*G0_1_1_3_1_1_0_0_0 - 0.13544973544974*G0_1_1_3_1_1_0_0_1 + 0.13544973544974*G0_1_1_3_1_1_1_0_0 + 0.13544973544974*G0_1_1_3_1_1_2_0_1 - 0.13544973544974*G0_1_1_3_1_1_3_1_0 - 0.13544973544974*G0_1_1_3_1_1_3_1_1 + 0.13544973544974*G0_1_1_3_1_1_4_1_0 + 0.13544973544974*G0_1_1_3_1_1_5_1_1 + 0.13544973544974*G0_1_1_4_1_0_0_0_0 + 0.13544973544974*G0_1_1_4_1_0_0_0_1 - 0.13544973544974*G0_1_1_4_1_0_1_0_0 - 0.13544973544974*G0_1_1_4_1_0_2_0_1 + 0.13544973544974*G0_1_1_4_1_0_3_1_0 + 0.13544973544974*G0_1_1_4_1_0_3_1_1 - 0.13544973544974*G0_1_1_4_1_0_4_1_0 - 0.13544973544974*G0_1_1_4_1_0_5_1_1 + 0.13544973544974*G0_1_1_5_1_1_0_0_0 + 0.13544973544974*G0_1_1_5_1_1_0_0_1 - 0.13544973544974*G0_1_1_5_1_1_1_0_0 - 0.13544973544974*G0_1_1_5_1_1_2_0_1 + 0.13544973544974*G0_1_1_5_1_1_3_1_0 + 0.13544973544974*G0_1_1_5_1_1_3_1_1 - 0.13544973544974*G0_1_1_5_1_1_4_1_0 - 0.13544973544974*G0_1_1_5_1_1_5_1_1; + A[576] = 0.0; + A[520] = 0.0; + A[237] = 0.0; + A[601] = 0.0; + A[557] = A[92]; + A[634] = 0.0; + A[671] = 0.0; + A[276] = A[741]; + A[449] = 0.0; + A[305] = A[625]; + A[474] = A[270] + 0.778835978835986*G0_0_1_0_0_0_0_0_0 + 0.778835978835986*G0_0_1_0_0_0_0_0_1 - 0.778835978835986*G0_0_1_0_0_0_1_0_0 - 0.778835978835986*G0_0_1_0_0_0_2_0_1 + 0.778835978835986*G0_0_1_0_0_0_3_1_0 + 0.778835978835986*G0_0_1_0_0_0_3_1_1 - 0.778835978835986*G0_0_1_0_0_0_4_1_0 - 0.778835978835986*G0_0_1_0_0_0_5_1_1 + 0.778835978835986*G0_0_1_0_0_1_0_0_0 + 0.778835978835986*G0_0_1_0_0_1_0_0_1 - 0.778835978835986*G0_0_1_0_0_1_1_0_0 - 0.778835978835986*G0_0_1_0_0_1_2_0_1 + 0.778835978835986*G0_0_1_0_0_1_3_1_0 + 0.778835978835986*G0_0_1_0_0_1_3_1_1 - 0.778835978835986*G0_0_1_0_0_1_4_1_0 - 0.778835978835986*G0_0_1_0_0_1_5_1_1 - 0.778835978835986*G0_0_1_1_0_0_0_0_0 - 0.778835978835986*G0_0_1_1_0_0_0_0_1 + 0.778835978835986*G0_0_1_1_0_0_1_0_0 + 0.778835978835986*G0_0_1_1_0_0_2_0_1 - 0.778835978835986*G0_0_1_1_0_0_3_1_0 - 0.778835978835986*G0_0_1_1_0_0_3_1_1 + 0.778835978835986*G0_0_1_1_0_0_4_1_0 + 0.778835978835986*G0_0_1_1_0_0_5_1_1 - 0.778835978835986*G0_0_1_2_0_1_0_0_0 - 0.778835978835986*G0_0_1_2_0_1_0_0_1 + 0.778835978835986*G0_0_1_2_0_1_1_0_0 + 0.778835978835986*G0_0_1_2_0_1_2_0_1 - 0.778835978835986*G0_0_1_2_0_1_3_1_0 - 0.778835978835986*G0_0_1_2_0_1_3_1_1 + 0.778835978835986*G0_0_1_2_0_1_4_1_0 + 0.778835978835986*G0_0_1_2_0_1_5_1_1 + 0.778835978835986*G0_0_1_3_1_0_0_0_0 + 0.778835978835986*G0_0_1_3_1_0_0_0_1 - 0.778835978835986*G0_0_1_3_1_0_1_0_0 - 0.778835978835986*G0_0_1_3_1_0_2_0_1 + 0.778835978835986*G0_0_1_3_1_0_3_1_0 + 0.778835978835986*G0_0_1_3_1_0_3_1_1 - 0.778835978835986*G0_0_1_3_1_0_4_1_0 - 0.778835978835986*G0_0_1_3_1_0_5_1_1 + 0.778835978835986*G0_0_1_3_1_1_0_0_0 + 0.778835978835986*G0_0_1_3_1_1_0_0_1 - 0.778835978835986*G0_0_1_3_1_1_1_0_0 - 0.778835978835986*G0_0_1_3_1_1_2_0_1 + 0.778835978835986*G0_0_1_3_1_1_3_1_0 + 0.778835978835986*G0_0_1_3_1_1_3_1_1 - 0.778835978835986*G0_0_1_3_1_1_4_1_0 - 0.778835978835986*G0_0_1_3_1_1_5_1_1 - 0.778835978835986*G0_0_1_4_1_0_0_0_0 - 0.778835978835986*G0_0_1_4_1_0_0_0_1 + 0.778835978835986*G0_0_1_4_1_0_1_0_0 + 0.778835978835986*G0_0_1_4_1_0_2_0_1 - 0.778835978835986*G0_0_1_4_1_0_3_1_0 - 0.778835978835986*G0_0_1_4_1_0_3_1_1 + 0.778835978835986*G0_0_1_4_1_0_4_1_0 + 0.778835978835986*G0_0_1_4_1_0_5_1_1 - 0.778835978835986*G0_0_1_5_1_1_0_0_0 - 0.778835978835986*G0_0_1_5_1_1_0_0_1 + 0.778835978835986*G0_0_1_5_1_1_1_0_0 + 0.778835978835986*G0_0_1_5_1_1_2_0_1 - 0.778835978835986*G0_0_1_5_1_1_3_1_0 - 0.778835978835986*G0_0_1_5_1_1_3_1_1 + 0.778835978835986*G0_0_1_5_1_1_4_1_0 + 0.778835978835986*G0_0_1_5_1_1_5_1_1 - 0.778835978835986*G0_1_0_0_0_0_0_0_0 - 0.778835978835986*G0_1_0_0_0_0_0_0_1 + 0.778835978835986*G0_1_0_0_0_0_1_0_0 + 0.778835978835986*G0_1_0_0_0_0_2_0_1 - 0.778835978835986*G0_1_0_0_0_0_3_1_0 - 0.778835978835986*G0_1_0_0_0_0_3_1_1 + 0.778835978835986*G0_1_0_0_0_0_4_1_0 + 0.778835978835986*G0_1_0_0_0_0_5_1_1 - 0.778835978835986*G0_1_0_0_0_1_0_0_0 - 0.778835978835986*G0_1_0_0_0_1_0_0_1 + 0.778835978835986*G0_1_0_0_0_1_1_0_0 + 0.778835978835986*G0_1_0_0_0_1_2_0_1 - 0.778835978835986*G0_1_0_0_0_1_3_1_0 - 0.778835978835986*G0_1_0_0_0_1_3_1_1 + 0.778835978835986*G0_1_0_0_0_1_4_1_0 + 0.778835978835986*G0_1_0_0_0_1_5_1_1 + 0.778835978835986*G0_1_0_1_0_0_0_0_0 + 0.778835978835986*G0_1_0_1_0_0_0_0_1 - 0.778835978835986*G0_1_0_1_0_0_1_0_0 - 0.778835978835986*G0_1_0_1_0_0_2_0_1 + 0.778835978835986*G0_1_0_1_0_0_3_1_0 + 0.778835978835986*G0_1_0_1_0_0_3_1_1 - 0.778835978835986*G0_1_0_1_0_0_4_1_0 - 0.778835978835986*G0_1_0_1_0_0_5_1_1 + 0.778835978835986*G0_1_0_2_0_1_0_0_0 + 0.778835978835986*G0_1_0_2_0_1_0_0_1 - 0.778835978835986*G0_1_0_2_0_1_1_0_0 - 0.778835978835986*G0_1_0_2_0_1_2_0_1 + 0.778835978835986*G0_1_0_2_0_1_3_1_0 + 0.778835978835986*G0_1_0_2_0_1_3_1_1 - 0.778835978835986*G0_1_0_2_0_1_4_1_0 - 0.778835978835986*G0_1_0_2_0_1_5_1_1 - 0.778835978835986*G0_1_0_3_1_0_0_0_0 - 0.778835978835986*G0_1_0_3_1_0_0_0_1 + 0.778835978835986*G0_1_0_3_1_0_1_0_0 + 0.778835978835986*G0_1_0_3_1_0_2_0_1 - 0.778835978835986*G0_1_0_3_1_0_3_1_0 - 0.778835978835986*G0_1_0_3_1_0_3_1_1 + 0.778835978835986*G0_1_0_3_1_0_4_1_0 + 0.778835978835986*G0_1_0_3_1_0_5_1_1 - 0.778835978835986*G0_1_0_3_1_1_0_0_0 - 0.778835978835986*G0_1_0_3_1_1_0_0_1 + 0.778835978835986*G0_1_0_3_1_1_1_0_0 + 0.778835978835986*G0_1_0_3_1_1_2_0_1 - 0.778835978835986*G0_1_0_3_1_1_3_1_0 - 0.778835978835986*G0_1_0_3_1_1_3_1_1 + 0.778835978835986*G0_1_0_3_1_1_4_1_0 + 0.778835978835986*G0_1_0_3_1_1_5_1_1 + 0.778835978835986*G0_1_0_4_1_0_0_0_0 + 0.778835978835986*G0_1_0_4_1_0_0_0_1 - 0.778835978835986*G0_1_0_4_1_0_1_0_0 - 0.778835978835986*G0_1_0_4_1_0_2_0_1 + 0.778835978835986*G0_1_0_4_1_0_3_1_0 + 0.778835978835986*G0_1_0_4_1_0_3_1_1 - 0.778835978835986*G0_1_0_4_1_0_4_1_0 - 0.778835978835986*G0_1_0_4_1_0_5_1_1 + 0.778835978835986*G0_1_0_5_1_1_0_0_0 + 0.778835978835986*G0_1_0_5_1_1_0_0_1 - 0.778835978835986*G0_1_0_5_1_1_1_0_0 - 0.778835978835986*G0_1_0_5_1_1_2_0_1 + 0.778835978835986*G0_1_0_5_1_1_3_1_0 + 0.778835978835986*G0_1_0_5_1_1_3_1_1 - 0.778835978835986*G0_1_0_5_1_1_4_1_0 - 0.778835978835986*G0_1_0_5_1_1_5_1_1; + A[645] = A[474] + 0.778835978835986*G0_0_0_0_0_0_0_0_0 + 0.778835978835986*G0_0_0_0_0_0_0_0_1 - 0.778835978835986*G0_0_0_0_0_0_1_0_0 - 0.778835978835986*G0_0_0_0_0_0_2_0_1 + 0.778835978835986*G0_0_0_0_0_0_3_1_0 + 0.778835978835986*G0_0_0_0_0_0_3_1_1 - 0.778835978835986*G0_0_0_0_0_0_4_1_0 - 0.778835978835986*G0_0_0_0_0_0_5_1_1 + 0.778835978835986*G0_0_0_0_0_1_0_0_0 + 0.778835978835986*G0_0_0_0_0_1_0_0_1 - 0.778835978835986*G0_0_0_0_0_1_1_0_0 - 0.778835978835986*G0_0_0_0_0_1_2_0_1 + 0.778835978835986*G0_0_0_0_0_1_3_1_0 + 0.778835978835986*G0_0_0_0_0_1_3_1_1 - 0.778835978835986*G0_0_0_0_0_1_4_1_0 - 0.778835978835986*G0_0_0_0_0_1_5_1_1 - 0.778835978835986*G0_0_0_1_0_0_0_0_0 - 0.778835978835986*G0_0_0_1_0_0_0_0_1 + 0.778835978835986*G0_0_0_1_0_0_1_0_0 + 0.778835978835986*G0_0_0_1_0_0_2_0_1 - 0.778835978835986*G0_0_0_1_0_0_3_1_0 - 0.778835978835986*G0_0_0_1_0_0_3_1_1 + 0.778835978835986*G0_0_0_1_0_0_4_1_0 + 0.778835978835986*G0_0_0_1_0_0_5_1_1 - 0.778835978835986*G0_0_0_2_0_1_0_0_0 - 0.778835978835986*G0_0_0_2_0_1_0_0_1 + 0.778835978835986*G0_0_0_2_0_1_1_0_0 + 0.778835978835986*G0_0_0_2_0_1_2_0_1 - 0.778835978835986*G0_0_0_2_0_1_3_1_0 - 0.778835978835986*G0_0_0_2_0_1_3_1_1 + 0.778835978835986*G0_0_0_2_0_1_4_1_0 + 0.778835978835986*G0_0_0_2_0_1_5_1_1 + 0.778835978835986*G0_0_0_3_1_0_0_0_0 + 0.778835978835986*G0_0_0_3_1_0_0_0_1 - 0.778835978835986*G0_0_0_3_1_0_1_0_0 - 0.778835978835986*G0_0_0_3_1_0_2_0_1 + 0.778835978835986*G0_0_0_3_1_0_3_1_0 + 0.778835978835986*G0_0_0_3_1_0_3_1_1 - 0.778835978835986*G0_0_0_3_1_0_4_1_0 - 0.778835978835986*G0_0_0_3_1_0_5_1_1 + 0.778835978835986*G0_0_0_3_1_1_0_0_0 + 0.778835978835986*G0_0_0_3_1_1_0_0_1 - 0.778835978835986*G0_0_0_3_1_1_1_0_0 - 0.778835978835986*G0_0_0_3_1_1_2_0_1 + 0.778835978835986*G0_0_0_3_1_1_3_1_0 + 0.778835978835986*G0_0_0_3_1_1_3_1_1 - 0.778835978835986*G0_0_0_3_1_1_4_1_0 - 0.778835978835986*G0_0_0_3_1_1_5_1_1 - 0.778835978835986*G0_0_0_4_1_0_0_0_0 - 0.778835978835986*G0_0_0_4_1_0_0_0_1 + 0.778835978835986*G0_0_0_4_1_0_1_0_0 + 0.778835978835986*G0_0_0_4_1_0_2_0_1 - 0.778835978835986*G0_0_0_4_1_0_3_1_0 - 0.778835978835986*G0_0_0_4_1_0_3_1_1 + 0.778835978835986*G0_0_0_4_1_0_4_1_0 + 0.778835978835986*G0_0_0_4_1_0_5_1_1 - 0.778835978835986*G0_0_0_5_1_1_0_0_0 - 0.778835978835986*G0_0_0_5_1_1_0_0_1 + 0.778835978835986*G0_0_0_5_1_1_1_0_0 + 0.778835978835986*G0_0_0_5_1_1_2_0_1 - 0.778835978835986*G0_0_0_5_1_1_3_1_0 - 0.778835978835986*G0_0_0_5_1_1_3_1_1 + 0.778835978835986*G0_0_0_5_1_1_4_1_0 + 0.778835978835986*G0_0_0_5_1_1_5_1_1 - 0.778835978835986*G0_1_1_0_0_0_0_0_0 - 0.778835978835986*G0_1_1_0_0_0_0_0_1 + 0.778835978835986*G0_1_1_0_0_0_1_0_0 + 0.778835978835986*G0_1_1_0_0_0_2_0_1 - 0.778835978835986*G0_1_1_0_0_0_3_1_0 - 0.778835978835986*G0_1_1_0_0_0_3_1_1 + 0.778835978835986*G0_1_1_0_0_0_4_1_0 + 0.778835978835986*G0_1_1_0_0_0_5_1_1 - 0.778835978835986*G0_1_1_0_0_1_0_0_0 - 0.778835978835986*G0_1_1_0_0_1_0_0_1 + 0.778835978835986*G0_1_1_0_0_1_1_0_0 + 0.778835978835986*G0_1_1_0_0_1_2_0_1 - 0.778835978835986*G0_1_1_0_0_1_3_1_0 - 0.778835978835986*G0_1_1_0_0_1_3_1_1 + 0.778835978835986*G0_1_1_0_0_1_4_1_0 + 0.778835978835986*G0_1_1_0_0_1_5_1_1 + 0.778835978835986*G0_1_1_1_0_0_0_0_0 + 0.778835978835986*G0_1_1_1_0_0_0_0_1 - 0.778835978835986*G0_1_1_1_0_0_1_0_0 - 0.778835978835986*G0_1_1_1_0_0_2_0_1 + 0.778835978835986*G0_1_1_1_0_0_3_1_0 + 0.778835978835986*G0_1_1_1_0_0_3_1_1 - 0.778835978835986*G0_1_1_1_0_0_4_1_0 - 0.778835978835986*G0_1_1_1_0_0_5_1_1 + 0.778835978835986*G0_1_1_2_0_1_0_0_0 + 0.778835978835986*G0_1_1_2_0_1_0_0_1 - 0.778835978835986*G0_1_1_2_0_1_1_0_0 - 0.778835978835986*G0_1_1_2_0_1_2_0_1 + 0.778835978835986*G0_1_1_2_0_1_3_1_0 + 0.778835978835986*G0_1_1_2_0_1_3_1_1 - 0.778835978835986*G0_1_1_2_0_1_4_1_0 - 0.778835978835986*G0_1_1_2_0_1_5_1_1 - 0.778835978835986*G0_1_1_3_1_0_0_0_0 - 0.778835978835986*G0_1_1_3_1_0_0_0_1 + 0.778835978835986*G0_1_1_3_1_0_1_0_0 + 0.778835978835986*G0_1_1_3_1_0_2_0_1 - 0.778835978835986*G0_1_1_3_1_0_3_1_0 - 0.778835978835986*G0_1_1_3_1_0_3_1_1 + 0.778835978835986*G0_1_1_3_1_0_4_1_0 + 0.778835978835986*G0_1_1_3_1_0_5_1_1 - 0.778835978835986*G0_1_1_3_1_1_0_0_0 - 0.778835978835986*G0_1_1_3_1_1_0_0_1 + 0.778835978835986*G0_1_1_3_1_1_1_0_0 + 0.778835978835986*G0_1_1_3_1_1_2_0_1 - 0.778835978835986*G0_1_1_3_1_1_3_1_0 - 0.778835978835986*G0_1_1_3_1_1_3_1_1 + 0.778835978835986*G0_1_1_3_1_1_4_1_0 + 0.778835978835986*G0_1_1_3_1_1_5_1_1 + 0.778835978835986*G0_1_1_4_1_0_0_0_0 + 0.778835978835986*G0_1_1_4_1_0_0_0_1 - 0.778835978835986*G0_1_1_4_1_0_1_0_0 - 0.778835978835986*G0_1_1_4_1_0_2_0_1 + 0.778835978835986*G0_1_1_4_1_0_3_1_0 + 0.778835978835986*G0_1_1_4_1_0_3_1_1 - 0.778835978835986*G0_1_1_4_1_0_4_1_0 - 0.778835978835986*G0_1_1_4_1_0_5_1_1 + 0.778835978835986*G0_1_1_5_1_1_0_0_0 + 0.778835978835986*G0_1_1_5_1_1_0_0_1 - 0.778835978835986*G0_1_1_5_1_1_1_0_0 - 0.778835978835986*G0_1_1_5_1_1_2_0_1 + 0.778835978835986*G0_1_1_5_1_1_3_1_0 + 0.778835978835986*G0_1_1_5_1_1_3_1_1 - 0.778835978835986*G0_1_1_5_1_1_4_1_0 - 0.778835978835986*G0_1_1_5_1_1_5_1_1; + A[338] = A[716]; + A[19] = 0.0; + A[736] = -A[151] - 0.287830687830692*G0_0_0_0_0_0_0_0_0 - 0.287830687830692*G0_0_0_0_0_0_0_0_1 + 0.287830687830692*G0_0_0_0_0_0_1_0_0 + 0.287830687830692*G0_0_0_0_0_0_2_0_1 - 0.287830687830692*G0_0_0_0_0_0_3_1_0 - 0.287830687830692*G0_0_0_0_0_0_3_1_1 + 0.287830687830692*G0_0_0_0_0_0_4_1_0 + 0.287830687830692*G0_0_0_0_0_0_5_1_1 - 0.287830687830692*G0_0_0_0_0_1_0_0_0 - 0.287830687830692*G0_0_0_0_0_1_0_0_1 + 0.287830687830692*G0_0_0_0_0_1_1_0_0 + 0.287830687830692*G0_0_0_0_0_1_2_0_1 - 0.287830687830692*G0_0_0_0_0_1_3_1_0 - 0.287830687830692*G0_0_0_0_0_1_3_1_1 + 0.287830687830692*G0_0_0_0_0_1_4_1_0 + 0.287830687830692*G0_0_0_0_0_1_5_1_1 + 0.287830687830692*G0_0_0_1_0_0_0_0_0 + 0.287830687830692*G0_0_0_1_0_0_0_0_1 - 0.287830687830692*G0_0_0_1_0_0_1_0_0 - 0.287830687830692*G0_0_0_1_0_0_2_0_1 + 0.287830687830692*G0_0_0_1_0_0_3_1_0 + 0.287830687830692*G0_0_0_1_0_0_3_1_1 - 0.287830687830692*G0_0_0_1_0_0_4_1_0 - 0.287830687830692*G0_0_0_1_0_0_5_1_1 + 0.287830687830692*G0_0_0_2_0_1_0_0_0 + 0.287830687830692*G0_0_0_2_0_1_0_0_1 - 0.287830687830692*G0_0_0_2_0_1_1_0_0 - 0.287830687830692*G0_0_0_2_0_1_2_0_1 + 0.287830687830692*G0_0_0_2_0_1_3_1_0 + 0.287830687830692*G0_0_0_2_0_1_3_1_1 - 0.287830687830692*G0_0_0_2_0_1_4_1_0 - 0.287830687830692*G0_0_0_2_0_1_5_1_1 - 0.287830687830692*G0_0_0_3_1_0_0_0_0 - 0.287830687830692*G0_0_0_3_1_0_0_0_1 + 0.287830687830692*G0_0_0_3_1_0_1_0_0 + 0.287830687830692*G0_0_0_3_1_0_2_0_1 - 0.287830687830692*G0_0_0_3_1_0_3_1_0 - 0.287830687830692*G0_0_0_3_1_0_3_1_1 + 0.287830687830692*G0_0_0_3_1_0_4_1_0 + 0.287830687830692*G0_0_0_3_1_0_5_1_1 - 0.287830687830692*G0_0_0_3_1_1_0_0_0 - 0.287830687830692*G0_0_0_3_1_1_0_0_1 + 0.287830687830692*G0_0_0_3_1_1_1_0_0 + 0.287830687830692*G0_0_0_3_1_1_2_0_1 - 0.287830687830692*G0_0_0_3_1_1_3_1_0 - 0.287830687830692*G0_0_0_3_1_1_3_1_1 + 0.287830687830692*G0_0_0_3_1_1_4_1_0 + 0.287830687830692*G0_0_0_3_1_1_5_1_1 + 0.287830687830692*G0_0_0_4_1_0_0_0_0 + 0.287830687830692*G0_0_0_4_1_0_0_0_1 - 0.287830687830692*G0_0_0_4_1_0_1_0_0 - 0.287830687830692*G0_0_0_4_1_0_2_0_1 + 0.287830687830692*G0_0_0_4_1_0_3_1_0 + 0.287830687830692*G0_0_0_4_1_0_3_1_1 - 0.287830687830692*G0_0_0_4_1_0_4_1_0 - 0.287830687830692*G0_0_0_4_1_0_5_1_1 + 0.287830687830692*G0_0_0_5_1_1_0_0_0 + 0.287830687830692*G0_0_0_5_1_1_0_0_1 - 0.287830687830692*G0_0_0_5_1_1_1_0_0 - 0.287830687830692*G0_0_0_5_1_1_2_0_1 + 0.287830687830692*G0_0_0_5_1_1_3_1_0 + 0.287830687830692*G0_0_0_5_1_1_3_1_1 - 0.287830687830692*G0_0_0_5_1_1_4_1_0 - 0.287830687830692*G0_0_0_5_1_1_5_1_1; + A[379] = 0.0; + A[48] = 0.0; + A[763] = 0.0; + A[456] = 0.0; + A[408] = 0.0; + A[85] = 0.0; + A[790] = 0.0; + A[9] = A[474]; + A[813] = 0.0; + A[127] = A[679]; + A[844] = 0.0; + A[879] = 0.0; + A[482] = 0.0; + A[201] = 0.0; + A[585] = A[5]; + A[513] = 0.0; + A[226] = 0.0; + A[608] = 0.0; + A[548] = 0.0; + A[504] = -A[500] - 0.287830687830692*G0_0_0_0_0_0_0_0_0 - 0.287830687830692*G0_0_0_0_0_0_0_0_1 + 0.287830687830692*G0_0_0_0_0_0_1_0_0 + 0.287830687830692*G0_0_0_0_0_0_2_0_1 - 0.287830687830692*G0_0_0_0_0_0_3_1_0 - 0.287830687830692*G0_0_0_0_0_0_3_1_1 + 0.287830687830692*G0_0_0_0_0_0_4_1_0 + 0.287830687830692*G0_0_0_0_0_0_5_1_1 - 0.287830687830692*G0_0_0_0_0_1_0_0_0 - 0.287830687830692*G0_0_0_0_0_1_0_0_1 + 0.287830687830692*G0_0_0_0_0_1_1_0_0 + 0.287830687830692*G0_0_0_0_0_1_2_0_1 - 0.287830687830692*G0_0_0_0_0_1_3_1_0 - 0.287830687830692*G0_0_0_0_0_1_3_1_1 + 0.287830687830692*G0_0_0_0_0_1_4_1_0 + 0.287830687830692*G0_0_0_0_0_1_5_1_1 + 0.287830687830692*G0_0_0_1_0_0_0_0_0 + 0.287830687830692*G0_0_0_1_0_0_0_0_1 - 0.287830687830692*G0_0_0_1_0_0_1_0_0 - 0.287830687830692*G0_0_0_1_0_0_2_0_1 + 0.287830687830692*G0_0_0_1_0_0_3_1_0 + 0.287830687830692*G0_0_0_1_0_0_3_1_1 - 0.287830687830692*G0_0_0_1_0_0_4_1_0 - 0.287830687830692*G0_0_0_1_0_0_5_1_1 + 0.287830687830692*G0_0_0_2_0_1_0_0_0 + 0.287830687830692*G0_0_0_2_0_1_0_0_1 - 0.287830687830692*G0_0_0_2_0_1_1_0_0 - 0.287830687830692*G0_0_0_2_0_1_2_0_1 + 0.287830687830692*G0_0_0_2_0_1_3_1_0 + 0.287830687830692*G0_0_0_2_0_1_3_1_1 - 0.287830687830692*G0_0_0_2_0_1_4_1_0 - 0.287830687830692*G0_0_0_2_0_1_5_1_1 - 0.287830687830692*G0_0_0_3_1_0_0_0_0 - 0.287830687830692*G0_0_0_3_1_0_0_0_1 + 0.287830687830692*G0_0_0_3_1_0_1_0_0 + 0.287830687830692*G0_0_0_3_1_0_2_0_1 - 0.287830687830692*G0_0_0_3_1_0_3_1_0 - 0.287830687830692*G0_0_0_3_1_0_3_1_1 + 0.287830687830692*G0_0_0_3_1_0_4_1_0 + 0.287830687830692*G0_0_0_3_1_0_5_1_1 - 0.287830687830692*G0_0_0_3_1_1_0_0_0 - 0.287830687830692*G0_0_0_3_1_1_0_0_1 + 0.287830687830692*G0_0_0_3_1_1_1_0_0 + 0.287830687830692*G0_0_0_3_1_1_2_0_1 - 0.287830687830692*G0_0_0_3_1_1_3_1_0 - 0.287830687830692*G0_0_0_3_1_1_3_1_1 + 0.287830687830692*G0_0_0_3_1_1_4_1_0 + 0.287830687830692*G0_0_0_3_1_1_5_1_1 + 0.287830687830692*G0_0_0_4_1_0_0_0_0 + 0.287830687830692*G0_0_0_4_1_0_0_0_1 - 0.287830687830692*G0_0_0_4_1_0_1_0_0 - 0.287830687830692*G0_0_0_4_1_0_2_0_1 + 0.287830687830692*G0_0_0_4_1_0_3_1_0 + 0.287830687830692*G0_0_0_4_1_0_3_1_1 - 0.287830687830692*G0_0_0_4_1_0_4_1_0 - 0.287830687830692*G0_0_0_4_1_0_5_1_1 + 0.287830687830692*G0_0_0_5_1_1_0_0_0 + 0.287830687830692*G0_0_0_5_1_1_0_0_1 - 0.287830687830692*G0_0_0_5_1_1_1_0_0 - 0.287830687830692*G0_0_0_5_1_1_2_0_1 + 0.287830687830692*G0_0_0_5_1_1_3_1_0 + 0.287830687830692*G0_0_0_5_1_1_3_1_1 - 0.287830687830692*G0_0_0_5_1_1_4_1_0 - 0.287830687830692*G0_0_0_5_1_1_5_1_1; + A[643] = 0.0; + A[662] = 0.0; + A[285] = 0.0; + A[701] = 0.0; + A[260] = 0.0; + A[331] = -0.651851851851859*G0_0_0_0_0_0_0_0_0 - 0.651851851851859*G0_0_0_0_0_0_0_0_1 + 0.651851851851859*G0_0_0_0_0_0_1_0_0 + 0.651851851851859*G0_0_0_0_0_0_2_0_1 - 0.651851851851859*G0_0_0_0_0_0_3_1_0 - 0.651851851851859*G0_0_0_0_0_0_3_1_1 + 0.651851851851859*G0_0_0_0_0_0_4_1_0 + 0.651851851851859*G0_0_0_0_0_0_5_1_1 - 0.651851851851859*G0_0_0_0_0_1_0_0_0 - 0.651851851851859*G0_0_0_0_0_1_0_0_1 + 0.651851851851859*G0_0_0_0_0_1_1_0_0 + 0.651851851851859*G0_0_0_0_0_1_2_0_1 - 0.651851851851859*G0_0_0_0_0_1_3_1_0 - 0.651851851851859*G0_0_0_0_0_1_3_1_1 + 0.651851851851859*G0_0_0_0_0_1_4_1_0 + 0.651851851851859*G0_0_0_0_0_1_5_1_1 + 0.651851851851859*G0_0_0_1_0_0_0_0_0 + 0.651851851851859*G0_0_0_1_0_0_0_0_1 - 0.651851851851859*G0_0_0_1_0_0_1_0_0 - 0.651851851851859*G0_0_0_1_0_0_2_0_1 + 0.651851851851859*G0_0_0_1_0_0_3_1_0 + 0.651851851851859*G0_0_0_1_0_0_3_1_1 - 0.651851851851859*G0_0_0_1_0_0_4_1_0 - 0.651851851851859*G0_0_0_1_0_0_5_1_1 + 0.651851851851859*G0_0_0_2_0_1_0_0_0 + 0.651851851851859*G0_0_0_2_0_1_0_0_1 - 0.651851851851859*G0_0_0_2_0_1_1_0_0 - 0.651851851851859*G0_0_0_2_0_1_2_0_1 + 0.651851851851859*G0_0_0_2_0_1_3_1_0 + 0.651851851851859*G0_0_0_2_0_1_3_1_1 - 0.651851851851859*G0_0_0_2_0_1_4_1_0 - 0.651851851851859*G0_0_0_2_0_1_5_1_1 - 0.651851851851859*G0_0_0_3_1_0_0_0_0 - 0.651851851851859*G0_0_0_3_1_0_0_0_1 + 0.651851851851859*G0_0_0_3_1_0_1_0_0 + 0.651851851851859*G0_0_0_3_1_0_2_0_1 - 0.651851851851859*G0_0_0_3_1_0_3_1_0 - 0.651851851851859*G0_0_0_3_1_0_3_1_1 + 0.651851851851859*G0_0_0_3_1_0_4_1_0 + 0.651851851851859*G0_0_0_3_1_0_5_1_1 - 0.651851851851859*G0_0_0_3_1_1_0_0_0 - 0.651851851851859*G0_0_0_3_1_1_0_0_1 + 0.651851851851859*G0_0_0_3_1_1_1_0_0 + 0.651851851851859*G0_0_0_3_1_1_2_0_1 - 0.651851851851859*G0_0_0_3_1_1_3_1_0 - 0.651851851851859*G0_0_0_3_1_1_3_1_1 + 0.651851851851859*G0_0_0_3_1_1_4_1_0 + 0.651851851851859*G0_0_0_3_1_1_5_1_1 + 0.651851851851859*G0_0_0_4_1_0_0_0_0 + 0.651851851851859*G0_0_0_4_1_0_0_0_1 - 0.651851851851859*G0_0_0_4_1_0_1_0_0 - 0.651851851851859*G0_0_0_4_1_0_2_0_1 + 0.651851851851859*G0_0_0_4_1_0_3_1_0 + 0.651851851851859*G0_0_0_4_1_0_3_1_1 - 0.651851851851859*G0_0_0_4_1_0_4_1_0 - 0.651851851851859*G0_0_0_4_1_0_5_1_1 + 0.651851851851859*G0_0_0_5_1_1_0_0_0 + 0.651851851851859*G0_0_0_5_1_1_0_0_1 - 0.651851851851859*G0_0_0_5_1_1_1_0_0 - 0.651851851851859*G0_0_0_5_1_1_2_0_1 + 0.651851851851859*G0_0_0_5_1_1_3_1_0 + 0.651851851851859*G0_0_0_5_1_1_3_1_1 - 0.651851851851859*G0_0_0_5_1_1_4_1_0 - 0.651851851851859*G0_0_0_5_1_1_5_1_1 - 0.778835978835987*G0_1_0_0_0_0_0_0_0 - 0.778835978835987*G0_1_0_0_0_0_0_0_1 + 0.778835978835987*G0_1_0_0_0_0_1_0_0 + 0.778835978835987*G0_1_0_0_0_0_2_0_1 - 0.778835978835987*G0_1_0_0_0_0_3_1_0 - 0.778835978835987*G0_1_0_0_0_0_3_1_1 + 0.778835978835987*G0_1_0_0_0_0_4_1_0 + 0.778835978835987*G0_1_0_0_0_0_5_1_1 - 0.778835978835987*G0_1_0_0_0_1_0_0_0 - 0.778835978835987*G0_1_0_0_0_1_0_0_1 + 0.778835978835987*G0_1_0_0_0_1_1_0_0 + 0.778835978835987*G0_1_0_0_0_1_2_0_1 - 0.778835978835987*G0_1_0_0_0_1_3_1_0 - 0.778835978835987*G0_1_0_0_0_1_3_1_1 + 0.778835978835987*G0_1_0_0_0_1_4_1_0 + 0.778835978835987*G0_1_0_0_0_1_5_1_1 + 0.778835978835987*G0_1_0_1_0_0_0_0_0 + 0.778835978835987*G0_1_0_1_0_0_0_0_1 - 0.778835978835987*G0_1_0_1_0_0_1_0_0 - 0.778835978835987*G0_1_0_1_0_0_2_0_1 + 0.778835978835987*G0_1_0_1_0_0_3_1_0 + 0.778835978835987*G0_1_0_1_0_0_3_1_1 - 0.778835978835987*G0_1_0_1_0_0_4_1_0 - 0.778835978835987*G0_1_0_1_0_0_5_1_1 + 0.778835978835987*G0_1_0_2_0_1_0_0_0 + 0.778835978835987*G0_1_0_2_0_1_0_0_1 - 0.778835978835987*G0_1_0_2_0_1_1_0_0 - 0.778835978835987*G0_1_0_2_0_1_2_0_1 + 0.778835978835987*G0_1_0_2_0_1_3_1_0 + 0.778835978835987*G0_1_0_2_0_1_3_1_1 - 0.778835978835987*G0_1_0_2_0_1_4_1_0 - 0.778835978835987*G0_1_0_2_0_1_5_1_1 - 0.778835978835987*G0_1_0_3_1_0_0_0_0 - 0.778835978835987*G0_1_0_3_1_0_0_0_1 + 0.778835978835987*G0_1_0_3_1_0_1_0_0 + 0.778835978835987*G0_1_0_3_1_0_2_0_1 - 0.778835978835987*G0_1_0_3_1_0_3_1_0 - 0.778835978835987*G0_1_0_3_1_0_3_1_1 + 0.778835978835987*G0_1_0_3_1_0_4_1_0 + 0.778835978835987*G0_1_0_3_1_0_5_1_1 - 0.778835978835987*G0_1_0_3_1_1_0_0_0 - 0.778835978835987*G0_1_0_3_1_1_0_0_1 + 0.778835978835987*G0_1_0_3_1_1_1_0_0 + 0.778835978835987*G0_1_0_3_1_1_2_0_1 - 0.778835978835987*G0_1_0_3_1_1_3_1_0 - 0.778835978835987*G0_1_0_3_1_1_3_1_1 + 0.778835978835987*G0_1_0_3_1_1_4_1_0 + 0.778835978835987*G0_1_0_3_1_1_5_1_1 + 0.778835978835987*G0_1_0_4_1_0_0_0_0 + 0.778835978835987*G0_1_0_4_1_0_0_0_1 - 0.778835978835987*G0_1_0_4_1_0_1_0_0 - 0.778835978835987*G0_1_0_4_1_0_2_0_1 + 0.778835978835987*G0_1_0_4_1_0_3_1_0 + 0.778835978835987*G0_1_0_4_1_0_3_1_1 - 0.778835978835987*G0_1_0_4_1_0_4_1_0 - 0.778835978835987*G0_1_0_4_1_0_5_1_1 + 0.778835978835987*G0_1_0_5_1_1_0_0_0 + 0.778835978835987*G0_1_0_5_1_1_0_0_1 - 0.778835978835987*G0_1_0_5_1_1_1_0_0 - 0.778835978835987*G0_1_0_5_1_1_2_0_1 + 0.778835978835987*G0_1_0_5_1_1_3_1_0 + 0.778835978835987*G0_1_0_5_1_1_3_1_1 - 0.778835978835987*G0_1_0_5_1_1_4_1_0 - 0.778835978835987*G0_1_0_5_1_1_5_1_1; + A[287] = 0.0; + A[743] = A[716] - 0.135449735449742*G0_1_1_0_0_0_0_0_0 - 0.135449735449742*G0_1_1_0_0_0_0_0_1 + 0.135449735449742*G0_1_1_0_0_0_1_0_0 + 0.135449735449742*G0_1_1_0_0_0_2_0_1 - 0.135449735449742*G0_1_1_0_0_0_3_1_0 - 0.135449735449742*G0_1_1_0_0_0_3_1_1 + 0.135449735449742*G0_1_1_0_0_0_4_1_0 + 0.135449735449742*G0_1_1_0_0_0_5_1_1 - 0.135449735449742*G0_1_1_0_0_1_0_0_0 - 0.135449735449742*G0_1_1_0_0_1_0_0_1 + 0.135449735449742*G0_1_1_0_0_1_1_0_0 + 0.135449735449742*G0_1_1_0_0_1_2_0_1 - 0.135449735449742*G0_1_1_0_0_1_3_1_0 - 0.135449735449742*G0_1_1_0_0_1_3_1_1 + 0.135449735449742*G0_1_1_0_0_1_4_1_0 + 0.135449735449742*G0_1_1_0_0_1_5_1_1 + 0.135449735449742*G0_1_1_1_0_0_0_0_0 + 0.135449735449742*G0_1_1_1_0_0_0_0_1 - 0.135449735449742*G0_1_1_1_0_0_1_0_0 - 0.135449735449742*G0_1_1_1_0_0_2_0_1 + 0.135449735449742*G0_1_1_1_0_0_3_1_0 + 0.135449735449742*G0_1_1_1_0_0_3_1_1 - 0.135449735449742*G0_1_1_1_0_0_4_1_0 - 0.135449735449742*G0_1_1_1_0_0_5_1_1 + 0.135449735449742*G0_1_1_2_0_1_0_0_0 + 0.135449735449742*G0_1_1_2_0_1_0_0_1 - 0.135449735449742*G0_1_1_2_0_1_1_0_0 - 0.135449735449742*G0_1_1_2_0_1_2_0_1 + 0.135449735449742*G0_1_1_2_0_1_3_1_0 + 0.135449735449742*G0_1_1_2_0_1_3_1_1 - 0.135449735449742*G0_1_1_2_0_1_4_1_0 - 0.135449735449742*G0_1_1_2_0_1_5_1_1 - 0.135449735449742*G0_1_1_3_1_0_0_0_0 - 0.135449735449742*G0_1_1_3_1_0_0_0_1 + 0.135449735449742*G0_1_1_3_1_0_1_0_0 + 0.135449735449742*G0_1_1_3_1_0_2_0_1 - 0.135449735449742*G0_1_1_3_1_0_3_1_0 - 0.135449735449742*G0_1_1_3_1_0_3_1_1 + 0.135449735449742*G0_1_1_3_1_0_4_1_0 + 0.135449735449742*G0_1_1_3_1_0_5_1_1 - 0.135449735449742*G0_1_1_3_1_1_0_0_0 - 0.135449735449742*G0_1_1_3_1_1_0_0_1 + 0.135449735449742*G0_1_1_3_1_1_1_0_0 + 0.135449735449742*G0_1_1_3_1_1_2_0_1 - 0.135449735449742*G0_1_1_3_1_1_3_1_0 - 0.135449735449742*G0_1_1_3_1_1_3_1_1 + 0.135449735449742*G0_1_1_3_1_1_4_1_0 + 0.135449735449742*G0_1_1_3_1_1_5_1_1 + 0.135449735449742*G0_1_1_4_1_0_0_0_0 + 0.135449735449742*G0_1_1_4_1_0_0_0_1 - 0.135449735449742*G0_1_1_4_1_0_1_0_0 - 0.135449735449742*G0_1_1_4_1_0_2_0_1 + 0.135449735449742*G0_1_1_4_1_0_3_1_0 + 0.135449735449742*G0_1_1_4_1_0_3_1_1 - 0.135449735449742*G0_1_1_4_1_0_4_1_0 - 0.135449735449742*G0_1_1_4_1_0_5_1_1 + 0.135449735449742*G0_1_1_5_1_1_0_0_0 + 0.135449735449742*G0_1_1_5_1_1_0_0_1 - 0.135449735449742*G0_1_1_5_1_1_1_0_0 - 0.135449735449742*G0_1_1_5_1_1_2_0_1 + 0.135449735449742*G0_1_1_5_1_1_3_1_0 + 0.135449735449742*G0_1_1_5_1_1_3_1_1 - 0.135449735449742*G0_1_1_5_1_1_4_1_0 - 0.135449735449742*G0_1_1_5_1_1_5_1_1; + A[658] = -A[743] + 0.812698412698439*G0_0_0_0_0_0_0_0_0 + 0.812698412698439*G0_0_0_0_0_0_0_0_1 - 0.812698412698439*G0_0_0_0_0_0_1_0_0 - 0.812698412698439*G0_0_0_0_0_0_2_0_1 + 0.812698412698439*G0_0_0_0_0_0_3_1_0 + 0.812698412698439*G0_0_0_0_0_0_3_1_1 - 0.812698412698439*G0_0_0_0_0_0_4_1_0 - 0.812698412698439*G0_0_0_0_0_0_5_1_1 + 0.812698412698439*G0_0_0_0_0_1_0_0_0 + 0.812698412698439*G0_0_0_0_0_1_0_0_1 - 0.812698412698439*G0_0_0_0_0_1_1_0_0 - 0.812698412698439*G0_0_0_0_0_1_2_0_1 + 0.812698412698439*G0_0_0_0_0_1_3_1_0 + 0.812698412698439*G0_0_0_0_0_1_3_1_1 - 0.812698412698439*G0_0_0_0_0_1_4_1_0 - 0.812698412698439*G0_0_0_0_0_1_5_1_1 - 0.812698412698439*G0_0_0_1_0_0_0_0_0 - 0.812698412698439*G0_0_0_1_0_0_0_0_1 + 0.812698412698439*G0_0_0_1_0_0_1_0_0 + 0.812698412698439*G0_0_0_1_0_0_2_0_1 - 0.812698412698439*G0_0_0_1_0_0_3_1_0 - 0.812698412698439*G0_0_0_1_0_0_3_1_1 + 0.812698412698439*G0_0_0_1_0_0_4_1_0 + 0.812698412698439*G0_0_0_1_0_0_5_1_1 - 0.812698412698439*G0_0_0_2_0_1_0_0_0 - 0.812698412698439*G0_0_0_2_0_1_0_0_1 + 0.812698412698439*G0_0_0_2_0_1_1_0_0 + 0.812698412698439*G0_0_0_2_0_1_2_0_1 - 0.812698412698439*G0_0_0_2_0_1_3_1_0 - 0.812698412698439*G0_0_0_2_0_1_3_1_1 + 0.812698412698439*G0_0_0_2_0_1_4_1_0 + 0.812698412698439*G0_0_0_2_0_1_5_1_1 + 0.812698412698439*G0_0_0_3_1_0_0_0_0 + 0.812698412698439*G0_0_0_3_1_0_0_0_1 - 0.812698412698439*G0_0_0_3_1_0_1_0_0 - 0.812698412698439*G0_0_0_3_1_0_2_0_1 + 0.812698412698439*G0_0_0_3_1_0_3_1_0 + 0.812698412698439*G0_0_0_3_1_0_3_1_1 - 0.812698412698439*G0_0_0_3_1_0_4_1_0 - 0.812698412698439*G0_0_0_3_1_0_5_1_1 + 0.812698412698439*G0_0_0_3_1_1_0_0_0 + 0.812698412698439*G0_0_0_3_1_1_0_0_1 - 0.812698412698439*G0_0_0_3_1_1_1_0_0 - 0.812698412698439*G0_0_0_3_1_1_2_0_1 + 0.812698412698439*G0_0_0_3_1_1_3_1_0 + 0.812698412698439*G0_0_0_3_1_1_3_1_1 - 0.812698412698439*G0_0_0_3_1_1_4_1_0 - 0.812698412698439*G0_0_0_3_1_1_5_1_1 - 0.812698412698439*G0_0_0_4_1_0_0_0_0 - 0.812698412698439*G0_0_0_4_1_0_0_0_1 + 0.812698412698439*G0_0_0_4_1_0_1_0_0 + 0.812698412698439*G0_0_0_4_1_0_2_0_1 - 0.812698412698439*G0_0_0_4_1_0_3_1_0 - 0.812698412698439*G0_0_0_4_1_0_3_1_1 + 0.812698412698439*G0_0_0_4_1_0_4_1_0 + 0.812698412698439*G0_0_0_4_1_0_5_1_1 - 0.812698412698439*G0_0_0_5_1_1_0_0_0 - 0.812698412698439*G0_0_0_5_1_1_0_0_1 + 0.812698412698439*G0_0_0_5_1_1_1_0_0 + 0.812698412698439*G0_0_0_5_1_1_2_0_1 - 0.812698412698439*G0_0_0_5_1_1_3_1_0 - 0.812698412698439*G0_0_0_5_1_1_3_1_1 + 0.812698412698439*G0_0_0_5_1_1_4_1_0 + 0.812698412698439*G0_0_0_5_1_1_5_1_1 + 0.575661375661385*G0_0_1_0_0_0_0_0_0 + 0.575661375661385*G0_0_1_0_0_0_0_0_1 - 0.575661375661385*G0_0_1_0_0_0_1_0_0 - 0.575661375661385*G0_0_1_0_0_0_2_0_1 + 0.575661375661385*G0_0_1_0_0_0_3_1_0 + 0.575661375661385*G0_0_1_0_0_0_3_1_1 - 0.575661375661385*G0_0_1_0_0_0_4_1_0 - 0.575661375661385*G0_0_1_0_0_0_5_1_1 + 0.575661375661385*G0_0_1_0_0_1_0_0_0 + 0.575661375661385*G0_0_1_0_0_1_0_0_1 - 0.575661375661385*G0_0_1_0_0_1_1_0_0 - 0.575661375661385*G0_0_1_0_0_1_2_0_1 + 0.575661375661385*G0_0_1_0_0_1_3_1_0 + 0.575661375661385*G0_0_1_0_0_1_3_1_1 - 0.575661375661385*G0_0_1_0_0_1_4_1_0 - 0.575661375661385*G0_0_1_0_0_1_5_1_1 - 0.575661375661385*G0_0_1_1_0_0_0_0_0 - 0.575661375661385*G0_0_1_1_0_0_0_0_1 + 0.575661375661385*G0_0_1_1_0_0_1_0_0 + 0.575661375661385*G0_0_1_1_0_0_2_0_1 - 0.575661375661385*G0_0_1_1_0_0_3_1_0 - 0.575661375661385*G0_0_1_1_0_0_3_1_1 + 0.575661375661385*G0_0_1_1_0_0_4_1_0 + 0.575661375661385*G0_0_1_1_0_0_5_1_1 - 0.575661375661385*G0_0_1_2_0_1_0_0_0 - 0.575661375661385*G0_0_1_2_0_1_0_0_1 + 0.575661375661385*G0_0_1_2_0_1_1_0_0 + 0.575661375661385*G0_0_1_2_0_1_2_0_1 - 0.575661375661385*G0_0_1_2_0_1_3_1_0 - 0.575661375661385*G0_0_1_2_0_1_3_1_1 + 0.575661375661385*G0_0_1_2_0_1_4_1_0 + 0.575661375661385*G0_0_1_2_0_1_5_1_1 + 0.575661375661385*G0_0_1_3_1_0_0_0_0 + 0.575661375661385*G0_0_1_3_1_0_0_0_1 - 0.575661375661385*G0_0_1_3_1_0_1_0_0 - 0.575661375661385*G0_0_1_3_1_0_2_0_1 + 0.575661375661385*G0_0_1_3_1_0_3_1_0 + 0.575661375661385*G0_0_1_3_1_0_3_1_1 - 0.575661375661385*G0_0_1_3_1_0_4_1_0 - 0.575661375661385*G0_0_1_3_1_0_5_1_1 + 0.575661375661385*G0_0_1_3_1_1_0_0_0 + 0.575661375661385*G0_0_1_3_1_1_0_0_1 - 0.575661375661385*G0_0_1_3_1_1_1_0_0 - 0.575661375661385*G0_0_1_3_1_1_2_0_1 + 0.575661375661385*G0_0_1_3_1_1_3_1_0 + 0.575661375661385*G0_0_1_3_1_1_3_1_1 - 0.575661375661385*G0_0_1_3_1_1_4_1_0 - 0.575661375661385*G0_0_1_3_1_1_5_1_1 - 0.575661375661385*G0_0_1_4_1_0_0_0_0 - 0.575661375661385*G0_0_1_4_1_0_0_0_1 + 0.575661375661385*G0_0_1_4_1_0_1_0_0 + 0.575661375661385*G0_0_1_4_1_0_2_0_1 - 0.575661375661385*G0_0_1_4_1_0_3_1_0 - 0.575661375661385*G0_0_1_4_1_0_3_1_1 + 0.575661375661385*G0_0_1_4_1_0_4_1_0 + 0.575661375661385*G0_0_1_4_1_0_5_1_1 - 0.575661375661385*G0_0_1_5_1_1_0_0_0 - 0.575661375661385*G0_0_1_5_1_1_0_0_1 + 0.575661375661385*G0_0_1_5_1_1_1_0_0 + 0.575661375661385*G0_0_1_5_1_1_2_0_1 - 0.575661375661385*G0_0_1_5_1_1_3_1_0 - 0.575661375661385*G0_0_1_5_1_1_3_1_1 + 0.575661375661385*G0_0_1_5_1_1_4_1_0 + 0.575661375661385*G0_0_1_5_1_1_5_1_1 + 0.575661375661395*G0_1_0_0_0_0_0_0_0 + 0.575661375661395*G0_1_0_0_0_0_0_0_1 - 0.575661375661395*G0_1_0_0_0_0_1_0_0 - 0.575661375661395*G0_1_0_0_0_0_2_0_1 + 0.575661375661395*G0_1_0_0_0_0_3_1_0 + 0.575661375661395*G0_1_0_0_0_0_3_1_1 - 0.575661375661395*G0_1_0_0_0_0_4_1_0 - 0.575661375661395*G0_1_0_0_0_0_5_1_1 + 0.575661375661395*G0_1_0_0_0_1_0_0_0 + 0.575661375661395*G0_1_0_0_0_1_0_0_1 - 0.575661375661395*G0_1_0_0_0_1_1_0_0 - 0.575661375661395*G0_1_0_0_0_1_2_0_1 + 0.575661375661395*G0_1_0_0_0_1_3_1_0 + 0.575661375661395*G0_1_0_0_0_1_3_1_1 - 0.575661375661395*G0_1_0_0_0_1_4_1_0 - 0.575661375661395*G0_1_0_0_0_1_5_1_1 - 0.575661375661395*G0_1_0_1_0_0_0_0_0 - 0.575661375661395*G0_1_0_1_0_0_0_0_1 + 0.575661375661395*G0_1_0_1_0_0_1_0_0 + 0.575661375661395*G0_1_0_1_0_0_2_0_1 - 0.575661375661395*G0_1_0_1_0_0_3_1_0 - 0.575661375661395*G0_1_0_1_0_0_3_1_1 + 0.575661375661395*G0_1_0_1_0_0_4_1_0 + 0.575661375661395*G0_1_0_1_0_0_5_1_1 - 0.575661375661395*G0_1_0_2_0_1_0_0_0 - 0.575661375661395*G0_1_0_2_0_1_0_0_1 + 0.575661375661395*G0_1_0_2_0_1_1_0_0 + 0.575661375661395*G0_1_0_2_0_1_2_0_1 - 0.575661375661395*G0_1_0_2_0_1_3_1_0 - 0.575661375661395*G0_1_0_2_0_1_3_1_1 + 0.575661375661395*G0_1_0_2_0_1_4_1_0 + 0.575661375661395*G0_1_0_2_0_1_5_1_1 + 0.575661375661395*G0_1_0_3_1_0_0_0_0 + 0.575661375661395*G0_1_0_3_1_0_0_0_1 - 0.575661375661395*G0_1_0_3_1_0_1_0_0 - 0.575661375661395*G0_1_0_3_1_0_2_0_1 + 0.575661375661395*G0_1_0_3_1_0_3_1_0 + 0.575661375661395*G0_1_0_3_1_0_3_1_1 - 0.575661375661395*G0_1_0_3_1_0_4_1_0 - 0.575661375661395*G0_1_0_3_1_0_5_1_1 + 0.575661375661395*G0_1_0_3_1_1_0_0_0 + 0.575661375661395*G0_1_0_3_1_1_0_0_1 - 0.575661375661395*G0_1_0_3_1_1_1_0_0 - 0.575661375661395*G0_1_0_3_1_1_2_0_1 + 0.575661375661395*G0_1_0_3_1_1_3_1_0 + 0.575661375661395*G0_1_0_3_1_1_3_1_1 - 0.575661375661395*G0_1_0_3_1_1_4_1_0 - 0.575661375661395*G0_1_0_3_1_1_5_1_1 - 0.575661375661395*G0_1_0_4_1_0_0_0_0 - 0.575661375661395*G0_1_0_4_1_0_0_0_1 + 0.575661375661395*G0_1_0_4_1_0_1_0_0 + 0.575661375661395*G0_1_0_4_1_0_2_0_1 - 0.575661375661395*G0_1_0_4_1_0_3_1_0 - 0.575661375661395*G0_1_0_4_1_0_3_1_1 + 0.575661375661395*G0_1_0_4_1_0_4_1_0 + 0.575661375661395*G0_1_0_4_1_0_5_1_1 - 0.575661375661395*G0_1_0_5_1_1_0_0_0 - 0.575661375661395*G0_1_0_5_1_1_0_0_1 + 0.575661375661395*G0_1_0_5_1_1_1_0_0 + 0.575661375661395*G0_1_0_5_1_1_2_0_1 - 0.575661375661395*G0_1_0_5_1_1_3_1_0 - 0.575661375661395*G0_1_0_5_1_1_3_1_1 + 0.575661375661395*G0_1_0_5_1_1_4_1_0 + 0.575661375661395*G0_1_0_5_1_1_5_1_1; + A[245] = A[743] - 2.09947089947092*G0_0_0_0_0_0_0_0_0 - 2.09947089947092*G0_0_0_0_0_0_0_0_1 + 2.09947089947092*G0_0_0_0_0_0_1_0_0 + 2.09947089947092*G0_0_0_0_0_0_2_0_1 - 2.09947089947092*G0_0_0_0_0_0_3_1_0 - 2.09947089947092*G0_0_0_0_0_0_3_1_1 + 2.09947089947092*G0_0_0_0_0_0_4_1_0 + 2.09947089947092*G0_0_0_0_0_0_5_1_1 - 2.09947089947092*G0_0_0_0_0_1_0_0_0 - 2.09947089947092*G0_0_0_0_0_1_0_0_1 + 2.09947089947092*G0_0_0_0_0_1_1_0_0 + 2.09947089947092*G0_0_0_0_0_1_2_0_1 - 2.09947089947092*G0_0_0_0_0_1_3_1_0 - 2.09947089947092*G0_0_0_0_0_1_3_1_1 + 2.09947089947092*G0_0_0_0_0_1_4_1_0 + 2.09947089947092*G0_0_0_0_0_1_5_1_1 + 2.09947089947092*G0_0_0_1_0_0_0_0_0 + 2.09947089947092*G0_0_0_1_0_0_0_0_1 - 2.09947089947092*G0_0_0_1_0_0_1_0_0 - 2.09947089947092*G0_0_0_1_0_0_2_0_1 + 2.09947089947092*G0_0_0_1_0_0_3_1_0 + 2.09947089947092*G0_0_0_1_0_0_3_1_1 - 2.09947089947092*G0_0_0_1_0_0_4_1_0 - 2.09947089947092*G0_0_0_1_0_0_5_1_1 + 2.09947089947092*G0_0_0_2_0_1_0_0_0 + 2.09947089947092*G0_0_0_2_0_1_0_0_1 - 2.09947089947092*G0_0_0_2_0_1_1_0_0 - 2.09947089947092*G0_0_0_2_0_1_2_0_1 + 2.09947089947092*G0_0_0_2_0_1_3_1_0 + 2.09947089947092*G0_0_0_2_0_1_3_1_1 - 2.09947089947092*G0_0_0_2_0_1_4_1_0 - 2.09947089947092*G0_0_0_2_0_1_5_1_1 - 2.09947089947092*G0_0_0_3_1_0_0_0_0 - 2.09947089947092*G0_0_0_3_1_0_0_0_1 + 2.09947089947092*G0_0_0_3_1_0_1_0_0 + 2.09947089947092*G0_0_0_3_1_0_2_0_1 - 2.09947089947092*G0_0_0_3_1_0_3_1_0 - 2.09947089947092*G0_0_0_3_1_0_3_1_1 + 2.09947089947092*G0_0_0_3_1_0_4_1_0 + 2.09947089947092*G0_0_0_3_1_0_5_1_1 - 2.09947089947092*G0_0_0_3_1_1_0_0_0 - 2.09947089947092*G0_0_0_3_1_1_0_0_1 + 2.09947089947092*G0_0_0_3_1_1_1_0_0 + 2.09947089947092*G0_0_0_3_1_1_2_0_1 - 2.09947089947092*G0_0_0_3_1_1_3_1_0 - 2.09947089947092*G0_0_0_3_1_1_3_1_1 + 2.09947089947092*G0_0_0_3_1_1_4_1_0 + 2.09947089947092*G0_0_0_3_1_1_5_1_1 + 2.09947089947092*G0_0_0_4_1_0_0_0_0 + 2.09947089947092*G0_0_0_4_1_0_0_0_1 - 2.09947089947092*G0_0_0_4_1_0_1_0_0 - 2.09947089947092*G0_0_0_4_1_0_2_0_1 + 2.09947089947092*G0_0_0_4_1_0_3_1_0 + 2.09947089947092*G0_0_0_4_1_0_3_1_1 - 2.09947089947092*G0_0_0_4_1_0_4_1_0 - 2.09947089947092*G0_0_0_4_1_0_5_1_1 + 2.09947089947092*G0_0_0_5_1_1_0_0_0 + 2.09947089947092*G0_0_0_5_1_1_0_0_1 - 2.09947089947092*G0_0_0_5_1_1_1_0_0 - 2.09947089947092*G0_0_0_5_1_1_2_0_1 + 2.09947089947092*G0_0_0_5_1_1_3_1_0 + 2.09947089947092*G0_0_0_5_1_1_3_1_1 - 2.09947089947092*G0_0_0_5_1_1_4_1_0 - 2.09947089947092*G0_0_0_5_1_1_5_1_1 - 1.15132275132275*G0_0_1_0_0_0_0_0_0 - 1.15132275132275*G0_0_1_0_0_0_0_0_1 + 1.15132275132275*G0_0_1_0_0_0_1_0_0 + 1.15132275132275*G0_0_1_0_0_0_2_0_1 - 1.15132275132275*G0_0_1_0_0_0_3_1_0 - 1.15132275132275*G0_0_1_0_0_0_3_1_1 + 1.15132275132275*G0_0_1_0_0_0_4_1_0 + 1.15132275132275*G0_0_1_0_0_0_5_1_1 - 1.15132275132275*G0_0_1_0_0_1_0_0_0 - 1.15132275132275*G0_0_1_0_0_1_0_0_1 + 1.15132275132275*G0_0_1_0_0_1_1_0_0 + 1.15132275132275*G0_0_1_0_0_1_2_0_1 - 1.15132275132275*G0_0_1_0_0_1_3_1_0 - 1.15132275132275*G0_0_1_0_0_1_3_1_1 + 1.15132275132275*G0_0_1_0_0_1_4_1_0 + 1.15132275132275*G0_0_1_0_0_1_5_1_1 + 1.15132275132275*G0_0_1_1_0_0_0_0_0 + 1.15132275132275*G0_0_1_1_0_0_0_0_1 - 1.15132275132275*G0_0_1_1_0_0_1_0_0 - 1.15132275132275*G0_0_1_1_0_0_2_0_1 + 1.15132275132275*G0_0_1_1_0_0_3_1_0 + 1.15132275132275*G0_0_1_1_0_0_3_1_1 - 1.15132275132275*G0_0_1_1_0_0_4_1_0 - 1.15132275132275*G0_0_1_1_0_0_5_1_1 + 1.15132275132275*G0_0_1_2_0_1_0_0_0 + 1.15132275132275*G0_0_1_2_0_1_0_0_1 - 1.15132275132275*G0_0_1_2_0_1_1_0_0 - 1.15132275132275*G0_0_1_2_0_1_2_0_1 + 1.15132275132275*G0_0_1_2_0_1_3_1_0 + 1.15132275132275*G0_0_1_2_0_1_3_1_1 - 1.15132275132275*G0_0_1_2_0_1_4_1_0 - 1.15132275132275*G0_0_1_2_0_1_5_1_1 - 1.15132275132275*G0_0_1_3_1_0_0_0_0 - 1.15132275132275*G0_0_1_3_1_0_0_0_1 + 1.15132275132275*G0_0_1_3_1_0_1_0_0 + 1.15132275132275*G0_0_1_3_1_0_2_0_1 - 1.15132275132275*G0_0_1_3_1_0_3_1_0 - 1.15132275132275*G0_0_1_3_1_0_3_1_1 + 1.15132275132275*G0_0_1_3_1_0_4_1_0 + 1.15132275132275*G0_0_1_3_1_0_5_1_1 - 1.15132275132275*G0_0_1_3_1_1_0_0_0 - 1.15132275132275*G0_0_1_3_1_1_0_0_1 + 1.15132275132275*G0_0_1_3_1_1_1_0_0 + 1.15132275132275*G0_0_1_3_1_1_2_0_1 - 1.15132275132275*G0_0_1_3_1_1_3_1_0 - 1.15132275132275*G0_0_1_3_1_1_3_1_1 + 1.15132275132275*G0_0_1_3_1_1_4_1_0 + 1.15132275132275*G0_0_1_3_1_1_5_1_1 + 1.15132275132275*G0_0_1_4_1_0_0_0_0 + 1.15132275132275*G0_0_1_4_1_0_0_0_1 - 1.15132275132275*G0_0_1_4_1_0_1_0_0 - 1.15132275132275*G0_0_1_4_1_0_2_0_1 + 1.15132275132275*G0_0_1_4_1_0_3_1_0 + 1.15132275132275*G0_0_1_4_1_0_3_1_1 - 1.15132275132275*G0_0_1_4_1_0_4_1_0 - 1.15132275132275*G0_0_1_4_1_0_5_1_1 + 1.15132275132275*G0_0_1_5_1_1_0_0_0 + 1.15132275132275*G0_0_1_5_1_1_0_0_1 - 1.15132275132275*G0_0_1_5_1_1_1_0_0 - 1.15132275132275*G0_0_1_5_1_1_2_0_1 + 1.15132275132275*G0_0_1_5_1_1_3_1_0 + 1.15132275132275*G0_0_1_5_1_1_3_1_1 - 1.15132275132275*G0_0_1_5_1_1_4_1_0 - 1.15132275132275*G0_0_1_5_1_1_5_1_1 - 1.15132275132276*G0_1_0_0_0_0_0_0_0 - 1.15132275132276*G0_1_0_0_0_0_0_0_1 + 1.15132275132276*G0_1_0_0_0_0_1_0_0 + 1.15132275132276*G0_1_0_0_0_0_2_0_1 - 1.15132275132276*G0_1_0_0_0_0_3_1_0 - 1.15132275132276*G0_1_0_0_0_0_3_1_1 + 1.15132275132276*G0_1_0_0_0_0_4_1_0 + 1.15132275132276*G0_1_0_0_0_0_5_1_1 - 1.15132275132276*G0_1_0_0_0_1_0_0_0 - 1.15132275132276*G0_1_0_0_0_1_0_0_1 + 1.15132275132276*G0_1_0_0_0_1_1_0_0 + 1.15132275132276*G0_1_0_0_0_1_2_0_1 - 1.15132275132276*G0_1_0_0_0_1_3_1_0 - 1.15132275132276*G0_1_0_0_0_1_3_1_1 + 1.15132275132276*G0_1_0_0_0_1_4_1_0 + 1.15132275132276*G0_1_0_0_0_1_5_1_1 + 1.15132275132276*G0_1_0_1_0_0_0_0_0 + 1.15132275132276*G0_1_0_1_0_0_0_0_1 - 1.15132275132276*G0_1_0_1_0_0_1_0_0 - 1.15132275132276*G0_1_0_1_0_0_2_0_1 + 1.15132275132276*G0_1_0_1_0_0_3_1_0 + 1.15132275132276*G0_1_0_1_0_0_3_1_1 - 1.15132275132276*G0_1_0_1_0_0_4_1_0 - 1.15132275132276*G0_1_0_1_0_0_5_1_1 + 1.15132275132276*G0_1_0_2_0_1_0_0_0 + 1.15132275132276*G0_1_0_2_0_1_0_0_1 - 1.15132275132276*G0_1_0_2_0_1_1_0_0 - 1.15132275132276*G0_1_0_2_0_1_2_0_1 + 1.15132275132276*G0_1_0_2_0_1_3_1_0 + 1.15132275132276*G0_1_0_2_0_1_3_1_1 - 1.15132275132276*G0_1_0_2_0_1_4_1_0 - 1.15132275132276*G0_1_0_2_0_1_5_1_1 - 1.15132275132276*G0_1_0_3_1_0_0_0_0 - 1.15132275132276*G0_1_0_3_1_0_0_0_1 + 1.15132275132276*G0_1_0_3_1_0_1_0_0 + 1.15132275132276*G0_1_0_3_1_0_2_0_1 - 1.15132275132276*G0_1_0_3_1_0_3_1_0 - 1.15132275132276*G0_1_0_3_1_0_3_1_1 + 1.15132275132276*G0_1_0_3_1_0_4_1_0 + 1.15132275132276*G0_1_0_3_1_0_5_1_1 - 1.15132275132276*G0_1_0_3_1_1_0_0_0 - 1.15132275132276*G0_1_0_3_1_1_0_0_1 + 1.15132275132276*G0_1_0_3_1_1_1_0_0 + 1.15132275132276*G0_1_0_3_1_1_2_0_1 - 1.15132275132276*G0_1_0_3_1_1_3_1_0 - 1.15132275132276*G0_1_0_3_1_1_3_1_1 + 1.15132275132276*G0_1_0_3_1_1_4_1_0 + 1.15132275132276*G0_1_0_3_1_1_5_1_1 + 1.15132275132276*G0_1_0_4_1_0_0_0_0 + 1.15132275132276*G0_1_0_4_1_0_0_0_1 - 1.15132275132276*G0_1_0_4_1_0_1_0_0 - 1.15132275132276*G0_1_0_4_1_0_2_0_1 + 1.15132275132276*G0_1_0_4_1_0_3_1_0 + 1.15132275132276*G0_1_0_4_1_0_3_1_1 - 1.15132275132276*G0_1_0_4_1_0_4_1_0 - 1.15132275132276*G0_1_0_4_1_0_5_1_1 + 1.15132275132276*G0_1_0_5_1_1_0_0_0 + 1.15132275132276*G0_1_0_5_1_1_0_0_1 - 1.15132275132276*G0_1_0_5_1_1_1_0_0 - 1.15132275132276*G0_1_0_5_1_1_2_0_1 + 1.15132275132276*G0_1_0_5_1_1_3_1_0 + 1.15132275132276*G0_1_0_5_1_1_3_1_1 - 1.15132275132276*G0_1_0_5_1_1_4_1_0 - 1.15132275132276*G0_1_0_5_1_1_5_1_1; + A[252] = -A[743] - 0.23703703703705*G0_0_1_0_0_0_0_0_0 - 0.23703703703705*G0_0_1_0_0_0_0_0_1 + 0.23703703703705*G0_0_1_0_0_0_1_0_0 + 0.23703703703705*G0_0_1_0_0_0_2_0_1 - 0.23703703703705*G0_0_1_0_0_0_3_1_0 - 0.23703703703705*G0_0_1_0_0_0_3_1_1 + 0.23703703703705*G0_0_1_0_0_0_4_1_0 + 0.23703703703705*G0_0_1_0_0_0_5_1_1 - 0.23703703703705*G0_0_1_0_0_1_0_0_0 - 0.23703703703705*G0_0_1_0_0_1_0_0_1 + 0.23703703703705*G0_0_1_0_0_1_1_0_0 + 0.23703703703705*G0_0_1_0_0_1_2_0_1 - 0.23703703703705*G0_0_1_0_0_1_3_1_0 - 0.23703703703705*G0_0_1_0_0_1_3_1_1 + 0.23703703703705*G0_0_1_0_0_1_4_1_0 + 0.23703703703705*G0_0_1_0_0_1_5_1_1 + 0.23703703703705*G0_0_1_1_0_0_0_0_0 + 0.23703703703705*G0_0_1_1_0_0_0_0_1 - 0.23703703703705*G0_0_1_1_0_0_1_0_0 - 0.23703703703705*G0_0_1_1_0_0_2_0_1 + 0.23703703703705*G0_0_1_1_0_0_3_1_0 + 0.23703703703705*G0_0_1_1_0_0_3_1_1 - 0.23703703703705*G0_0_1_1_0_0_4_1_0 - 0.23703703703705*G0_0_1_1_0_0_5_1_1 + 0.23703703703705*G0_0_1_2_0_1_0_0_0 + 0.23703703703705*G0_0_1_2_0_1_0_0_1 - 0.23703703703705*G0_0_1_2_0_1_1_0_0 - 0.23703703703705*G0_0_1_2_0_1_2_0_1 + 0.23703703703705*G0_0_1_2_0_1_3_1_0 + 0.23703703703705*G0_0_1_2_0_1_3_1_1 - 0.23703703703705*G0_0_1_2_0_1_4_1_0 - 0.23703703703705*G0_0_1_2_0_1_5_1_1 - 0.23703703703705*G0_0_1_3_1_0_0_0_0 - 0.23703703703705*G0_0_1_3_1_0_0_0_1 + 0.23703703703705*G0_0_1_3_1_0_1_0_0 + 0.23703703703705*G0_0_1_3_1_0_2_0_1 - 0.23703703703705*G0_0_1_3_1_0_3_1_0 - 0.23703703703705*G0_0_1_3_1_0_3_1_1 + 0.23703703703705*G0_0_1_3_1_0_4_1_0 + 0.23703703703705*G0_0_1_3_1_0_5_1_1 - 0.23703703703705*G0_0_1_3_1_1_0_0_0 - 0.23703703703705*G0_0_1_3_1_1_0_0_1 + 0.23703703703705*G0_0_1_3_1_1_1_0_0 + 0.23703703703705*G0_0_1_3_1_1_2_0_1 - 0.23703703703705*G0_0_1_3_1_1_3_1_0 - 0.23703703703705*G0_0_1_3_1_1_3_1_1 + 0.23703703703705*G0_0_1_3_1_1_4_1_0 + 0.23703703703705*G0_0_1_3_1_1_5_1_1 + 0.23703703703705*G0_0_1_4_1_0_0_0_0 + 0.23703703703705*G0_0_1_4_1_0_0_0_1 - 0.23703703703705*G0_0_1_4_1_0_1_0_0 - 0.23703703703705*G0_0_1_4_1_0_2_0_1 + 0.23703703703705*G0_0_1_4_1_0_3_1_0 + 0.23703703703705*G0_0_1_4_1_0_3_1_1 - 0.23703703703705*G0_0_1_4_1_0_4_1_0 - 0.23703703703705*G0_0_1_4_1_0_5_1_1 + 0.23703703703705*G0_0_1_5_1_1_0_0_0 + 0.23703703703705*G0_0_1_5_1_1_0_0_1 - 0.23703703703705*G0_0_1_5_1_1_1_0_0 - 0.23703703703705*G0_0_1_5_1_1_2_0_1 + 0.23703703703705*G0_0_1_5_1_1_3_1_0 + 0.23703703703705*G0_0_1_5_1_1_3_1_1 - 0.23703703703705*G0_0_1_5_1_1_4_1_0 - 0.23703703703705*G0_0_1_5_1_1_5_1_1 - 0.237037037037039*G0_1_0_0_0_0_0_0_0 - 0.237037037037039*G0_1_0_0_0_0_0_0_1 + 0.237037037037039*G0_1_0_0_0_0_1_0_0 + 0.237037037037039*G0_1_0_0_0_0_2_0_1 - 0.237037037037039*G0_1_0_0_0_0_3_1_0 - 0.237037037037039*G0_1_0_0_0_0_3_1_1 + 0.237037037037039*G0_1_0_0_0_0_4_1_0 + 0.237037037037039*G0_1_0_0_0_0_5_1_1 - 0.237037037037039*G0_1_0_0_0_1_0_0_0 - 0.237037037037039*G0_1_0_0_0_1_0_0_1 + 0.237037037037039*G0_1_0_0_0_1_1_0_0 + 0.237037037037039*G0_1_0_0_0_1_2_0_1 - 0.237037037037039*G0_1_0_0_0_1_3_1_0 - 0.237037037037039*G0_1_0_0_0_1_3_1_1 + 0.237037037037039*G0_1_0_0_0_1_4_1_0 + 0.237037037037039*G0_1_0_0_0_1_5_1_1 + 0.237037037037039*G0_1_0_1_0_0_0_0_0 + 0.237037037037039*G0_1_0_1_0_0_0_0_1 - 0.237037037037039*G0_1_0_1_0_0_1_0_0 - 0.237037037037039*G0_1_0_1_0_0_2_0_1 + 0.237037037037039*G0_1_0_1_0_0_3_1_0 + 0.237037037037039*G0_1_0_1_0_0_3_1_1 - 0.237037037037039*G0_1_0_1_0_0_4_1_0 - 0.237037037037039*G0_1_0_1_0_0_5_1_1 + 0.237037037037039*G0_1_0_2_0_1_0_0_0 + 0.237037037037039*G0_1_0_2_0_1_0_0_1 - 0.237037037037039*G0_1_0_2_0_1_1_0_0 - 0.237037037037039*G0_1_0_2_0_1_2_0_1 + 0.237037037037039*G0_1_0_2_0_1_3_1_0 + 0.237037037037039*G0_1_0_2_0_1_3_1_1 - 0.237037037037039*G0_1_0_2_0_1_4_1_0 - 0.237037037037039*G0_1_0_2_0_1_5_1_1 - 0.237037037037039*G0_1_0_3_1_0_0_0_0 - 0.237037037037039*G0_1_0_3_1_0_0_0_1 + 0.237037037037039*G0_1_0_3_1_0_1_0_0 + 0.237037037037039*G0_1_0_3_1_0_2_0_1 - 0.237037037037039*G0_1_0_3_1_0_3_1_0 - 0.237037037037039*G0_1_0_3_1_0_3_1_1 + 0.237037037037039*G0_1_0_3_1_0_4_1_0 + 0.237037037037039*G0_1_0_3_1_0_5_1_1 - 0.237037037037039*G0_1_0_3_1_1_0_0_0 - 0.237037037037039*G0_1_0_3_1_1_0_0_1 + 0.237037037037039*G0_1_0_3_1_1_1_0_0 + 0.237037037037039*G0_1_0_3_1_1_2_0_1 - 0.237037037037039*G0_1_0_3_1_1_3_1_0 - 0.237037037037039*G0_1_0_3_1_1_3_1_1 + 0.237037037037039*G0_1_0_3_1_1_4_1_0 + 0.237037037037039*G0_1_0_3_1_1_5_1_1 + 0.237037037037039*G0_1_0_4_1_0_0_0_0 + 0.237037037037039*G0_1_0_4_1_0_0_0_1 - 0.237037037037039*G0_1_0_4_1_0_1_0_0 - 0.237037037037039*G0_1_0_4_1_0_2_0_1 + 0.237037037037039*G0_1_0_4_1_0_3_1_0 + 0.237037037037039*G0_1_0_4_1_0_3_1_1 - 0.237037037037039*G0_1_0_4_1_0_4_1_0 - 0.237037037037039*G0_1_0_4_1_0_5_1_1 + 0.237037037037039*G0_1_0_5_1_1_0_0_0 + 0.237037037037039*G0_1_0_5_1_1_0_0_1 - 0.237037037037039*G0_1_0_5_1_1_1_0_0 - 0.237037037037039*G0_1_0_5_1_1_2_0_1 + 0.237037037037039*G0_1_0_5_1_1_3_1_0 + 0.237037037037039*G0_1_0_5_1_1_3_1_1 - 0.237037037037039*G0_1_0_5_1_1_4_1_0 - 0.237037037037039*G0_1_0_5_1_1_5_1_1; + A[428] = -A[743] + 1.38835978835982*G0_0_1_0_0_0_0_0_0 + 1.38835978835982*G0_0_1_0_0_0_0_0_1 - 1.38835978835982*G0_0_1_0_0_0_1_0_0 - 1.38835978835982*G0_0_1_0_0_0_2_0_1 + 1.38835978835982*G0_0_1_0_0_0_3_1_0 + 1.38835978835982*G0_0_1_0_0_0_3_1_1 - 1.38835978835982*G0_0_1_0_0_0_4_1_0 - 1.38835978835982*G0_0_1_0_0_0_5_1_1 + 1.38835978835982*G0_0_1_0_0_1_0_0_0 + 1.38835978835982*G0_0_1_0_0_1_0_0_1 - 1.38835978835982*G0_0_1_0_0_1_1_0_0 - 1.38835978835982*G0_0_1_0_0_1_2_0_1 + 1.38835978835982*G0_0_1_0_0_1_3_1_0 + 1.38835978835982*G0_0_1_0_0_1_3_1_1 - 1.38835978835982*G0_0_1_0_0_1_4_1_0 - 1.38835978835982*G0_0_1_0_0_1_5_1_1 - 1.38835978835982*G0_0_1_1_0_0_0_0_0 - 1.38835978835982*G0_0_1_1_0_0_0_0_1 + 1.38835978835982*G0_0_1_1_0_0_1_0_0 + 1.38835978835982*G0_0_1_1_0_0_2_0_1 - 1.38835978835982*G0_0_1_1_0_0_3_1_0 - 1.38835978835982*G0_0_1_1_0_0_3_1_1 + 1.38835978835982*G0_0_1_1_0_0_4_1_0 + 1.38835978835982*G0_0_1_1_0_0_5_1_1 - 1.38835978835982*G0_0_1_2_0_1_0_0_0 - 1.38835978835982*G0_0_1_2_0_1_0_0_1 + 1.38835978835982*G0_0_1_2_0_1_1_0_0 + 1.38835978835982*G0_0_1_2_0_1_2_0_1 - 1.38835978835982*G0_0_1_2_0_1_3_1_0 - 1.38835978835982*G0_0_1_2_0_1_3_1_1 + 1.38835978835982*G0_0_1_2_0_1_4_1_0 + 1.38835978835982*G0_0_1_2_0_1_5_1_1 + 1.38835978835982*G0_0_1_3_1_0_0_0_0 + 1.38835978835982*G0_0_1_3_1_0_0_0_1 - 1.38835978835982*G0_0_1_3_1_0_1_0_0 - 1.38835978835982*G0_0_1_3_1_0_2_0_1 + 1.38835978835982*G0_0_1_3_1_0_3_1_0 + 1.38835978835982*G0_0_1_3_1_0_3_1_1 - 1.38835978835982*G0_0_1_3_1_0_4_1_0 - 1.38835978835982*G0_0_1_3_1_0_5_1_1 + 1.38835978835982*G0_0_1_3_1_1_0_0_0 + 1.38835978835982*G0_0_1_3_1_1_0_0_1 - 1.38835978835982*G0_0_1_3_1_1_1_0_0 - 1.38835978835982*G0_0_1_3_1_1_2_0_1 + 1.38835978835982*G0_0_1_3_1_1_3_1_0 + 1.38835978835982*G0_0_1_3_1_1_3_1_1 - 1.38835978835982*G0_0_1_3_1_1_4_1_0 - 1.38835978835982*G0_0_1_3_1_1_5_1_1 - 1.38835978835982*G0_0_1_4_1_0_0_0_0 - 1.38835978835982*G0_0_1_4_1_0_0_0_1 + 1.38835978835982*G0_0_1_4_1_0_1_0_0 + 1.38835978835982*G0_0_1_4_1_0_2_0_1 - 1.38835978835982*G0_0_1_4_1_0_3_1_0 - 1.38835978835982*G0_0_1_4_1_0_3_1_1 + 1.38835978835982*G0_0_1_4_1_0_4_1_0 + 1.38835978835982*G0_0_1_4_1_0_5_1_1 - 1.38835978835982*G0_0_1_5_1_1_0_0_0 - 1.38835978835982*G0_0_1_5_1_1_0_0_1 + 1.38835978835982*G0_0_1_5_1_1_1_0_0 + 1.38835978835982*G0_0_1_5_1_1_2_0_1 - 1.38835978835982*G0_0_1_5_1_1_3_1_0 - 1.38835978835982*G0_0_1_5_1_1_3_1_1 + 1.38835978835982*G0_0_1_5_1_1_4_1_0 + 1.38835978835982*G0_0_1_5_1_1_5_1_1 + 1.3883597883598*G0_1_0_0_0_0_0_0_0 + 1.3883597883598*G0_1_0_0_0_0_0_0_1 - 1.3883597883598*G0_1_0_0_0_0_1_0_0 - 1.3883597883598*G0_1_0_0_0_0_2_0_1 + 1.3883597883598*G0_1_0_0_0_0_3_1_0 + 1.3883597883598*G0_1_0_0_0_0_3_1_1 - 1.3883597883598*G0_1_0_0_0_0_4_1_0 - 1.3883597883598*G0_1_0_0_0_0_5_1_1 + 1.3883597883598*G0_1_0_0_0_1_0_0_0 + 1.3883597883598*G0_1_0_0_0_1_0_0_1 - 1.3883597883598*G0_1_0_0_0_1_1_0_0 - 1.3883597883598*G0_1_0_0_0_1_2_0_1 + 1.3883597883598*G0_1_0_0_0_1_3_1_0 + 1.3883597883598*G0_1_0_0_0_1_3_1_1 - 1.3883597883598*G0_1_0_0_0_1_4_1_0 - 1.3883597883598*G0_1_0_0_0_1_5_1_1 - 1.3883597883598*G0_1_0_1_0_0_0_0_0 - 1.3883597883598*G0_1_0_1_0_0_0_0_1 + 1.3883597883598*G0_1_0_1_0_0_1_0_0 + 1.3883597883598*G0_1_0_1_0_0_2_0_1 - 1.3883597883598*G0_1_0_1_0_0_3_1_0 - 1.3883597883598*G0_1_0_1_0_0_3_1_1 + 1.3883597883598*G0_1_0_1_0_0_4_1_0 + 1.3883597883598*G0_1_0_1_0_0_5_1_1 - 1.3883597883598*G0_1_0_2_0_1_0_0_0 - 1.3883597883598*G0_1_0_2_0_1_0_0_1 + 1.3883597883598*G0_1_0_2_0_1_1_0_0 + 1.3883597883598*G0_1_0_2_0_1_2_0_1 - 1.3883597883598*G0_1_0_2_0_1_3_1_0 - 1.3883597883598*G0_1_0_2_0_1_3_1_1 + 1.3883597883598*G0_1_0_2_0_1_4_1_0 + 1.3883597883598*G0_1_0_2_0_1_5_1_1 + 1.3883597883598*G0_1_0_3_1_0_0_0_0 + 1.3883597883598*G0_1_0_3_1_0_0_0_1 - 1.3883597883598*G0_1_0_3_1_0_1_0_0 - 1.3883597883598*G0_1_0_3_1_0_2_0_1 + 1.3883597883598*G0_1_0_3_1_0_3_1_0 + 1.3883597883598*G0_1_0_3_1_0_3_1_1 - 1.3883597883598*G0_1_0_3_1_0_4_1_0 - 1.3883597883598*G0_1_0_3_1_0_5_1_1 + 1.3883597883598*G0_1_0_3_1_1_0_0_0 + 1.3883597883598*G0_1_0_3_1_1_0_0_1 - 1.3883597883598*G0_1_0_3_1_1_1_0_0 - 1.3883597883598*G0_1_0_3_1_1_2_0_1 + 1.3883597883598*G0_1_0_3_1_1_3_1_0 + 1.3883597883598*G0_1_0_3_1_1_3_1_1 - 1.3883597883598*G0_1_0_3_1_1_4_1_0 - 1.3883597883598*G0_1_0_3_1_1_5_1_1 - 1.3883597883598*G0_1_0_4_1_0_0_0_0 - 1.3883597883598*G0_1_0_4_1_0_0_0_1 + 1.3883597883598*G0_1_0_4_1_0_1_0_0 + 1.3883597883598*G0_1_0_4_1_0_2_0_1 - 1.3883597883598*G0_1_0_4_1_0_3_1_0 - 1.3883597883598*G0_1_0_4_1_0_3_1_1 + 1.3883597883598*G0_1_0_4_1_0_4_1_0 + 1.3883597883598*G0_1_0_4_1_0_5_1_1 - 1.3883597883598*G0_1_0_5_1_1_0_0_0 - 1.3883597883598*G0_1_0_5_1_1_0_0_1 + 1.3883597883598*G0_1_0_5_1_1_1_0_0 + 1.3883597883598*G0_1_0_5_1_1_2_0_1 - 1.3883597883598*G0_1_0_5_1_1_3_1_0 - 1.3883597883598*G0_1_0_5_1_1_3_1_1 + 1.3883597883598*G0_1_0_5_1_1_4_1_0 + 1.3883597883598*G0_1_0_5_1_1_5_1_1; + A[368] = A[252]; + A[101] = A[245] + 1.96402116402118*G0_0_0_0_0_0_0_0_0 + 1.96402116402118*G0_0_0_0_0_0_0_0_1 - 1.96402116402118*G0_0_0_0_0_0_1_0_0 - 1.96402116402118*G0_0_0_0_0_0_2_0_1 + 1.96402116402118*G0_0_0_0_0_0_3_1_0 + 1.96402116402118*G0_0_0_0_0_0_3_1_1 - 1.96402116402118*G0_0_0_0_0_0_4_1_0 - 1.96402116402118*G0_0_0_0_0_0_5_1_1 + 1.96402116402118*G0_0_0_0_0_1_0_0_0 + 1.96402116402118*G0_0_0_0_0_1_0_0_1 - 1.96402116402118*G0_0_0_0_0_1_1_0_0 - 1.96402116402118*G0_0_0_0_0_1_2_0_1 + 1.96402116402118*G0_0_0_0_0_1_3_1_0 + 1.96402116402118*G0_0_0_0_0_1_3_1_1 - 1.96402116402118*G0_0_0_0_0_1_4_1_0 - 1.96402116402118*G0_0_0_0_0_1_5_1_1 - 1.96402116402118*G0_0_0_1_0_0_0_0_0 - 1.96402116402118*G0_0_0_1_0_0_0_0_1 + 1.96402116402118*G0_0_0_1_0_0_1_0_0 + 1.96402116402118*G0_0_0_1_0_0_2_0_1 - 1.96402116402118*G0_0_0_1_0_0_3_1_0 - 1.96402116402118*G0_0_0_1_0_0_3_1_1 + 1.96402116402118*G0_0_0_1_0_0_4_1_0 + 1.96402116402118*G0_0_0_1_0_0_5_1_1 - 1.96402116402118*G0_0_0_2_0_1_0_0_0 - 1.96402116402118*G0_0_0_2_0_1_0_0_1 + 1.96402116402118*G0_0_0_2_0_1_1_0_0 + 1.96402116402118*G0_0_0_2_0_1_2_0_1 - 1.96402116402118*G0_0_0_2_0_1_3_1_0 - 1.96402116402118*G0_0_0_2_0_1_3_1_1 + 1.96402116402118*G0_0_0_2_0_1_4_1_0 + 1.96402116402118*G0_0_0_2_0_1_5_1_1 + 1.96402116402118*G0_0_0_3_1_0_0_0_0 + 1.96402116402118*G0_0_0_3_1_0_0_0_1 - 1.96402116402118*G0_0_0_3_1_0_1_0_0 - 1.96402116402118*G0_0_0_3_1_0_2_0_1 + 1.96402116402118*G0_0_0_3_1_0_3_1_0 + 1.96402116402118*G0_0_0_3_1_0_3_1_1 - 1.96402116402118*G0_0_0_3_1_0_4_1_0 - 1.96402116402118*G0_0_0_3_1_0_5_1_1 + 1.96402116402118*G0_0_0_3_1_1_0_0_0 + 1.96402116402118*G0_0_0_3_1_1_0_0_1 - 1.96402116402118*G0_0_0_3_1_1_1_0_0 - 1.96402116402118*G0_0_0_3_1_1_2_0_1 + 1.96402116402118*G0_0_0_3_1_1_3_1_0 + 1.96402116402118*G0_0_0_3_1_1_3_1_1 - 1.96402116402118*G0_0_0_3_1_1_4_1_0 - 1.96402116402118*G0_0_0_3_1_1_5_1_1 - 1.96402116402118*G0_0_0_4_1_0_0_0_0 - 1.96402116402118*G0_0_0_4_1_0_0_0_1 + 1.96402116402118*G0_0_0_4_1_0_1_0_0 + 1.96402116402118*G0_0_0_4_1_0_2_0_1 - 1.96402116402118*G0_0_0_4_1_0_3_1_0 - 1.96402116402118*G0_0_0_4_1_0_3_1_1 + 1.96402116402118*G0_0_0_4_1_0_4_1_0 + 1.96402116402118*G0_0_0_4_1_0_5_1_1 - 1.96402116402118*G0_0_0_5_1_1_0_0_0 - 1.96402116402118*G0_0_0_5_1_1_0_0_1 + 1.96402116402118*G0_0_0_5_1_1_1_0_0 + 1.96402116402118*G0_0_0_5_1_1_2_0_1 - 1.96402116402118*G0_0_0_5_1_1_3_1_0 - 1.96402116402118*G0_0_0_5_1_1_3_1_1 + 1.96402116402118*G0_0_0_5_1_1_4_1_0 + 1.96402116402118*G0_0_0_5_1_1_5_1_1 - 1.96402116402118*G0_1_1_0_0_0_0_0_0 - 1.96402116402118*G0_1_1_0_0_0_0_0_1 + 1.96402116402118*G0_1_1_0_0_0_1_0_0 + 1.96402116402118*G0_1_1_0_0_0_2_0_1 - 1.96402116402118*G0_1_1_0_0_0_3_1_0 - 1.96402116402118*G0_1_1_0_0_0_3_1_1 + 1.96402116402118*G0_1_1_0_0_0_4_1_0 + 1.96402116402118*G0_1_1_0_0_0_5_1_1 - 1.96402116402118*G0_1_1_0_0_1_0_0_0 - 1.96402116402118*G0_1_1_0_0_1_0_0_1 + 1.96402116402118*G0_1_1_0_0_1_1_0_0 + 1.96402116402118*G0_1_1_0_0_1_2_0_1 - 1.96402116402118*G0_1_1_0_0_1_3_1_0 - 1.96402116402118*G0_1_1_0_0_1_3_1_1 + 1.96402116402118*G0_1_1_0_0_1_4_1_0 + 1.96402116402118*G0_1_1_0_0_1_5_1_1 + 1.96402116402118*G0_1_1_1_0_0_0_0_0 + 1.96402116402118*G0_1_1_1_0_0_0_0_1 - 1.96402116402118*G0_1_1_1_0_0_1_0_0 - 1.96402116402118*G0_1_1_1_0_0_2_0_1 + 1.96402116402118*G0_1_1_1_0_0_3_1_0 + 1.96402116402118*G0_1_1_1_0_0_3_1_1 - 1.96402116402118*G0_1_1_1_0_0_4_1_0 - 1.96402116402118*G0_1_1_1_0_0_5_1_1 + 1.96402116402118*G0_1_1_2_0_1_0_0_0 + 1.96402116402118*G0_1_1_2_0_1_0_0_1 - 1.96402116402118*G0_1_1_2_0_1_1_0_0 - 1.96402116402118*G0_1_1_2_0_1_2_0_1 + 1.96402116402118*G0_1_1_2_0_1_3_1_0 + 1.96402116402118*G0_1_1_2_0_1_3_1_1 - 1.96402116402118*G0_1_1_2_0_1_4_1_0 - 1.96402116402118*G0_1_1_2_0_1_5_1_1 - 1.96402116402118*G0_1_1_3_1_0_0_0_0 - 1.96402116402118*G0_1_1_3_1_0_0_0_1 + 1.96402116402118*G0_1_1_3_1_0_1_0_0 + 1.96402116402118*G0_1_1_3_1_0_2_0_1 - 1.96402116402118*G0_1_1_3_1_0_3_1_0 - 1.96402116402118*G0_1_1_3_1_0_3_1_1 + 1.96402116402118*G0_1_1_3_1_0_4_1_0 + 1.96402116402118*G0_1_1_3_1_0_5_1_1 - 1.96402116402118*G0_1_1_3_1_1_0_0_0 - 1.96402116402118*G0_1_1_3_1_1_0_0_1 + 1.96402116402118*G0_1_1_3_1_1_1_0_0 + 1.96402116402118*G0_1_1_3_1_1_2_0_1 - 1.96402116402118*G0_1_1_3_1_1_3_1_0 - 1.96402116402118*G0_1_1_3_1_1_3_1_1 + 1.96402116402118*G0_1_1_3_1_1_4_1_0 + 1.96402116402118*G0_1_1_3_1_1_5_1_1 + 1.96402116402118*G0_1_1_4_1_0_0_0_0 + 1.96402116402118*G0_1_1_4_1_0_0_0_1 - 1.96402116402118*G0_1_1_4_1_0_1_0_0 - 1.96402116402118*G0_1_1_4_1_0_2_0_1 + 1.96402116402118*G0_1_1_4_1_0_3_1_0 + 1.96402116402118*G0_1_1_4_1_0_3_1_1 - 1.96402116402118*G0_1_1_4_1_0_4_1_0 - 1.96402116402118*G0_1_1_4_1_0_5_1_1 + 1.96402116402118*G0_1_1_5_1_1_0_0_0 + 1.96402116402118*G0_1_1_5_1_1_0_0_1 - 1.96402116402118*G0_1_1_5_1_1_1_0_0 - 1.96402116402118*G0_1_1_5_1_1_2_0_1 + 1.96402116402118*G0_1_1_5_1_1_3_1_0 + 1.96402116402118*G0_1_1_5_1_1_3_1_1 - 1.96402116402118*G0_1_1_5_1_1_4_1_0 - 1.96402116402118*G0_1_1_5_1_1_5_1_1; + A[194] = A[658]; + A[621] = A[743] - 0.338624338624344*G0_0_0_0_0_0_0_0_0 - 0.338624338624344*G0_0_0_0_0_0_0_0_1 + 0.338624338624344*G0_0_0_0_0_0_1_0_0 + 0.338624338624344*G0_0_0_0_0_0_2_0_1 - 0.338624338624344*G0_0_0_0_0_0_3_1_0 - 0.338624338624344*G0_0_0_0_0_0_3_1_1 + 0.338624338624344*G0_0_0_0_0_0_4_1_0 + 0.338624338624344*G0_0_0_0_0_0_5_1_1 - 0.338624338624344*G0_0_0_0_0_1_0_0_0 - 0.338624338624344*G0_0_0_0_0_1_0_0_1 + 0.338624338624344*G0_0_0_0_0_1_1_0_0 + 0.338624338624344*G0_0_0_0_0_1_2_0_1 - 0.338624338624344*G0_0_0_0_0_1_3_1_0 - 0.338624338624344*G0_0_0_0_0_1_3_1_1 + 0.338624338624344*G0_0_0_0_0_1_4_1_0 + 0.338624338624344*G0_0_0_0_0_1_5_1_1 + 0.338624338624344*G0_0_0_1_0_0_0_0_0 + 0.338624338624344*G0_0_0_1_0_0_0_0_1 - 0.338624338624344*G0_0_0_1_0_0_1_0_0 - 0.338624338624344*G0_0_0_1_0_0_2_0_1 + 0.338624338624344*G0_0_0_1_0_0_3_1_0 + 0.338624338624344*G0_0_0_1_0_0_3_1_1 - 0.338624338624344*G0_0_0_1_0_0_4_1_0 - 0.338624338624344*G0_0_0_1_0_0_5_1_1 + 0.338624338624344*G0_0_0_2_0_1_0_0_0 + 0.338624338624344*G0_0_0_2_0_1_0_0_1 - 0.338624338624344*G0_0_0_2_0_1_1_0_0 - 0.338624338624344*G0_0_0_2_0_1_2_0_1 + 0.338624338624344*G0_0_0_2_0_1_3_1_0 + 0.338624338624344*G0_0_0_2_0_1_3_1_1 - 0.338624338624344*G0_0_0_2_0_1_4_1_0 - 0.338624338624344*G0_0_0_2_0_1_5_1_1 - 0.338624338624344*G0_0_0_3_1_0_0_0_0 - 0.338624338624344*G0_0_0_3_1_0_0_0_1 + 0.338624338624344*G0_0_0_3_1_0_1_0_0 + 0.338624338624344*G0_0_0_3_1_0_2_0_1 - 0.338624338624344*G0_0_0_3_1_0_3_1_0 - 0.338624338624344*G0_0_0_3_1_0_3_1_1 + 0.338624338624344*G0_0_0_3_1_0_4_1_0 + 0.338624338624344*G0_0_0_3_1_0_5_1_1 - 0.338624338624344*G0_0_0_3_1_1_0_0_0 - 0.338624338624344*G0_0_0_3_1_1_0_0_1 + 0.338624338624344*G0_0_0_3_1_1_1_0_0 + 0.338624338624344*G0_0_0_3_1_1_2_0_1 - 0.338624338624344*G0_0_0_3_1_1_3_1_0 - 0.338624338624344*G0_0_0_3_1_1_3_1_1 + 0.338624338624344*G0_0_0_3_1_1_4_1_0 + 0.338624338624344*G0_0_0_3_1_1_5_1_1 + 0.338624338624344*G0_0_0_4_1_0_0_0_0 + 0.338624338624344*G0_0_0_4_1_0_0_0_1 - 0.338624338624344*G0_0_0_4_1_0_1_0_0 - 0.338624338624344*G0_0_0_4_1_0_2_0_1 + 0.338624338624344*G0_0_0_4_1_0_3_1_0 + 0.338624338624344*G0_0_0_4_1_0_3_1_1 - 0.338624338624344*G0_0_0_4_1_0_4_1_0 - 0.338624338624344*G0_0_0_4_1_0_5_1_1 + 0.338624338624344*G0_0_0_5_1_1_0_0_0 + 0.338624338624344*G0_0_0_5_1_1_0_0_1 - 0.338624338624344*G0_0_0_5_1_1_1_0_0 - 0.338624338624344*G0_0_0_5_1_1_2_0_1 + 0.338624338624344*G0_0_0_5_1_1_3_1_0 + 0.338624338624344*G0_0_0_5_1_1_3_1_1 - 0.338624338624344*G0_0_0_5_1_1_4_1_0 - 0.338624338624344*G0_0_0_5_1_1_5_1_1 - 0.33862433862434*G0_0_1_0_0_0_0_0_0 - 0.33862433862434*G0_0_1_0_0_0_0_0_1 + 0.33862433862434*G0_0_1_0_0_0_1_0_0 + 0.33862433862434*G0_0_1_0_0_0_2_0_1 - 0.33862433862434*G0_0_1_0_0_0_3_1_0 - 0.33862433862434*G0_0_1_0_0_0_3_1_1 + 0.33862433862434*G0_0_1_0_0_0_4_1_0 + 0.33862433862434*G0_0_1_0_0_0_5_1_1 - 0.33862433862434*G0_0_1_0_0_1_0_0_0 - 0.33862433862434*G0_0_1_0_0_1_0_0_1 + 0.33862433862434*G0_0_1_0_0_1_1_0_0 + 0.33862433862434*G0_0_1_0_0_1_2_0_1 - 0.33862433862434*G0_0_1_0_0_1_3_1_0 - 0.33862433862434*G0_0_1_0_0_1_3_1_1 + 0.33862433862434*G0_0_1_0_0_1_4_1_0 + 0.33862433862434*G0_0_1_0_0_1_5_1_1 + 0.33862433862434*G0_0_1_1_0_0_0_0_0 + 0.33862433862434*G0_0_1_1_0_0_0_0_1 - 0.33862433862434*G0_0_1_1_0_0_1_0_0 - 0.33862433862434*G0_0_1_1_0_0_2_0_1 + 0.33862433862434*G0_0_1_1_0_0_3_1_0 + 0.33862433862434*G0_0_1_1_0_0_3_1_1 - 0.33862433862434*G0_0_1_1_0_0_4_1_0 - 0.33862433862434*G0_0_1_1_0_0_5_1_1 + 0.33862433862434*G0_0_1_2_0_1_0_0_0 + 0.33862433862434*G0_0_1_2_0_1_0_0_1 - 0.33862433862434*G0_0_1_2_0_1_1_0_0 - 0.33862433862434*G0_0_1_2_0_1_2_0_1 + 0.33862433862434*G0_0_1_2_0_1_3_1_0 + 0.33862433862434*G0_0_1_2_0_1_3_1_1 - 0.33862433862434*G0_0_1_2_0_1_4_1_0 - 0.33862433862434*G0_0_1_2_0_1_5_1_1 - 0.33862433862434*G0_0_1_3_1_0_0_0_0 - 0.33862433862434*G0_0_1_3_1_0_0_0_1 + 0.33862433862434*G0_0_1_3_1_0_1_0_0 + 0.33862433862434*G0_0_1_3_1_0_2_0_1 - 0.33862433862434*G0_0_1_3_1_0_3_1_0 - 0.33862433862434*G0_0_1_3_1_0_3_1_1 + 0.33862433862434*G0_0_1_3_1_0_4_1_0 + 0.33862433862434*G0_0_1_3_1_0_5_1_1 - 0.33862433862434*G0_0_1_3_1_1_0_0_0 - 0.33862433862434*G0_0_1_3_1_1_0_0_1 + 0.33862433862434*G0_0_1_3_1_1_1_0_0 + 0.33862433862434*G0_0_1_3_1_1_2_0_1 - 0.33862433862434*G0_0_1_3_1_1_3_1_0 - 0.33862433862434*G0_0_1_3_1_1_3_1_1 + 0.33862433862434*G0_0_1_3_1_1_4_1_0 + 0.33862433862434*G0_0_1_3_1_1_5_1_1 + 0.33862433862434*G0_0_1_4_1_0_0_0_0 + 0.33862433862434*G0_0_1_4_1_0_0_0_1 - 0.33862433862434*G0_0_1_4_1_0_1_0_0 - 0.33862433862434*G0_0_1_4_1_0_2_0_1 + 0.33862433862434*G0_0_1_4_1_0_3_1_0 + 0.33862433862434*G0_0_1_4_1_0_3_1_1 - 0.33862433862434*G0_0_1_4_1_0_4_1_0 - 0.33862433862434*G0_0_1_4_1_0_5_1_1 + 0.33862433862434*G0_0_1_5_1_1_0_0_0 + 0.33862433862434*G0_0_1_5_1_1_0_0_1 - 0.33862433862434*G0_0_1_5_1_1_1_0_0 - 0.33862433862434*G0_0_1_5_1_1_2_0_1 + 0.33862433862434*G0_0_1_5_1_1_3_1_0 + 0.33862433862434*G0_0_1_5_1_1_3_1_1 - 0.33862433862434*G0_0_1_5_1_1_4_1_0 - 0.33862433862434*G0_0_1_5_1_1_5_1_1 - 0.33862433862435*G0_1_0_0_0_0_0_0_0 - 0.33862433862435*G0_1_0_0_0_0_0_0_1 + 0.33862433862435*G0_1_0_0_0_0_1_0_0 + 0.33862433862435*G0_1_0_0_0_0_2_0_1 - 0.33862433862435*G0_1_0_0_0_0_3_1_0 - 0.33862433862435*G0_1_0_0_0_0_3_1_1 + 0.33862433862435*G0_1_0_0_0_0_4_1_0 + 0.33862433862435*G0_1_0_0_0_0_5_1_1 - 0.33862433862435*G0_1_0_0_0_1_0_0_0 - 0.33862433862435*G0_1_0_0_0_1_0_0_1 + 0.33862433862435*G0_1_0_0_0_1_1_0_0 + 0.33862433862435*G0_1_0_0_0_1_2_0_1 - 0.33862433862435*G0_1_0_0_0_1_3_1_0 - 0.33862433862435*G0_1_0_0_0_1_3_1_1 + 0.33862433862435*G0_1_0_0_0_1_4_1_0 + 0.33862433862435*G0_1_0_0_0_1_5_1_1 + 0.33862433862435*G0_1_0_1_0_0_0_0_0 + 0.33862433862435*G0_1_0_1_0_0_0_0_1 - 0.33862433862435*G0_1_0_1_0_0_1_0_0 - 0.33862433862435*G0_1_0_1_0_0_2_0_1 + 0.33862433862435*G0_1_0_1_0_0_3_1_0 + 0.33862433862435*G0_1_0_1_0_0_3_1_1 - 0.33862433862435*G0_1_0_1_0_0_4_1_0 - 0.33862433862435*G0_1_0_1_0_0_5_1_1 + 0.33862433862435*G0_1_0_2_0_1_0_0_0 + 0.33862433862435*G0_1_0_2_0_1_0_0_1 - 0.33862433862435*G0_1_0_2_0_1_1_0_0 - 0.33862433862435*G0_1_0_2_0_1_2_0_1 + 0.33862433862435*G0_1_0_2_0_1_3_1_0 + 0.33862433862435*G0_1_0_2_0_1_3_1_1 - 0.33862433862435*G0_1_0_2_0_1_4_1_0 - 0.33862433862435*G0_1_0_2_0_1_5_1_1 - 0.33862433862435*G0_1_0_3_1_0_0_0_0 - 0.33862433862435*G0_1_0_3_1_0_0_0_1 + 0.33862433862435*G0_1_0_3_1_0_1_0_0 + 0.33862433862435*G0_1_0_3_1_0_2_0_1 - 0.33862433862435*G0_1_0_3_1_0_3_1_0 - 0.33862433862435*G0_1_0_3_1_0_3_1_1 + 0.33862433862435*G0_1_0_3_1_0_4_1_0 + 0.33862433862435*G0_1_0_3_1_0_5_1_1 - 0.33862433862435*G0_1_0_3_1_1_0_0_0 - 0.33862433862435*G0_1_0_3_1_1_0_0_1 + 0.33862433862435*G0_1_0_3_1_1_1_0_0 + 0.33862433862435*G0_1_0_3_1_1_2_0_1 - 0.33862433862435*G0_1_0_3_1_1_3_1_0 - 0.33862433862435*G0_1_0_3_1_1_3_1_1 + 0.33862433862435*G0_1_0_3_1_1_4_1_0 + 0.33862433862435*G0_1_0_3_1_1_5_1_1 + 0.33862433862435*G0_1_0_4_1_0_0_0_0 + 0.33862433862435*G0_1_0_4_1_0_0_0_1 - 0.33862433862435*G0_1_0_4_1_0_1_0_0 - 0.33862433862435*G0_1_0_4_1_0_2_0_1 + 0.33862433862435*G0_1_0_4_1_0_3_1_0 + 0.33862433862435*G0_1_0_4_1_0_3_1_1 - 0.33862433862435*G0_1_0_4_1_0_4_1_0 - 0.33862433862435*G0_1_0_4_1_0_5_1_1 + 0.33862433862435*G0_1_0_5_1_1_0_0_0 + 0.33862433862435*G0_1_0_5_1_1_0_0_1 - 0.33862433862435*G0_1_0_5_1_1_1_0_0 - 0.33862433862435*G0_1_0_5_1_1_2_0_1 + 0.33862433862435*G0_1_0_5_1_1_3_1_0 + 0.33862433862435*G0_1_0_5_1_1_3_1_1 - 0.33862433862435*G0_1_0_5_1_1_4_1_0 - 0.33862433862435*G0_1_0_5_1_1_5_1_1; + A[748] = A[658] - 0.67724867724869*G0_0_0_0_0_0_0_0_0 - 0.67724867724869*G0_0_0_0_0_0_0_0_1 + 0.67724867724869*G0_0_0_0_0_0_1_0_0 + 0.67724867724869*G0_0_0_0_0_0_2_0_1 - 0.67724867724869*G0_0_0_0_0_0_3_1_0 - 0.67724867724869*G0_0_0_0_0_0_3_1_1 + 0.67724867724869*G0_0_0_0_0_0_4_1_0 + 0.67724867724869*G0_0_0_0_0_0_5_1_1 - 0.67724867724869*G0_0_0_0_0_1_0_0_0 - 0.67724867724869*G0_0_0_0_0_1_0_0_1 + 0.67724867724869*G0_0_0_0_0_1_1_0_0 + 0.67724867724869*G0_0_0_0_0_1_2_0_1 - 0.67724867724869*G0_0_0_0_0_1_3_1_0 - 0.67724867724869*G0_0_0_0_0_1_3_1_1 + 0.67724867724869*G0_0_0_0_0_1_4_1_0 + 0.67724867724869*G0_0_0_0_0_1_5_1_1 + 0.67724867724869*G0_0_0_1_0_0_0_0_0 + 0.67724867724869*G0_0_0_1_0_0_0_0_1 - 0.67724867724869*G0_0_0_1_0_0_1_0_0 - 0.67724867724869*G0_0_0_1_0_0_2_0_1 + 0.67724867724869*G0_0_0_1_0_0_3_1_0 + 0.67724867724869*G0_0_0_1_0_0_3_1_1 - 0.67724867724869*G0_0_0_1_0_0_4_1_0 - 0.67724867724869*G0_0_0_1_0_0_5_1_1 + 0.67724867724869*G0_0_0_2_0_1_0_0_0 + 0.67724867724869*G0_0_0_2_0_1_0_0_1 - 0.67724867724869*G0_0_0_2_0_1_1_0_0 - 0.67724867724869*G0_0_0_2_0_1_2_0_1 + 0.67724867724869*G0_0_0_2_0_1_3_1_0 + 0.67724867724869*G0_0_0_2_0_1_3_1_1 - 0.67724867724869*G0_0_0_2_0_1_4_1_0 - 0.67724867724869*G0_0_0_2_0_1_5_1_1 - 0.67724867724869*G0_0_0_3_1_0_0_0_0 - 0.67724867724869*G0_0_0_3_1_0_0_0_1 + 0.67724867724869*G0_0_0_3_1_0_1_0_0 + 0.67724867724869*G0_0_0_3_1_0_2_0_1 - 0.67724867724869*G0_0_0_3_1_0_3_1_0 - 0.67724867724869*G0_0_0_3_1_0_3_1_1 + 0.67724867724869*G0_0_0_3_1_0_4_1_0 + 0.67724867724869*G0_0_0_3_1_0_5_1_1 - 0.67724867724869*G0_0_0_3_1_1_0_0_0 - 0.67724867724869*G0_0_0_3_1_1_0_0_1 + 0.67724867724869*G0_0_0_3_1_1_1_0_0 + 0.67724867724869*G0_0_0_3_1_1_2_0_1 - 0.67724867724869*G0_0_0_3_1_1_3_1_0 - 0.67724867724869*G0_0_0_3_1_1_3_1_1 + 0.67724867724869*G0_0_0_3_1_1_4_1_0 + 0.67724867724869*G0_0_0_3_1_1_5_1_1 + 0.67724867724869*G0_0_0_4_1_0_0_0_0 + 0.67724867724869*G0_0_0_4_1_0_0_0_1 - 0.67724867724869*G0_0_0_4_1_0_1_0_0 - 0.67724867724869*G0_0_0_4_1_0_2_0_1 + 0.67724867724869*G0_0_0_4_1_0_3_1_0 + 0.67724867724869*G0_0_0_4_1_0_3_1_1 - 0.67724867724869*G0_0_0_4_1_0_4_1_0 - 0.67724867724869*G0_0_0_4_1_0_5_1_1 + 0.67724867724869*G0_0_0_5_1_1_0_0_0 + 0.67724867724869*G0_0_0_5_1_1_0_0_1 - 0.67724867724869*G0_0_0_5_1_1_1_0_0 - 0.67724867724869*G0_0_0_5_1_1_2_0_1 + 0.67724867724869*G0_0_0_5_1_1_3_1_0 + 0.67724867724869*G0_0_0_5_1_1_3_1_1 - 0.67724867724869*G0_0_0_5_1_1_4_1_0 - 0.67724867724869*G0_0_0_5_1_1_5_1_1 + 0.677248677248681*G0_1_1_0_0_0_0_0_0 + 0.677248677248681*G0_1_1_0_0_0_0_0_1 - 0.677248677248681*G0_1_1_0_0_0_1_0_0 - 0.677248677248681*G0_1_1_0_0_0_2_0_1 + 0.677248677248681*G0_1_1_0_0_0_3_1_0 + 0.677248677248681*G0_1_1_0_0_0_3_1_1 - 0.677248677248681*G0_1_1_0_0_0_4_1_0 - 0.677248677248681*G0_1_1_0_0_0_5_1_1 + 0.677248677248681*G0_1_1_0_0_1_0_0_0 + 0.677248677248681*G0_1_1_0_0_1_0_0_1 - 0.677248677248681*G0_1_1_0_0_1_1_0_0 - 0.677248677248681*G0_1_1_0_0_1_2_0_1 + 0.677248677248681*G0_1_1_0_0_1_3_1_0 + 0.677248677248681*G0_1_1_0_0_1_3_1_1 - 0.677248677248681*G0_1_1_0_0_1_4_1_0 - 0.677248677248681*G0_1_1_0_0_1_5_1_1 - 0.677248677248681*G0_1_1_1_0_0_0_0_0 - 0.677248677248681*G0_1_1_1_0_0_0_0_1 + 0.677248677248681*G0_1_1_1_0_0_1_0_0 + 0.677248677248681*G0_1_1_1_0_0_2_0_1 - 0.677248677248681*G0_1_1_1_0_0_3_1_0 - 0.677248677248681*G0_1_1_1_0_0_3_1_1 + 0.677248677248681*G0_1_1_1_0_0_4_1_0 + 0.677248677248681*G0_1_1_1_0_0_5_1_1 - 0.677248677248681*G0_1_1_2_0_1_0_0_0 - 0.677248677248681*G0_1_1_2_0_1_0_0_1 + 0.677248677248681*G0_1_1_2_0_1_1_0_0 + 0.677248677248681*G0_1_1_2_0_1_2_0_1 - 0.677248677248681*G0_1_1_2_0_1_3_1_0 - 0.677248677248681*G0_1_1_2_0_1_3_1_1 + 0.677248677248681*G0_1_1_2_0_1_4_1_0 + 0.677248677248681*G0_1_1_2_0_1_5_1_1 + 0.677248677248681*G0_1_1_3_1_0_0_0_0 + 0.677248677248681*G0_1_1_3_1_0_0_0_1 - 0.677248677248681*G0_1_1_3_1_0_1_0_0 - 0.677248677248681*G0_1_1_3_1_0_2_0_1 + 0.677248677248681*G0_1_1_3_1_0_3_1_0 + 0.677248677248681*G0_1_1_3_1_0_3_1_1 - 0.677248677248681*G0_1_1_3_1_0_4_1_0 - 0.677248677248681*G0_1_1_3_1_0_5_1_1 + 0.677248677248681*G0_1_1_3_1_1_0_0_0 + 0.677248677248681*G0_1_1_3_1_1_0_0_1 - 0.677248677248681*G0_1_1_3_1_1_1_0_0 - 0.677248677248681*G0_1_1_3_1_1_2_0_1 + 0.677248677248681*G0_1_1_3_1_1_3_1_0 + 0.677248677248681*G0_1_1_3_1_1_3_1_1 - 0.677248677248681*G0_1_1_3_1_1_4_1_0 - 0.677248677248681*G0_1_1_3_1_1_5_1_1 - 0.677248677248681*G0_1_1_4_1_0_0_0_0 - 0.677248677248681*G0_1_1_4_1_0_0_0_1 + 0.677248677248681*G0_1_1_4_1_0_1_0_0 + 0.677248677248681*G0_1_1_4_1_0_2_0_1 - 0.677248677248681*G0_1_1_4_1_0_3_1_0 - 0.677248677248681*G0_1_1_4_1_0_3_1_1 + 0.677248677248681*G0_1_1_4_1_0_4_1_0 + 0.677248677248681*G0_1_1_4_1_0_5_1_1 - 0.677248677248681*G0_1_1_5_1_1_0_0_0 - 0.677248677248681*G0_1_1_5_1_1_0_0_1 + 0.677248677248681*G0_1_1_5_1_1_1_0_0 + 0.677248677248681*G0_1_1_5_1_1_2_0_1 - 0.677248677248681*G0_1_1_5_1_1_3_1_0 - 0.677248677248681*G0_1_1_5_1_1_3_1_1 + 0.677248677248681*G0_1_1_5_1_1_4_1_0 + 0.677248677248681*G0_1_1_5_1_1_5_1_1; + A[396] = A[658]; + A[864] = A[748]; + A[628] = -A[252] + 0.948148148148172*G0_1_1_0_0_0_0_0_0 + 0.948148148148172*G0_1_1_0_0_0_0_0_1 - 0.948148148148172*G0_1_1_0_0_0_1_0_0 - 0.948148148148172*G0_1_1_0_0_0_2_0_1 + 0.948148148148172*G0_1_1_0_0_0_3_1_0 + 0.948148148148172*G0_1_1_0_0_0_3_1_1 - 0.948148148148172*G0_1_1_0_0_0_4_1_0 - 0.948148148148172*G0_1_1_0_0_0_5_1_1 + 0.948148148148172*G0_1_1_0_0_1_0_0_0 + 0.948148148148172*G0_1_1_0_0_1_0_0_1 - 0.948148148148172*G0_1_1_0_0_1_1_0_0 - 0.948148148148172*G0_1_1_0_0_1_2_0_1 + 0.948148148148172*G0_1_1_0_0_1_3_1_0 + 0.948148148148172*G0_1_1_0_0_1_3_1_1 - 0.948148148148172*G0_1_1_0_0_1_4_1_0 - 0.948148148148172*G0_1_1_0_0_1_5_1_1 - 0.948148148148172*G0_1_1_1_0_0_0_0_0 - 0.948148148148172*G0_1_1_1_0_0_0_0_1 + 0.948148148148172*G0_1_1_1_0_0_1_0_0 + 0.948148148148172*G0_1_1_1_0_0_2_0_1 - 0.948148148148172*G0_1_1_1_0_0_3_1_0 - 0.948148148148172*G0_1_1_1_0_0_3_1_1 + 0.948148148148172*G0_1_1_1_0_0_4_1_0 + 0.948148148148172*G0_1_1_1_0_0_5_1_1 - 0.948148148148172*G0_1_1_2_0_1_0_0_0 - 0.948148148148172*G0_1_1_2_0_1_0_0_1 + 0.948148148148172*G0_1_1_2_0_1_1_0_0 + 0.948148148148172*G0_1_1_2_0_1_2_0_1 - 0.948148148148172*G0_1_1_2_0_1_3_1_0 - 0.948148148148172*G0_1_1_2_0_1_3_1_1 + 0.948148148148172*G0_1_1_2_0_1_4_1_0 + 0.948148148148172*G0_1_1_2_0_1_5_1_1 + 0.948148148148172*G0_1_1_3_1_0_0_0_0 + 0.948148148148172*G0_1_1_3_1_0_0_0_1 - 0.948148148148172*G0_1_1_3_1_0_1_0_0 - 0.948148148148172*G0_1_1_3_1_0_2_0_1 + 0.948148148148172*G0_1_1_3_1_0_3_1_0 + 0.948148148148172*G0_1_1_3_1_0_3_1_1 - 0.948148148148172*G0_1_1_3_1_0_4_1_0 - 0.948148148148172*G0_1_1_3_1_0_5_1_1 + 0.948148148148172*G0_1_1_3_1_1_0_0_0 + 0.948148148148172*G0_1_1_3_1_1_0_0_1 - 0.948148148148172*G0_1_1_3_1_1_1_0_0 - 0.948148148148172*G0_1_1_3_1_1_2_0_1 + 0.948148148148172*G0_1_1_3_1_1_3_1_0 + 0.948148148148172*G0_1_1_3_1_1_3_1_1 - 0.948148148148172*G0_1_1_3_1_1_4_1_0 - 0.948148148148172*G0_1_1_3_1_1_5_1_1 - 0.948148148148172*G0_1_1_4_1_0_0_0_0 - 0.948148148148172*G0_1_1_4_1_0_0_0_1 + 0.948148148148172*G0_1_1_4_1_0_1_0_0 + 0.948148148148172*G0_1_1_4_1_0_2_0_1 - 0.948148148148172*G0_1_1_4_1_0_3_1_0 - 0.948148148148172*G0_1_1_4_1_0_3_1_1 + 0.948148148148172*G0_1_1_4_1_0_4_1_0 + 0.948148148148172*G0_1_1_4_1_0_5_1_1 - 0.948148148148172*G0_1_1_5_1_1_0_0_0 - 0.948148148148172*G0_1_1_5_1_1_0_0_1 + 0.948148148148172*G0_1_1_5_1_1_1_0_0 + 0.948148148148172*G0_1_1_5_1_1_2_0_1 - 0.948148148148172*G0_1_1_5_1_1_3_1_0 - 0.948148148148172*G0_1_1_5_1_1_3_1_1 + 0.948148148148172*G0_1_1_5_1_1_4_1_0 + 0.948148148148172*G0_1_1_5_1_1_5_1_1; + A[830] = A[628]; + A[863] = A[252]; + A[627] = A[628]; + A[710] = A[245]; + A[156] = A[621]; + A[254] = A[428]; + A[434] = A[403]; + A[322] = 0.0; + A[772] = A[307]; + A[465] = 8.81249999999981*A[5]; + A[401] = -A[656] + 1.3883597883598*G0_0_1_0_0_0_0_0_0 + 1.3883597883598*G0_0_1_0_0_0_0_0_1 - 1.3883597883598*G0_0_1_0_0_0_1_0_0 - 1.3883597883598*G0_0_1_0_0_0_2_0_1 + 1.3883597883598*G0_0_1_0_0_0_3_1_0 + 1.3883597883598*G0_0_1_0_0_0_3_1_1 - 1.3883597883598*G0_0_1_0_0_0_4_1_0 - 1.3883597883598*G0_0_1_0_0_0_5_1_1 + 1.3883597883598*G0_0_1_0_0_1_0_0_0 + 1.3883597883598*G0_0_1_0_0_1_0_0_1 - 1.3883597883598*G0_0_1_0_0_1_1_0_0 - 1.3883597883598*G0_0_1_0_0_1_2_0_1 + 1.3883597883598*G0_0_1_0_0_1_3_1_0 + 1.3883597883598*G0_0_1_0_0_1_3_1_1 - 1.3883597883598*G0_0_1_0_0_1_4_1_0 - 1.3883597883598*G0_0_1_0_0_1_5_1_1 - 1.3883597883598*G0_0_1_1_0_0_0_0_0 - 1.3883597883598*G0_0_1_1_0_0_0_0_1 + 1.3883597883598*G0_0_1_1_0_0_1_0_0 + 1.3883597883598*G0_0_1_1_0_0_2_0_1 - 1.3883597883598*G0_0_1_1_0_0_3_1_0 - 1.3883597883598*G0_0_1_1_0_0_3_1_1 + 1.3883597883598*G0_0_1_1_0_0_4_1_0 + 1.3883597883598*G0_0_1_1_0_0_5_1_1 - 1.3883597883598*G0_0_1_2_0_1_0_0_0 - 1.3883597883598*G0_0_1_2_0_1_0_0_1 + 1.3883597883598*G0_0_1_2_0_1_1_0_0 + 1.3883597883598*G0_0_1_2_0_1_2_0_1 - 1.3883597883598*G0_0_1_2_0_1_3_1_0 - 1.3883597883598*G0_0_1_2_0_1_3_1_1 + 1.3883597883598*G0_0_1_2_0_1_4_1_0 + 1.3883597883598*G0_0_1_2_0_1_5_1_1 + 1.3883597883598*G0_0_1_3_1_0_0_0_0 + 1.3883597883598*G0_0_1_3_1_0_0_0_1 - 1.3883597883598*G0_0_1_3_1_0_1_0_0 - 1.3883597883598*G0_0_1_3_1_0_2_0_1 + 1.3883597883598*G0_0_1_3_1_0_3_1_0 + 1.3883597883598*G0_0_1_3_1_0_3_1_1 - 1.3883597883598*G0_0_1_3_1_0_4_1_0 - 1.3883597883598*G0_0_1_3_1_0_5_1_1 + 1.3883597883598*G0_0_1_3_1_1_0_0_0 + 1.3883597883598*G0_0_1_3_1_1_0_0_1 - 1.3883597883598*G0_0_1_3_1_1_1_0_0 - 1.3883597883598*G0_0_1_3_1_1_2_0_1 + 1.3883597883598*G0_0_1_3_1_1_3_1_0 + 1.3883597883598*G0_0_1_3_1_1_3_1_1 - 1.3883597883598*G0_0_1_3_1_1_4_1_0 - 1.3883597883598*G0_0_1_3_1_1_5_1_1 - 1.3883597883598*G0_0_1_4_1_0_0_0_0 - 1.3883597883598*G0_0_1_4_1_0_0_0_1 + 1.3883597883598*G0_0_1_4_1_0_1_0_0 + 1.3883597883598*G0_0_1_4_1_0_2_0_1 - 1.3883597883598*G0_0_1_4_1_0_3_1_0 - 1.3883597883598*G0_0_1_4_1_0_3_1_1 + 1.3883597883598*G0_0_1_4_1_0_4_1_0 + 1.3883597883598*G0_0_1_4_1_0_5_1_1 - 1.3883597883598*G0_0_1_5_1_1_0_0_0 - 1.3883597883598*G0_0_1_5_1_1_0_0_1 + 1.3883597883598*G0_0_1_5_1_1_1_0_0 + 1.3883597883598*G0_0_1_5_1_1_2_0_1 - 1.3883597883598*G0_0_1_5_1_1_3_1_0 - 1.3883597883598*G0_0_1_5_1_1_3_1_1 + 1.3883597883598*G0_0_1_5_1_1_4_1_0 + 1.3883597883598*G0_0_1_5_1_1_5_1_1 + 1.38835978835981*G0_1_0_0_0_0_0_0_0 + 1.38835978835981*G0_1_0_0_0_0_0_0_1 - 1.38835978835981*G0_1_0_0_0_0_1_0_0 - 1.38835978835981*G0_1_0_0_0_0_2_0_1 + 1.38835978835981*G0_1_0_0_0_0_3_1_0 + 1.38835978835981*G0_1_0_0_0_0_3_1_1 - 1.38835978835981*G0_1_0_0_0_0_4_1_0 - 1.38835978835981*G0_1_0_0_0_0_5_1_1 + 1.38835978835981*G0_1_0_0_0_1_0_0_0 + 1.38835978835981*G0_1_0_0_0_1_0_0_1 - 1.38835978835981*G0_1_0_0_0_1_1_0_0 - 1.38835978835981*G0_1_0_0_0_1_2_0_1 + 1.38835978835981*G0_1_0_0_0_1_3_1_0 + 1.38835978835981*G0_1_0_0_0_1_3_1_1 - 1.38835978835981*G0_1_0_0_0_1_4_1_0 - 1.38835978835981*G0_1_0_0_0_1_5_1_1 - 1.38835978835981*G0_1_0_1_0_0_0_0_0 - 1.38835978835981*G0_1_0_1_0_0_0_0_1 + 1.38835978835981*G0_1_0_1_0_0_1_0_0 + 1.38835978835981*G0_1_0_1_0_0_2_0_1 - 1.38835978835981*G0_1_0_1_0_0_3_1_0 - 1.38835978835981*G0_1_0_1_0_0_3_1_1 + 1.38835978835981*G0_1_0_1_0_0_4_1_0 + 1.38835978835981*G0_1_0_1_0_0_5_1_1 - 1.38835978835981*G0_1_0_2_0_1_0_0_0 - 1.38835978835981*G0_1_0_2_0_1_0_0_1 + 1.38835978835981*G0_1_0_2_0_1_1_0_0 + 1.38835978835981*G0_1_0_2_0_1_2_0_1 - 1.38835978835981*G0_1_0_2_0_1_3_1_0 - 1.38835978835981*G0_1_0_2_0_1_3_1_1 + 1.38835978835981*G0_1_0_2_0_1_4_1_0 + 1.38835978835981*G0_1_0_2_0_1_5_1_1 + 1.38835978835981*G0_1_0_3_1_0_0_0_0 + 1.38835978835981*G0_1_0_3_1_0_0_0_1 - 1.38835978835981*G0_1_0_3_1_0_1_0_0 - 1.38835978835981*G0_1_0_3_1_0_2_0_1 + 1.38835978835981*G0_1_0_3_1_0_3_1_0 + 1.38835978835981*G0_1_0_3_1_0_3_1_1 - 1.38835978835981*G0_1_0_3_1_0_4_1_0 - 1.38835978835981*G0_1_0_3_1_0_5_1_1 + 1.38835978835981*G0_1_0_3_1_1_0_0_0 + 1.38835978835981*G0_1_0_3_1_1_0_0_1 - 1.38835978835981*G0_1_0_3_1_1_1_0_0 - 1.38835978835981*G0_1_0_3_1_1_2_0_1 + 1.38835978835981*G0_1_0_3_1_1_3_1_0 + 1.38835978835981*G0_1_0_3_1_1_3_1_1 - 1.38835978835981*G0_1_0_3_1_1_4_1_0 - 1.38835978835981*G0_1_0_3_1_1_5_1_1 - 1.38835978835981*G0_1_0_4_1_0_0_0_0 - 1.38835978835981*G0_1_0_4_1_0_0_0_1 + 1.38835978835981*G0_1_0_4_1_0_1_0_0 + 1.38835978835981*G0_1_0_4_1_0_2_0_1 - 1.38835978835981*G0_1_0_4_1_0_3_1_0 - 1.38835978835981*G0_1_0_4_1_0_3_1_1 + 1.38835978835981*G0_1_0_4_1_0_4_1_0 + 1.38835978835981*G0_1_0_4_1_0_5_1_1 - 1.38835978835981*G0_1_0_5_1_1_0_0_0 - 1.38835978835981*G0_1_0_5_1_1_0_0_1 + 1.38835978835981*G0_1_0_5_1_1_1_0_0 + 1.38835978835981*G0_1_0_5_1_1_2_0_1 - 1.38835978835981*G0_1_0_5_1_1_3_1_0 - 1.38835978835981*G0_1_0_5_1_1_3_1_1 + 1.38835978835981*G0_1_0_5_1_1_4_1_0 + 1.38835978835981*G0_1_0_5_1_1_5_1_1; + A[76] = 0.0; + A[801] = A[656]; + A[0] = A[465]; + A[103] = -A[401] - 2.30264550264554*G0_0_0_0_0_0_0_0_0 - 2.30264550264554*G0_0_0_0_0_0_0_0_1 + 2.30264550264554*G0_0_0_0_0_0_1_0_0 + 2.30264550264554*G0_0_0_0_0_0_2_0_1 - 2.30264550264554*G0_0_0_0_0_0_3_1_0 - 2.30264550264554*G0_0_0_0_0_0_3_1_1 + 2.30264550264554*G0_0_0_0_0_0_4_1_0 + 2.30264550264554*G0_0_0_0_0_0_5_1_1 - 2.30264550264554*G0_0_0_0_0_1_0_0_0 - 2.30264550264554*G0_0_0_0_0_1_0_0_1 + 2.30264550264554*G0_0_0_0_0_1_1_0_0 + 2.30264550264554*G0_0_0_0_0_1_2_0_1 - 2.30264550264554*G0_0_0_0_0_1_3_1_0 - 2.30264550264554*G0_0_0_0_0_1_3_1_1 + 2.30264550264554*G0_0_0_0_0_1_4_1_0 + 2.30264550264554*G0_0_0_0_0_1_5_1_1 + 2.30264550264554*G0_0_0_1_0_0_0_0_0 + 2.30264550264554*G0_0_0_1_0_0_0_0_1 - 2.30264550264554*G0_0_0_1_0_0_1_0_0 - 2.30264550264554*G0_0_0_1_0_0_2_0_1 + 2.30264550264554*G0_0_0_1_0_0_3_1_0 + 2.30264550264554*G0_0_0_1_0_0_3_1_1 - 2.30264550264554*G0_0_0_1_0_0_4_1_0 - 2.30264550264554*G0_0_0_1_0_0_5_1_1 + 2.30264550264554*G0_0_0_2_0_1_0_0_0 + 2.30264550264554*G0_0_0_2_0_1_0_0_1 - 2.30264550264554*G0_0_0_2_0_1_1_0_0 - 2.30264550264554*G0_0_0_2_0_1_2_0_1 + 2.30264550264554*G0_0_0_2_0_1_3_1_0 + 2.30264550264554*G0_0_0_2_0_1_3_1_1 - 2.30264550264554*G0_0_0_2_0_1_4_1_0 - 2.30264550264554*G0_0_0_2_0_1_5_1_1 - 2.30264550264554*G0_0_0_3_1_0_0_0_0 - 2.30264550264554*G0_0_0_3_1_0_0_0_1 + 2.30264550264554*G0_0_0_3_1_0_1_0_0 + 2.30264550264554*G0_0_0_3_1_0_2_0_1 - 2.30264550264554*G0_0_0_3_1_0_3_1_0 - 2.30264550264554*G0_0_0_3_1_0_3_1_1 + 2.30264550264554*G0_0_0_3_1_0_4_1_0 + 2.30264550264554*G0_0_0_3_1_0_5_1_1 - 2.30264550264554*G0_0_0_3_1_1_0_0_0 - 2.30264550264554*G0_0_0_3_1_1_0_0_1 + 2.30264550264554*G0_0_0_3_1_1_1_0_0 + 2.30264550264554*G0_0_0_3_1_1_2_0_1 - 2.30264550264554*G0_0_0_3_1_1_3_1_0 - 2.30264550264554*G0_0_0_3_1_1_3_1_1 + 2.30264550264554*G0_0_0_3_1_1_4_1_0 + 2.30264550264554*G0_0_0_3_1_1_5_1_1 + 2.30264550264554*G0_0_0_4_1_0_0_0_0 + 2.30264550264554*G0_0_0_4_1_0_0_0_1 - 2.30264550264554*G0_0_0_4_1_0_1_0_0 - 2.30264550264554*G0_0_0_4_1_0_2_0_1 + 2.30264550264554*G0_0_0_4_1_0_3_1_0 + 2.30264550264554*G0_0_0_4_1_0_3_1_1 - 2.30264550264554*G0_0_0_4_1_0_4_1_0 - 2.30264550264554*G0_0_0_4_1_0_5_1_1 + 2.30264550264554*G0_0_0_5_1_1_0_0_0 + 2.30264550264554*G0_0_0_5_1_1_0_0_1 - 2.30264550264554*G0_0_0_5_1_1_1_0_0 - 2.30264550264554*G0_0_0_5_1_1_2_0_1 + 2.30264550264554*G0_0_0_5_1_1_3_1_0 + 2.30264550264554*G0_0_0_5_1_1_3_1_1 - 2.30264550264554*G0_0_0_5_1_1_4_1_0 - 2.30264550264554*G0_0_0_5_1_1_5_1_1; + A[834] = -A[656] - 1.04973544973546*G0_0_1_0_0_0_0_0_0 - 1.04973544973546*G0_0_1_0_0_0_0_0_1 + 1.04973544973546*G0_0_1_0_0_0_1_0_0 + 1.04973544973546*G0_0_1_0_0_0_2_0_1 - 1.04973544973546*G0_0_1_0_0_0_3_1_0 - 1.04973544973546*G0_0_1_0_0_0_3_1_1 + 1.04973544973546*G0_0_1_0_0_0_4_1_0 + 1.04973544973546*G0_0_1_0_0_0_5_1_1 - 1.04973544973546*G0_0_1_0_0_1_0_0_0 - 1.04973544973546*G0_0_1_0_0_1_0_0_1 + 1.04973544973546*G0_0_1_0_0_1_1_0_0 + 1.04973544973546*G0_0_1_0_0_1_2_0_1 - 1.04973544973546*G0_0_1_0_0_1_3_1_0 - 1.04973544973546*G0_0_1_0_0_1_3_1_1 + 1.04973544973546*G0_0_1_0_0_1_4_1_0 + 1.04973544973546*G0_0_1_0_0_1_5_1_1 + 1.04973544973546*G0_0_1_1_0_0_0_0_0 + 1.04973544973546*G0_0_1_1_0_0_0_0_1 - 1.04973544973546*G0_0_1_1_0_0_1_0_0 - 1.04973544973546*G0_0_1_1_0_0_2_0_1 + 1.04973544973546*G0_0_1_1_0_0_3_1_0 + 1.04973544973546*G0_0_1_1_0_0_3_1_1 - 1.04973544973546*G0_0_1_1_0_0_4_1_0 - 1.04973544973546*G0_0_1_1_0_0_5_1_1 + 1.04973544973546*G0_0_1_2_0_1_0_0_0 + 1.04973544973546*G0_0_1_2_0_1_0_0_1 - 1.04973544973546*G0_0_1_2_0_1_1_0_0 - 1.04973544973546*G0_0_1_2_0_1_2_0_1 + 1.04973544973546*G0_0_1_2_0_1_3_1_0 + 1.04973544973546*G0_0_1_2_0_1_3_1_1 - 1.04973544973546*G0_0_1_2_0_1_4_1_0 - 1.04973544973546*G0_0_1_2_0_1_5_1_1 - 1.04973544973546*G0_0_1_3_1_0_0_0_0 - 1.04973544973546*G0_0_1_3_1_0_0_0_1 + 1.04973544973546*G0_0_1_3_1_0_1_0_0 + 1.04973544973546*G0_0_1_3_1_0_2_0_1 - 1.04973544973546*G0_0_1_3_1_0_3_1_0 - 1.04973544973546*G0_0_1_3_1_0_3_1_1 + 1.04973544973546*G0_0_1_3_1_0_4_1_0 + 1.04973544973546*G0_0_1_3_1_0_5_1_1 - 1.04973544973546*G0_0_1_3_1_1_0_0_0 - 1.04973544973546*G0_0_1_3_1_1_0_0_1 + 1.04973544973546*G0_0_1_3_1_1_1_0_0 + 1.04973544973546*G0_0_1_3_1_1_2_0_1 - 1.04973544973546*G0_0_1_3_1_1_3_1_0 - 1.04973544973546*G0_0_1_3_1_1_3_1_1 + 1.04973544973546*G0_0_1_3_1_1_4_1_0 + 1.04973544973546*G0_0_1_3_1_1_5_1_1 + 1.04973544973546*G0_0_1_4_1_0_0_0_0 + 1.04973544973546*G0_0_1_4_1_0_0_0_1 - 1.04973544973546*G0_0_1_4_1_0_1_0_0 - 1.04973544973546*G0_0_1_4_1_0_2_0_1 + 1.04973544973546*G0_0_1_4_1_0_3_1_0 + 1.04973544973546*G0_0_1_4_1_0_3_1_1 - 1.04973544973546*G0_0_1_4_1_0_4_1_0 - 1.04973544973546*G0_0_1_4_1_0_5_1_1 + 1.04973544973546*G0_0_1_5_1_1_0_0_0 + 1.04973544973546*G0_0_1_5_1_1_0_0_1 - 1.04973544973546*G0_0_1_5_1_1_1_0_0 - 1.04973544973546*G0_0_1_5_1_1_2_0_1 + 1.04973544973546*G0_0_1_5_1_1_3_1_0 + 1.04973544973546*G0_0_1_5_1_1_3_1_1 - 1.04973544973546*G0_0_1_5_1_1_4_1_0 - 1.04973544973546*G0_0_1_5_1_1_5_1_1 - 1.04973544973548*G0_1_0_0_0_0_0_0_0 - 1.04973544973548*G0_1_0_0_0_0_0_0_1 + 1.04973544973548*G0_1_0_0_0_0_1_0_0 + 1.04973544973548*G0_1_0_0_0_0_2_0_1 - 1.04973544973548*G0_1_0_0_0_0_3_1_0 - 1.04973544973548*G0_1_0_0_0_0_3_1_1 + 1.04973544973548*G0_1_0_0_0_0_4_1_0 + 1.04973544973548*G0_1_0_0_0_0_5_1_1 - 1.04973544973548*G0_1_0_0_0_1_0_0_0 - 1.04973544973548*G0_1_0_0_0_1_0_0_1 + 1.04973544973548*G0_1_0_0_0_1_1_0_0 + 1.04973544973548*G0_1_0_0_0_1_2_0_1 - 1.04973544973548*G0_1_0_0_0_1_3_1_0 - 1.04973544973548*G0_1_0_0_0_1_3_1_1 + 1.04973544973548*G0_1_0_0_0_1_4_1_0 + 1.04973544973548*G0_1_0_0_0_1_5_1_1 + 1.04973544973548*G0_1_0_1_0_0_0_0_0 + 1.04973544973548*G0_1_0_1_0_0_0_0_1 - 1.04973544973548*G0_1_0_1_0_0_1_0_0 - 1.04973544973548*G0_1_0_1_0_0_2_0_1 + 1.04973544973548*G0_1_0_1_0_0_3_1_0 + 1.04973544973548*G0_1_0_1_0_0_3_1_1 - 1.04973544973548*G0_1_0_1_0_0_4_1_0 - 1.04973544973548*G0_1_0_1_0_0_5_1_1 + 1.04973544973548*G0_1_0_2_0_1_0_0_0 + 1.04973544973548*G0_1_0_2_0_1_0_0_1 - 1.04973544973548*G0_1_0_2_0_1_1_0_0 - 1.04973544973548*G0_1_0_2_0_1_2_0_1 + 1.04973544973548*G0_1_0_2_0_1_3_1_0 + 1.04973544973548*G0_1_0_2_0_1_3_1_1 - 1.04973544973548*G0_1_0_2_0_1_4_1_0 - 1.04973544973548*G0_1_0_2_0_1_5_1_1 - 1.04973544973548*G0_1_0_3_1_0_0_0_0 - 1.04973544973548*G0_1_0_3_1_0_0_0_1 + 1.04973544973548*G0_1_0_3_1_0_1_0_0 + 1.04973544973548*G0_1_0_3_1_0_2_0_1 - 1.04973544973548*G0_1_0_3_1_0_3_1_0 - 1.04973544973548*G0_1_0_3_1_0_3_1_1 + 1.04973544973548*G0_1_0_3_1_0_4_1_0 + 1.04973544973548*G0_1_0_3_1_0_5_1_1 - 1.04973544973548*G0_1_0_3_1_1_0_0_0 - 1.04973544973548*G0_1_0_3_1_1_0_0_1 + 1.04973544973548*G0_1_0_3_1_1_1_0_0 + 1.04973544973548*G0_1_0_3_1_1_2_0_1 - 1.04973544973548*G0_1_0_3_1_1_3_1_0 - 1.04973544973548*G0_1_0_3_1_1_3_1_1 + 1.04973544973548*G0_1_0_3_1_1_4_1_0 + 1.04973544973548*G0_1_0_3_1_1_5_1_1 + 1.04973544973548*G0_1_0_4_1_0_0_0_0 + 1.04973544973548*G0_1_0_4_1_0_0_0_1 - 1.04973544973548*G0_1_0_4_1_0_1_0_0 - 1.04973544973548*G0_1_0_4_1_0_2_0_1 + 1.04973544973548*G0_1_0_4_1_0_3_1_0 + 1.04973544973548*G0_1_0_4_1_0_3_1_1 - 1.04973544973548*G0_1_0_4_1_0_4_1_0 - 1.04973544973548*G0_1_0_4_1_0_5_1_1 + 1.04973544973548*G0_1_0_5_1_1_0_0_0 + 1.04973544973548*G0_1_0_5_1_1_0_0_1 - 1.04973544973548*G0_1_0_5_1_1_1_0_0 - 1.04973544973548*G0_1_0_5_1_1_2_0_1 + 1.04973544973548*G0_1_0_5_1_1_3_1_0 + 1.04973544973548*G0_1_0_5_1_1_3_1_1 - 1.04973544973548*G0_1_0_5_1_1_4_1_0 - 1.04973544973548*G0_1_0_5_1_1_5_1_1 - 2.43809523809528*G0_1_1_0_0_0_0_0_0 - 2.43809523809528*G0_1_1_0_0_0_0_0_1 + 2.43809523809528*G0_1_1_0_0_0_1_0_0 + 2.43809523809528*G0_1_1_0_0_0_2_0_1 - 2.43809523809528*G0_1_1_0_0_0_3_1_0 - 2.43809523809528*G0_1_1_0_0_0_3_1_1 + 2.43809523809528*G0_1_1_0_0_0_4_1_0 + 2.43809523809528*G0_1_1_0_0_0_5_1_1 - 2.43809523809528*G0_1_1_0_0_1_0_0_0 - 2.43809523809528*G0_1_1_0_0_1_0_0_1 + 2.43809523809528*G0_1_1_0_0_1_1_0_0 + 2.43809523809528*G0_1_1_0_0_1_2_0_1 - 2.43809523809528*G0_1_1_0_0_1_3_1_0 - 2.43809523809528*G0_1_1_0_0_1_3_1_1 + 2.43809523809528*G0_1_1_0_0_1_4_1_0 + 2.43809523809528*G0_1_1_0_0_1_5_1_1 + 2.43809523809528*G0_1_1_1_0_0_0_0_0 + 2.43809523809528*G0_1_1_1_0_0_0_0_1 - 2.43809523809528*G0_1_1_1_0_0_1_0_0 - 2.43809523809528*G0_1_1_1_0_0_2_0_1 + 2.43809523809528*G0_1_1_1_0_0_3_1_0 + 2.43809523809528*G0_1_1_1_0_0_3_1_1 - 2.43809523809528*G0_1_1_1_0_0_4_1_0 - 2.43809523809528*G0_1_1_1_0_0_5_1_1 + 2.43809523809528*G0_1_1_2_0_1_0_0_0 + 2.43809523809528*G0_1_1_2_0_1_0_0_1 - 2.43809523809528*G0_1_1_2_0_1_1_0_0 - 2.43809523809528*G0_1_1_2_0_1_2_0_1 + 2.43809523809528*G0_1_1_2_0_1_3_1_0 + 2.43809523809528*G0_1_1_2_0_1_3_1_1 - 2.43809523809528*G0_1_1_2_0_1_4_1_0 - 2.43809523809528*G0_1_1_2_0_1_5_1_1 - 2.43809523809528*G0_1_1_3_1_0_0_0_0 - 2.43809523809528*G0_1_1_3_1_0_0_0_1 + 2.43809523809528*G0_1_1_3_1_0_1_0_0 + 2.43809523809528*G0_1_1_3_1_0_2_0_1 - 2.43809523809528*G0_1_1_3_1_0_3_1_0 - 2.43809523809528*G0_1_1_3_1_0_3_1_1 + 2.43809523809528*G0_1_1_3_1_0_4_1_0 + 2.43809523809528*G0_1_1_3_1_0_5_1_1 - 2.43809523809528*G0_1_1_3_1_1_0_0_0 - 2.43809523809528*G0_1_1_3_1_1_0_0_1 + 2.43809523809528*G0_1_1_3_1_1_1_0_0 + 2.43809523809528*G0_1_1_3_1_1_2_0_1 - 2.43809523809528*G0_1_1_3_1_1_3_1_0 - 2.43809523809528*G0_1_1_3_1_1_3_1_1 + 2.43809523809528*G0_1_1_3_1_1_4_1_0 + 2.43809523809528*G0_1_1_3_1_1_5_1_1 + 2.43809523809528*G0_1_1_4_1_0_0_0_0 + 2.43809523809528*G0_1_1_4_1_0_0_0_1 - 2.43809523809528*G0_1_1_4_1_0_1_0_0 - 2.43809523809528*G0_1_1_4_1_0_2_0_1 + 2.43809523809528*G0_1_1_4_1_0_3_1_0 + 2.43809523809528*G0_1_1_4_1_0_3_1_1 - 2.43809523809528*G0_1_1_4_1_0_4_1_0 - 2.43809523809528*G0_1_1_4_1_0_5_1_1 + 2.43809523809528*G0_1_1_5_1_1_0_0_0 + 2.43809523809528*G0_1_1_5_1_1_0_0_1 - 2.43809523809528*G0_1_1_5_1_1_1_0_0 - 2.43809523809528*G0_1_1_5_1_1_2_0_1 + 2.43809523809528*G0_1_1_5_1_1_3_1_0 + 2.43809523809528*G0_1_1_5_1_1_3_1_1 - 2.43809523809528*G0_1_1_5_1_1_4_1_0 - 2.43809523809528*G0_1_1_5_1_1_5_1_1; + A[43] = A[421]; + A[843] = 0.0; + A[70] = A[534]; + A[165] = 0.0; + A[872] = 0.0; + A[109] = 0.0; + A[192] = A[834] - 2.57354497354501*G0_0_0_0_0_0_0_0_0 - 2.57354497354501*G0_0_0_0_0_0_0_0_1 + 2.57354497354501*G0_0_0_0_0_0_1_0_0 + 2.57354497354501*G0_0_0_0_0_0_2_0_1 - 2.57354497354501*G0_0_0_0_0_0_3_1_0 - 2.57354497354501*G0_0_0_0_0_0_3_1_1 + 2.57354497354501*G0_0_0_0_0_0_4_1_0 + 2.57354497354501*G0_0_0_0_0_0_5_1_1 - 2.57354497354501*G0_0_0_0_0_1_0_0_0 - 2.57354497354501*G0_0_0_0_0_1_0_0_1 + 2.57354497354501*G0_0_0_0_0_1_1_0_0 + 2.57354497354501*G0_0_0_0_0_1_2_0_1 - 2.57354497354501*G0_0_0_0_0_1_3_1_0 - 2.57354497354501*G0_0_0_0_0_1_3_1_1 + 2.57354497354501*G0_0_0_0_0_1_4_1_0 + 2.57354497354501*G0_0_0_0_0_1_5_1_1 + 2.57354497354501*G0_0_0_1_0_0_0_0_0 + 2.57354497354501*G0_0_0_1_0_0_0_0_1 - 2.57354497354501*G0_0_0_1_0_0_1_0_0 - 2.57354497354501*G0_0_0_1_0_0_2_0_1 + 2.57354497354501*G0_0_0_1_0_0_3_1_0 + 2.57354497354501*G0_0_0_1_0_0_3_1_1 - 2.57354497354501*G0_0_0_1_0_0_4_1_0 - 2.57354497354501*G0_0_0_1_0_0_5_1_1 + 2.57354497354501*G0_0_0_2_0_1_0_0_0 + 2.57354497354501*G0_0_0_2_0_1_0_0_1 - 2.57354497354501*G0_0_0_2_0_1_1_0_0 - 2.57354497354501*G0_0_0_2_0_1_2_0_1 + 2.57354497354501*G0_0_0_2_0_1_3_1_0 + 2.57354497354501*G0_0_0_2_0_1_3_1_1 - 2.57354497354501*G0_0_0_2_0_1_4_1_0 - 2.57354497354501*G0_0_0_2_0_1_5_1_1 - 2.57354497354501*G0_0_0_3_1_0_0_0_0 - 2.57354497354501*G0_0_0_3_1_0_0_0_1 + 2.57354497354501*G0_0_0_3_1_0_1_0_0 + 2.57354497354501*G0_0_0_3_1_0_2_0_1 - 2.57354497354501*G0_0_0_3_1_0_3_1_0 - 2.57354497354501*G0_0_0_3_1_0_3_1_1 + 2.57354497354501*G0_0_0_3_1_0_4_1_0 + 2.57354497354501*G0_0_0_3_1_0_5_1_1 - 2.57354497354501*G0_0_0_3_1_1_0_0_0 - 2.57354497354501*G0_0_0_3_1_1_0_0_1 + 2.57354497354501*G0_0_0_3_1_1_1_0_0 + 2.57354497354501*G0_0_0_3_1_1_2_0_1 - 2.57354497354501*G0_0_0_3_1_1_3_1_0 - 2.57354497354501*G0_0_0_3_1_1_3_1_1 + 2.57354497354501*G0_0_0_3_1_1_4_1_0 + 2.57354497354501*G0_0_0_3_1_1_5_1_1 + 2.57354497354501*G0_0_0_4_1_0_0_0_0 + 2.57354497354501*G0_0_0_4_1_0_0_0_1 - 2.57354497354501*G0_0_0_4_1_0_1_0_0 - 2.57354497354501*G0_0_0_4_1_0_2_0_1 + 2.57354497354501*G0_0_0_4_1_0_3_1_0 + 2.57354497354501*G0_0_0_4_1_0_3_1_1 - 2.57354497354501*G0_0_0_4_1_0_4_1_0 - 2.57354497354501*G0_0_0_4_1_0_5_1_1 + 2.57354497354501*G0_0_0_5_1_1_0_0_0 + 2.57354497354501*G0_0_0_5_1_1_0_0_1 - 2.57354497354501*G0_0_0_5_1_1_1_0_0 - 2.57354497354501*G0_0_0_5_1_1_2_0_1 + 2.57354497354501*G0_0_0_5_1_1_3_1_0 + 2.57354497354501*G0_0_0_5_1_1_3_1_1 - 2.57354497354501*G0_0_0_5_1_1_4_1_0 - 2.57354497354501*G0_0_0_5_1_1_5_1_1 + 2.57354497354501*G0_1_1_0_0_0_0_0_0 + 2.57354497354501*G0_1_1_0_0_0_0_0_1 - 2.57354497354501*G0_1_1_0_0_0_1_0_0 - 2.57354497354501*G0_1_1_0_0_0_2_0_1 + 2.57354497354501*G0_1_1_0_0_0_3_1_0 + 2.57354497354501*G0_1_1_0_0_0_3_1_1 - 2.57354497354501*G0_1_1_0_0_0_4_1_0 - 2.57354497354501*G0_1_1_0_0_0_5_1_1 + 2.57354497354501*G0_1_1_0_0_1_0_0_0 + 2.57354497354501*G0_1_1_0_0_1_0_0_1 - 2.57354497354501*G0_1_1_0_0_1_1_0_0 - 2.57354497354501*G0_1_1_0_0_1_2_0_1 + 2.57354497354501*G0_1_1_0_0_1_3_1_0 + 2.57354497354501*G0_1_1_0_0_1_3_1_1 - 2.57354497354501*G0_1_1_0_0_1_4_1_0 - 2.57354497354501*G0_1_1_0_0_1_5_1_1 - 2.57354497354501*G0_1_1_1_0_0_0_0_0 - 2.57354497354501*G0_1_1_1_0_0_0_0_1 + 2.57354497354501*G0_1_1_1_0_0_1_0_0 + 2.57354497354501*G0_1_1_1_0_0_2_0_1 - 2.57354497354501*G0_1_1_1_0_0_3_1_0 - 2.57354497354501*G0_1_1_1_0_0_3_1_1 + 2.57354497354501*G0_1_1_1_0_0_4_1_0 + 2.57354497354501*G0_1_1_1_0_0_5_1_1 - 2.57354497354501*G0_1_1_2_0_1_0_0_0 - 2.57354497354501*G0_1_1_2_0_1_0_0_1 + 2.57354497354501*G0_1_1_2_0_1_1_0_0 + 2.57354497354501*G0_1_1_2_0_1_2_0_1 - 2.57354497354501*G0_1_1_2_0_1_3_1_0 - 2.57354497354501*G0_1_1_2_0_1_3_1_1 + 2.57354497354501*G0_1_1_2_0_1_4_1_0 + 2.57354497354501*G0_1_1_2_0_1_5_1_1 + 2.57354497354501*G0_1_1_3_1_0_0_0_0 + 2.57354497354501*G0_1_1_3_1_0_0_0_1 - 2.57354497354501*G0_1_1_3_1_0_1_0_0 - 2.57354497354501*G0_1_1_3_1_0_2_0_1 + 2.57354497354501*G0_1_1_3_1_0_3_1_0 + 2.57354497354501*G0_1_1_3_1_0_3_1_1 - 2.57354497354501*G0_1_1_3_1_0_4_1_0 - 2.57354497354501*G0_1_1_3_1_0_5_1_1 + 2.57354497354501*G0_1_1_3_1_1_0_0_0 + 2.57354497354501*G0_1_1_3_1_1_0_0_1 - 2.57354497354501*G0_1_1_3_1_1_1_0_0 - 2.57354497354501*G0_1_1_3_1_1_2_0_1 + 2.57354497354501*G0_1_1_3_1_1_3_1_0 + 2.57354497354501*G0_1_1_3_1_1_3_1_1 - 2.57354497354501*G0_1_1_3_1_1_4_1_0 - 2.57354497354501*G0_1_1_3_1_1_5_1_1 - 2.57354497354501*G0_1_1_4_1_0_0_0_0 - 2.57354497354501*G0_1_1_4_1_0_0_0_1 + 2.57354497354501*G0_1_1_4_1_0_1_0_0 + 2.57354497354501*G0_1_1_4_1_0_2_0_1 - 2.57354497354501*G0_1_1_4_1_0_3_1_0 - 2.57354497354501*G0_1_1_4_1_0_3_1_1 + 2.57354497354501*G0_1_1_4_1_0_4_1_0 + 2.57354497354501*G0_1_1_4_1_0_5_1_1 - 2.57354497354501*G0_1_1_5_1_1_0_0_0 - 2.57354497354501*G0_1_1_5_1_1_0_0_1 + 2.57354497354501*G0_1_1_5_1_1_1_0_0 + 2.57354497354501*G0_1_1_5_1_1_2_0_1 - 2.57354497354501*G0_1_1_5_1_1_3_1_0 - 2.57354497354501*G0_1_1_5_1_1_3_1_1 + 2.57354497354501*G0_1_1_5_1_1_4_1_0 + 2.57354497354501*G0_1_1_5_1_1_5_1_1; + A[140] = 0.0; + A[514] = 0.0; + A[623] = A[245]; + A[543] = 0.0; + A[665] = 0.0; + A[569] = -A[252] + 0.812698412698417*G0_0_0_0_0_0_0_0_0 + 0.812698412698417*G0_0_0_0_0_0_0_0_1 - 0.812698412698417*G0_0_0_0_0_0_1_0_0 - 0.812698412698417*G0_0_0_0_0_0_2_0_1 + 0.812698412698417*G0_0_0_0_0_0_3_1_0 + 0.812698412698417*G0_0_0_0_0_0_3_1_1 - 0.812698412698417*G0_0_0_0_0_0_4_1_0 - 0.812698412698417*G0_0_0_0_0_0_5_1_1 + 0.812698412698417*G0_0_0_0_0_1_0_0_0 + 0.812698412698417*G0_0_0_0_0_1_0_0_1 - 0.812698412698417*G0_0_0_0_0_1_1_0_0 - 0.812698412698417*G0_0_0_0_0_1_2_0_1 + 0.812698412698417*G0_0_0_0_0_1_3_1_0 + 0.812698412698417*G0_0_0_0_0_1_3_1_1 - 0.812698412698417*G0_0_0_0_0_1_4_1_0 - 0.812698412698417*G0_0_0_0_0_1_5_1_1 - 0.812698412698417*G0_0_0_1_0_0_0_0_0 - 0.812698412698417*G0_0_0_1_0_0_0_0_1 + 0.812698412698417*G0_0_0_1_0_0_1_0_0 + 0.812698412698417*G0_0_0_1_0_0_2_0_1 - 0.812698412698417*G0_0_0_1_0_0_3_1_0 - 0.812698412698417*G0_0_0_1_0_0_3_1_1 + 0.812698412698417*G0_0_0_1_0_0_4_1_0 + 0.812698412698417*G0_0_0_1_0_0_5_1_1 - 0.812698412698417*G0_0_0_2_0_1_0_0_0 - 0.812698412698417*G0_0_0_2_0_1_0_0_1 + 0.812698412698417*G0_0_0_2_0_1_1_0_0 + 0.812698412698417*G0_0_0_2_0_1_2_0_1 - 0.812698412698417*G0_0_0_2_0_1_3_1_0 - 0.812698412698417*G0_0_0_2_0_1_3_1_1 + 0.812698412698417*G0_0_0_2_0_1_4_1_0 + 0.812698412698417*G0_0_0_2_0_1_5_1_1 + 0.812698412698417*G0_0_0_3_1_0_0_0_0 + 0.812698412698417*G0_0_0_3_1_0_0_0_1 - 0.812698412698417*G0_0_0_3_1_0_1_0_0 - 0.812698412698417*G0_0_0_3_1_0_2_0_1 + 0.812698412698417*G0_0_0_3_1_0_3_1_0 + 0.812698412698417*G0_0_0_3_1_0_3_1_1 - 0.812698412698417*G0_0_0_3_1_0_4_1_0 - 0.812698412698417*G0_0_0_3_1_0_5_1_1 + 0.812698412698417*G0_0_0_3_1_1_0_0_0 + 0.812698412698417*G0_0_0_3_1_1_0_0_1 - 0.812698412698417*G0_0_0_3_1_1_1_0_0 - 0.812698412698417*G0_0_0_3_1_1_2_0_1 + 0.812698412698417*G0_0_0_3_1_1_3_1_0 + 0.812698412698417*G0_0_0_3_1_1_3_1_1 - 0.812698412698417*G0_0_0_3_1_1_4_1_0 - 0.812698412698417*G0_0_0_3_1_1_5_1_1 - 0.812698412698417*G0_0_0_4_1_0_0_0_0 - 0.812698412698417*G0_0_0_4_1_0_0_0_1 + 0.812698412698417*G0_0_0_4_1_0_1_0_0 + 0.812698412698417*G0_0_0_4_1_0_2_0_1 - 0.812698412698417*G0_0_0_4_1_0_3_1_0 - 0.812698412698417*G0_0_0_4_1_0_3_1_1 + 0.812698412698417*G0_0_0_4_1_0_4_1_0 + 0.812698412698417*G0_0_0_4_1_0_5_1_1 - 0.812698412698417*G0_0_0_5_1_1_0_0_0 - 0.812698412698417*G0_0_0_5_1_1_0_0_1 + 0.812698412698417*G0_0_0_5_1_1_1_0_0 + 0.812698412698417*G0_0_0_5_1_1_2_0_1 - 0.812698412698417*G0_0_0_5_1_1_3_1_0 - 0.812698412698417*G0_0_0_5_1_1_3_1_1 + 0.812698412698417*G0_0_0_5_1_1_4_1_0 + 0.812698412698417*G0_0_0_5_1_1_5_1_1 + 0.13544973544974*G0_1_1_0_0_0_0_0_0 + 0.13544973544974*G0_1_1_0_0_0_0_0_1 - 0.13544973544974*G0_1_1_0_0_0_1_0_0 - 0.13544973544974*G0_1_1_0_0_0_2_0_1 + 0.13544973544974*G0_1_1_0_0_0_3_1_0 + 0.13544973544974*G0_1_1_0_0_0_3_1_1 - 0.13544973544974*G0_1_1_0_0_0_4_1_0 - 0.13544973544974*G0_1_1_0_0_0_5_1_1 + 0.13544973544974*G0_1_1_0_0_1_0_0_0 + 0.13544973544974*G0_1_1_0_0_1_0_0_1 - 0.13544973544974*G0_1_1_0_0_1_1_0_0 - 0.13544973544974*G0_1_1_0_0_1_2_0_1 + 0.13544973544974*G0_1_1_0_0_1_3_1_0 + 0.13544973544974*G0_1_1_0_0_1_3_1_1 - 0.13544973544974*G0_1_1_0_0_1_4_1_0 - 0.13544973544974*G0_1_1_0_0_1_5_1_1 - 0.13544973544974*G0_1_1_1_0_0_0_0_0 - 0.13544973544974*G0_1_1_1_0_0_0_0_1 + 0.13544973544974*G0_1_1_1_0_0_1_0_0 + 0.13544973544974*G0_1_1_1_0_0_2_0_1 - 0.13544973544974*G0_1_1_1_0_0_3_1_0 - 0.13544973544974*G0_1_1_1_0_0_3_1_1 + 0.13544973544974*G0_1_1_1_0_0_4_1_0 + 0.13544973544974*G0_1_1_1_0_0_5_1_1 - 0.13544973544974*G0_1_1_2_0_1_0_0_0 - 0.13544973544974*G0_1_1_2_0_1_0_0_1 + 0.13544973544974*G0_1_1_2_0_1_1_0_0 + 0.13544973544974*G0_1_1_2_0_1_2_0_1 - 0.13544973544974*G0_1_1_2_0_1_3_1_0 - 0.13544973544974*G0_1_1_2_0_1_3_1_1 + 0.13544973544974*G0_1_1_2_0_1_4_1_0 + 0.13544973544974*G0_1_1_2_0_1_5_1_1 + 0.13544973544974*G0_1_1_3_1_0_0_0_0 + 0.13544973544974*G0_1_1_3_1_0_0_0_1 - 0.13544973544974*G0_1_1_3_1_0_1_0_0 - 0.13544973544974*G0_1_1_3_1_0_2_0_1 + 0.13544973544974*G0_1_1_3_1_0_3_1_0 + 0.13544973544974*G0_1_1_3_1_0_3_1_1 - 0.13544973544974*G0_1_1_3_1_0_4_1_0 - 0.13544973544974*G0_1_1_3_1_0_5_1_1 + 0.13544973544974*G0_1_1_3_1_1_0_0_0 + 0.13544973544974*G0_1_1_3_1_1_0_0_1 - 0.13544973544974*G0_1_1_3_1_1_1_0_0 - 0.13544973544974*G0_1_1_3_1_1_2_0_1 + 0.13544973544974*G0_1_1_3_1_1_3_1_0 + 0.13544973544974*G0_1_1_3_1_1_3_1_1 - 0.13544973544974*G0_1_1_3_1_1_4_1_0 - 0.13544973544974*G0_1_1_3_1_1_5_1_1 - 0.13544973544974*G0_1_1_4_1_0_0_0_0 - 0.13544973544974*G0_1_1_4_1_0_0_0_1 + 0.13544973544974*G0_1_1_4_1_0_1_0_0 + 0.13544973544974*G0_1_1_4_1_0_2_0_1 - 0.13544973544974*G0_1_1_4_1_0_3_1_0 - 0.13544973544974*G0_1_1_4_1_0_3_1_1 + 0.13544973544974*G0_1_1_4_1_0_4_1_0 + 0.13544973544974*G0_1_1_4_1_0_5_1_1 - 0.13544973544974*G0_1_1_5_1_1_0_0_0 - 0.13544973544974*G0_1_1_5_1_1_0_0_1 + 0.13544973544974*G0_1_1_5_1_1_1_0_0 + 0.13544973544974*G0_1_1_5_1_1_2_0_1 - 0.13544973544974*G0_1_1_5_1_1_3_1_0 - 0.13544973544974*G0_1_1_5_1_1_3_1_1 + 0.13544973544974*G0_1_1_5_1_1_4_1_0 + 0.13544973544974*G0_1_1_5_1_1_5_1_1; + A[690] = 0.0; + A[267] = 0.0; + A[336] = A[656]; + A[296] = 0.0; + A[437] = 0.0; + A[361] = A[421]; + A[317] = 0.0; + A[470] = A[5]; + A[358] = 0.0; + A[808] = A[401]; + A[7] = A[5] + 0.425396825396828*G0_0_1_0_0_0_0_0_0 + 0.425396825396828*G0_0_1_0_0_0_0_0_1 - 0.425396825396828*G0_0_1_0_0_0_1_0_0 - 0.425396825396828*G0_0_1_0_0_0_2_0_1 + 0.425396825396828*G0_0_1_0_0_0_3_1_0 + 0.425396825396828*G0_0_1_0_0_0_3_1_1 - 0.425396825396828*G0_0_1_0_0_0_4_1_0 - 0.425396825396828*G0_0_1_0_0_0_5_1_1 + 0.425396825396828*G0_0_1_0_0_1_0_0_0 + 0.425396825396828*G0_0_1_0_0_1_0_0_1 - 0.425396825396828*G0_0_1_0_0_1_1_0_0 - 0.425396825396828*G0_0_1_0_0_1_2_0_1 + 0.425396825396828*G0_0_1_0_0_1_3_1_0 + 0.425396825396828*G0_0_1_0_0_1_3_1_1 - 0.425396825396828*G0_0_1_0_0_1_4_1_0 - 0.425396825396828*G0_0_1_0_0_1_5_1_1 - 0.425396825396828*G0_0_1_1_0_0_0_0_0 - 0.425396825396828*G0_0_1_1_0_0_0_0_1 + 0.425396825396828*G0_0_1_1_0_0_1_0_0 + 0.425396825396828*G0_0_1_1_0_0_2_0_1 - 0.425396825396828*G0_0_1_1_0_0_3_1_0 - 0.425396825396828*G0_0_1_1_0_0_3_1_1 + 0.425396825396828*G0_0_1_1_0_0_4_1_0 + 0.425396825396828*G0_0_1_1_0_0_5_1_1 - 0.425396825396828*G0_0_1_2_0_1_0_0_0 - 0.425396825396828*G0_0_1_2_0_1_0_0_1 + 0.425396825396828*G0_0_1_2_0_1_1_0_0 + 0.425396825396828*G0_0_1_2_0_1_2_0_1 - 0.425396825396828*G0_0_1_2_0_1_3_1_0 - 0.425396825396828*G0_0_1_2_0_1_3_1_1 + 0.425396825396828*G0_0_1_2_0_1_4_1_0 + 0.425396825396828*G0_0_1_2_0_1_5_1_1 + 0.425396825396828*G0_0_1_3_1_0_0_0_0 + 0.425396825396828*G0_0_1_3_1_0_0_0_1 - 0.425396825396828*G0_0_1_3_1_0_1_0_0 - 0.425396825396828*G0_0_1_3_1_0_2_0_1 + 0.425396825396828*G0_0_1_3_1_0_3_1_0 + 0.425396825396828*G0_0_1_3_1_0_3_1_1 - 0.425396825396828*G0_0_1_3_1_0_4_1_0 - 0.425396825396828*G0_0_1_3_1_0_5_1_1 + 0.425396825396828*G0_0_1_3_1_1_0_0_0 + 0.425396825396828*G0_0_1_3_1_1_0_0_1 - 0.425396825396828*G0_0_1_3_1_1_1_0_0 - 0.425396825396828*G0_0_1_3_1_1_2_0_1 + 0.425396825396828*G0_0_1_3_1_1_3_1_0 + 0.425396825396828*G0_0_1_3_1_1_3_1_1 - 0.425396825396828*G0_0_1_3_1_1_4_1_0 - 0.425396825396828*G0_0_1_3_1_1_5_1_1 - 0.425396825396828*G0_0_1_4_1_0_0_0_0 - 0.425396825396828*G0_0_1_4_1_0_0_0_1 + 0.425396825396828*G0_0_1_4_1_0_1_0_0 + 0.425396825396828*G0_0_1_4_1_0_2_0_1 - 0.425396825396828*G0_0_1_4_1_0_3_1_0 - 0.425396825396828*G0_0_1_4_1_0_3_1_1 + 0.425396825396828*G0_0_1_4_1_0_4_1_0 + 0.425396825396828*G0_0_1_4_1_0_5_1_1 - 0.425396825396828*G0_0_1_5_1_1_0_0_0 - 0.425396825396828*G0_0_1_5_1_1_0_0_1 + 0.425396825396828*G0_0_1_5_1_1_1_0_0 + 0.425396825396828*G0_0_1_5_1_1_2_0_1 - 0.425396825396828*G0_0_1_5_1_1_3_1_0 - 0.425396825396828*G0_0_1_5_1_1_3_1_1 + 0.425396825396828*G0_0_1_5_1_1_4_1_0 + 0.425396825396828*G0_0_1_5_1_1_5_1_1 + 0.425396825396829*G0_1_1_0_0_0_0_0_0 + 0.425396825396829*G0_1_1_0_0_0_0_0_1 - 0.425396825396829*G0_1_1_0_0_0_1_0_0 - 0.425396825396829*G0_1_1_0_0_0_2_0_1 + 0.425396825396829*G0_1_1_0_0_0_3_1_0 + 0.425396825396829*G0_1_1_0_0_0_3_1_1 - 0.425396825396829*G0_1_1_0_0_0_4_1_0 - 0.425396825396829*G0_1_1_0_0_0_5_1_1 + 0.425396825396829*G0_1_1_0_0_1_0_0_0 + 0.425396825396829*G0_1_1_0_0_1_0_0_1 - 0.425396825396829*G0_1_1_0_0_1_1_0_0 - 0.425396825396829*G0_1_1_0_0_1_2_0_1 + 0.425396825396829*G0_1_1_0_0_1_3_1_0 + 0.425396825396829*G0_1_1_0_0_1_3_1_1 - 0.425396825396829*G0_1_1_0_0_1_4_1_0 - 0.425396825396829*G0_1_1_0_0_1_5_1_1 - 0.425396825396829*G0_1_1_1_0_0_0_0_0 - 0.425396825396829*G0_1_1_1_0_0_0_0_1 + 0.425396825396829*G0_1_1_1_0_0_1_0_0 + 0.425396825396829*G0_1_1_1_0_0_2_0_1 - 0.425396825396829*G0_1_1_1_0_0_3_1_0 - 0.425396825396829*G0_1_1_1_0_0_3_1_1 + 0.425396825396829*G0_1_1_1_0_0_4_1_0 + 0.425396825396829*G0_1_1_1_0_0_5_1_1 - 0.425396825396829*G0_1_1_2_0_1_0_0_0 - 0.425396825396829*G0_1_1_2_0_1_0_0_1 + 0.425396825396829*G0_1_1_2_0_1_1_0_0 + 0.425396825396829*G0_1_1_2_0_1_2_0_1 - 0.425396825396829*G0_1_1_2_0_1_3_1_0 - 0.425396825396829*G0_1_1_2_0_1_3_1_1 + 0.425396825396829*G0_1_1_2_0_1_4_1_0 + 0.425396825396829*G0_1_1_2_0_1_5_1_1 + 0.425396825396829*G0_1_1_3_1_0_0_0_0 + 0.425396825396829*G0_1_1_3_1_0_0_0_1 - 0.425396825396829*G0_1_1_3_1_0_1_0_0 - 0.425396825396829*G0_1_1_3_1_0_2_0_1 + 0.425396825396829*G0_1_1_3_1_0_3_1_0 + 0.425396825396829*G0_1_1_3_1_0_3_1_1 - 0.425396825396829*G0_1_1_3_1_0_4_1_0 - 0.425396825396829*G0_1_1_3_1_0_5_1_1 + 0.425396825396829*G0_1_1_3_1_1_0_0_0 + 0.425396825396829*G0_1_1_3_1_1_0_0_1 - 0.425396825396829*G0_1_1_3_1_1_1_0_0 - 0.425396825396829*G0_1_1_3_1_1_2_0_1 + 0.425396825396829*G0_1_1_3_1_1_3_1_0 + 0.425396825396829*G0_1_1_3_1_1_3_1_1 - 0.425396825396829*G0_1_1_3_1_1_4_1_0 - 0.425396825396829*G0_1_1_3_1_1_5_1_1 - 0.425396825396829*G0_1_1_4_1_0_0_0_0 - 0.425396825396829*G0_1_1_4_1_0_0_0_1 + 0.425396825396829*G0_1_1_4_1_0_1_0_0 + 0.425396825396829*G0_1_1_4_1_0_2_0_1 - 0.425396825396829*G0_1_1_4_1_0_3_1_0 - 0.425396825396829*G0_1_1_4_1_0_3_1_1 + 0.425396825396829*G0_1_1_4_1_0_4_1_0 + 0.425396825396829*G0_1_1_4_1_0_5_1_1 - 0.425396825396829*G0_1_1_5_1_1_0_0_0 - 0.425396825396829*G0_1_1_5_1_1_0_0_1 + 0.425396825396829*G0_1_1_5_1_1_1_0_0 + 0.425396825396829*G0_1_1_5_1_1_2_0_1 - 0.425396825396829*G0_1_1_5_1_1_3_1_0 - 0.425396825396829*G0_1_1_5_1_1_3_1_1 + 0.425396825396829*G0_1_1_5_1_1_4_1_0 + 0.425396825396829*G0_1_1_5_1_1_5_1_1; + A[724] = 0.0; + A[827] = A[887]; + A[36] = A[181]; + A[751] = 0.0; + A[866] = A[401]; + A[65] = A[530]; + A[786] = 0.0; + A[158] = A[245]; + A[897] = -A[569] - 1.69312169312175*G0_0_1_0_0_0_0_0_0 - 1.69312169312175*G0_0_1_0_0_0_0_0_1 + 1.69312169312175*G0_0_1_0_0_0_1_0_0 + 1.69312169312175*G0_0_1_0_0_0_2_0_1 - 1.69312169312175*G0_0_1_0_0_0_3_1_0 - 1.69312169312175*G0_0_1_0_0_0_3_1_1 + 1.69312169312175*G0_0_1_0_0_0_4_1_0 + 1.69312169312175*G0_0_1_0_0_0_5_1_1 - 1.69312169312175*G0_0_1_0_0_1_0_0_0 - 1.69312169312175*G0_0_1_0_0_1_0_0_1 + 1.69312169312175*G0_0_1_0_0_1_1_0_0 + 1.69312169312175*G0_0_1_0_0_1_2_0_1 - 1.69312169312175*G0_0_1_0_0_1_3_1_0 - 1.69312169312175*G0_0_1_0_0_1_3_1_1 + 1.69312169312175*G0_0_1_0_0_1_4_1_0 + 1.69312169312175*G0_0_1_0_0_1_5_1_1 + 1.69312169312175*G0_0_1_1_0_0_0_0_0 + 1.69312169312175*G0_0_1_1_0_0_0_0_1 - 1.69312169312175*G0_0_1_1_0_0_1_0_0 - 1.69312169312175*G0_0_1_1_0_0_2_0_1 + 1.69312169312175*G0_0_1_1_0_0_3_1_0 + 1.69312169312175*G0_0_1_1_0_0_3_1_1 - 1.69312169312175*G0_0_1_1_0_0_4_1_0 - 1.69312169312175*G0_0_1_1_0_0_5_1_1 + 1.69312169312175*G0_0_1_2_0_1_0_0_0 + 1.69312169312175*G0_0_1_2_0_1_0_0_1 - 1.69312169312175*G0_0_1_2_0_1_1_0_0 - 1.69312169312175*G0_0_1_2_0_1_2_0_1 + 1.69312169312175*G0_0_1_2_0_1_3_1_0 + 1.69312169312175*G0_0_1_2_0_1_3_1_1 - 1.69312169312175*G0_0_1_2_0_1_4_1_0 - 1.69312169312175*G0_0_1_2_0_1_5_1_1 - 1.69312169312175*G0_0_1_3_1_0_0_0_0 - 1.69312169312175*G0_0_1_3_1_0_0_0_1 + 1.69312169312175*G0_0_1_3_1_0_1_0_0 + 1.69312169312175*G0_0_1_3_1_0_2_0_1 - 1.69312169312175*G0_0_1_3_1_0_3_1_0 - 1.69312169312175*G0_0_1_3_1_0_3_1_1 + 1.69312169312175*G0_0_1_3_1_0_4_1_0 + 1.69312169312175*G0_0_1_3_1_0_5_1_1 - 1.69312169312175*G0_0_1_3_1_1_0_0_0 - 1.69312169312175*G0_0_1_3_1_1_0_0_1 + 1.69312169312175*G0_0_1_3_1_1_1_0_0 + 1.69312169312175*G0_0_1_3_1_1_2_0_1 - 1.69312169312175*G0_0_1_3_1_1_3_1_0 - 1.69312169312175*G0_0_1_3_1_1_3_1_1 + 1.69312169312175*G0_0_1_3_1_1_4_1_0 + 1.69312169312175*G0_0_1_3_1_1_5_1_1 + 1.69312169312175*G0_0_1_4_1_0_0_0_0 + 1.69312169312175*G0_0_1_4_1_0_0_0_1 - 1.69312169312175*G0_0_1_4_1_0_1_0_0 - 1.69312169312175*G0_0_1_4_1_0_2_0_1 + 1.69312169312175*G0_0_1_4_1_0_3_1_0 + 1.69312169312175*G0_0_1_4_1_0_3_1_1 - 1.69312169312175*G0_0_1_4_1_0_4_1_0 - 1.69312169312175*G0_0_1_4_1_0_5_1_1 + 1.69312169312175*G0_0_1_5_1_1_0_0_0 + 1.69312169312175*G0_0_1_5_1_1_0_0_1 - 1.69312169312175*G0_0_1_5_1_1_1_0_0 - 1.69312169312175*G0_0_1_5_1_1_2_0_1 + 1.69312169312175*G0_0_1_5_1_1_3_1_0 + 1.69312169312175*G0_0_1_5_1_1_3_1_1 - 1.69312169312175*G0_0_1_5_1_1_4_1_0 - 1.69312169312175*G0_0_1_5_1_1_5_1_1 - 1.69312169312172*G0_1_0_0_0_0_0_0_0 - 1.69312169312172*G0_1_0_0_0_0_0_0_1 + 1.69312169312172*G0_1_0_0_0_0_1_0_0 + 1.69312169312172*G0_1_0_0_0_0_2_0_1 - 1.69312169312172*G0_1_0_0_0_0_3_1_0 - 1.69312169312172*G0_1_0_0_0_0_3_1_1 + 1.69312169312172*G0_1_0_0_0_0_4_1_0 + 1.69312169312172*G0_1_0_0_0_0_5_1_1 - 1.69312169312172*G0_1_0_0_0_1_0_0_0 - 1.69312169312172*G0_1_0_0_0_1_0_0_1 + 1.69312169312172*G0_1_0_0_0_1_1_0_0 + 1.69312169312172*G0_1_0_0_0_1_2_0_1 - 1.69312169312172*G0_1_0_0_0_1_3_1_0 - 1.69312169312172*G0_1_0_0_0_1_3_1_1 + 1.69312169312172*G0_1_0_0_0_1_4_1_0 + 1.69312169312172*G0_1_0_0_0_1_5_1_1 + 1.69312169312172*G0_1_0_1_0_0_0_0_0 + 1.69312169312172*G0_1_0_1_0_0_0_0_1 - 1.69312169312172*G0_1_0_1_0_0_1_0_0 - 1.69312169312172*G0_1_0_1_0_0_2_0_1 + 1.69312169312172*G0_1_0_1_0_0_3_1_0 + 1.69312169312172*G0_1_0_1_0_0_3_1_1 - 1.69312169312172*G0_1_0_1_0_0_4_1_0 - 1.69312169312172*G0_1_0_1_0_0_5_1_1 + 1.69312169312172*G0_1_0_2_0_1_0_0_0 + 1.69312169312172*G0_1_0_2_0_1_0_0_1 - 1.69312169312172*G0_1_0_2_0_1_1_0_0 - 1.69312169312172*G0_1_0_2_0_1_2_0_1 + 1.69312169312172*G0_1_0_2_0_1_3_1_0 + 1.69312169312172*G0_1_0_2_0_1_3_1_1 - 1.69312169312172*G0_1_0_2_0_1_4_1_0 - 1.69312169312172*G0_1_0_2_0_1_5_1_1 - 1.69312169312172*G0_1_0_3_1_0_0_0_0 - 1.69312169312172*G0_1_0_3_1_0_0_0_1 + 1.69312169312172*G0_1_0_3_1_0_1_0_0 + 1.69312169312172*G0_1_0_3_1_0_2_0_1 - 1.69312169312172*G0_1_0_3_1_0_3_1_0 - 1.69312169312172*G0_1_0_3_1_0_3_1_1 + 1.69312169312172*G0_1_0_3_1_0_4_1_0 + 1.69312169312172*G0_1_0_3_1_0_5_1_1 - 1.69312169312172*G0_1_0_3_1_1_0_0_0 - 1.69312169312172*G0_1_0_3_1_1_0_0_1 + 1.69312169312172*G0_1_0_3_1_1_1_0_0 + 1.69312169312172*G0_1_0_3_1_1_2_0_1 - 1.69312169312172*G0_1_0_3_1_1_3_1_0 - 1.69312169312172*G0_1_0_3_1_1_3_1_1 + 1.69312169312172*G0_1_0_3_1_1_4_1_0 + 1.69312169312172*G0_1_0_3_1_1_5_1_1 + 1.69312169312172*G0_1_0_4_1_0_0_0_0 + 1.69312169312172*G0_1_0_4_1_0_0_0_1 - 1.69312169312172*G0_1_0_4_1_0_1_0_0 - 1.69312169312172*G0_1_0_4_1_0_2_0_1 + 1.69312169312172*G0_1_0_4_1_0_3_1_0 + 1.69312169312172*G0_1_0_4_1_0_3_1_1 - 1.69312169312172*G0_1_0_4_1_0_4_1_0 - 1.69312169312172*G0_1_0_4_1_0_5_1_1 + 1.69312169312172*G0_1_0_5_1_1_0_0_0 + 1.69312169312172*G0_1_0_5_1_1_0_0_1 - 1.69312169312172*G0_1_0_5_1_1_1_0_0 - 1.69312169312172*G0_1_0_5_1_1_2_0_1 + 1.69312169312172*G0_1_0_5_1_1_3_1_0 + 1.69312169312172*G0_1_0_5_1_1_3_1_1 - 1.69312169312172*G0_1_0_5_1_1_4_1_0 - 1.69312169312172*G0_1_0_5_1_1_5_1_1 - 4.06349206349214*G0_1_1_0_0_0_0_0_0 - 4.06349206349214*G0_1_1_0_0_0_0_0_1 + 4.06349206349214*G0_1_1_0_0_0_1_0_0 + 4.06349206349214*G0_1_1_0_0_0_2_0_1 - 4.06349206349214*G0_1_1_0_0_0_3_1_0 - 4.06349206349214*G0_1_1_0_0_0_3_1_1 + 4.06349206349214*G0_1_1_0_0_0_4_1_0 + 4.06349206349214*G0_1_1_0_0_0_5_1_1 - 4.06349206349214*G0_1_1_0_0_1_0_0_0 - 4.06349206349214*G0_1_1_0_0_1_0_0_1 + 4.06349206349214*G0_1_1_0_0_1_1_0_0 + 4.06349206349214*G0_1_1_0_0_1_2_0_1 - 4.06349206349214*G0_1_1_0_0_1_3_1_0 - 4.06349206349214*G0_1_1_0_0_1_3_1_1 + 4.06349206349214*G0_1_1_0_0_1_4_1_0 + 4.06349206349214*G0_1_1_0_0_1_5_1_1 + 4.06349206349214*G0_1_1_1_0_0_0_0_0 + 4.06349206349214*G0_1_1_1_0_0_0_0_1 - 4.06349206349214*G0_1_1_1_0_0_1_0_0 - 4.06349206349214*G0_1_1_1_0_0_2_0_1 + 4.06349206349214*G0_1_1_1_0_0_3_1_0 + 4.06349206349214*G0_1_1_1_0_0_3_1_1 - 4.06349206349214*G0_1_1_1_0_0_4_1_0 - 4.06349206349214*G0_1_1_1_0_0_5_1_1 + 4.06349206349214*G0_1_1_2_0_1_0_0_0 + 4.06349206349214*G0_1_1_2_0_1_0_0_1 - 4.06349206349214*G0_1_1_2_0_1_1_0_0 - 4.06349206349214*G0_1_1_2_0_1_2_0_1 + 4.06349206349214*G0_1_1_2_0_1_3_1_0 + 4.06349206349214*G0_1_1_2_0_1_3_1_1 - 4.06349206349214*G0_1_1_2_0_1_4_1_0 - 4.06349206349214*G0_1_1_2_0_1_5_1_1 - 4.06349206349214*G0_1_1_3_1_0_0_0_0 - 4.06349206349214*G0_1_1_3_1_0_0_0_1 + 4.06349206349214*G0_1_1_3_1_0_1_0_0 + 4.06349206349214*G0_1_1_3_1_0_2_0_1 - 4.06349206349214*G0_1_1_3_1_0_3_1_0 - 4.06349206349214*G0_1_1_3_1_0_3_1_1 + 4.06349206349214*G0_1_1_3_1_0_4_1_0 + 4.06349206349214*G0_1_1_3_1_0_5_1_1 - 4.06349206349214*G0_1_1_3_1_1_0_0_0 - 4.06349206349214*G0_1_1_3_1_1_0_0_1 + 4.06349206349214*G0_1_1_3_1_1_1_0_0 + 4.06349206349214*G0_1_1_3_1_1_2_0_1 - 4.06349206349214*G0_1_1_3_1_1_3_1_0 - 4.06349206349214*G0_1_1_3_1_1_3_1_1 + 4.06349206349214*G0_1_1_3_1_1_4_1_0 + 4.06349206349214*G0_1_1_3_1_1_5_1_1 + 4.06349206349214*G0_1_1_4_1_0_0_0_0 + 4.06349206349214*G0_1_1_4_1_0_0_0_1 - 4.06349206349214*G0_1_1_4_1_0_1_0_0 - 4.06349206349214*G0_1_1_4_1_0_2_0_1 + 4.06349206349214*G0_1_1_4_1_0_3_1_0 + 4.06349206349214*G0_1_1_4_1_0_3_1_1 - 4.06349206349214*G0_1_1_4_1_0_4_1_0 - 4.06349206349214*G0_1_1_4_1_0_5_1_1 + 4.06349206349214*G0_1_1_5_1_1_0_0_0 + 4.06349206349214*G0_1_1_5_1_1_0_0_1 - 4.06349206349214*G0_1_1_5_1_1_1_0_0 - 4.06349206349214*G0_1_1_5_1_1_2_0_1 + 4.06349206349214*G0_1_1_5_1_1_3_1_0 + 4.06349206349214*G0_1_1_5_1_1_3_1_1 - 4.06349206349214*G0_1_1_5_1_1_4_1_0 - 4.06349206349214*G0_1_1_5_1_1_5_1_1; + A[114] = 0.0; + A[139] = 0.0; + A[168] = 0.0; + A[502] = A[181]; + A[205] = 0.0; + A[573] = 0.0; + A[533] = -A[530] - 0.524867724867732*G0_1_1_0_0_0_0_0_0 - 0.524867724867732*G0_1_1_0_0_0_0_0_1 + 0.524867724867732*G0_1_1_0_0_0_1_0_0 + 0.524867724867732*G0_1_1_0_0_0_2_0_1 - 0.524867724867732*G0_1_1_0_0_0_3_1_0 - 0.524867724867732*G0_1_1_0_0_0_3_1_1 + 0.524867724867732*G0_1_1_0_0_0_4_1_0 + 0.524867724867732*G0_1_1_0_0_0_5_1_1 - 0.524867724867732*G0_1_1_0_0_1_0_0_0 - 0.524867724867732*G0_1_1_0_0_1_0_0_1 + 0.524867724867732*G0_1_1_0_0_1_1_0_0 + 0.524867724867732*G0_1_1_0_0_1_2_0_1 - 0.524867724867732*G0_1_1_0_0_1_3_1_0 - 0.524867724867732*G0_1_1_0_0_1_3_1_1 + 0.524867724867732*G0_1_1_0_0_1_4_1_0 + 0.524867724867732*G0_1_1_0_0_1_5_1_1 + 0.524867724867732*G0_1_1_1_0_0_0_0_0 + 0.524867724867732*G0_1_1_1_0_0_0_0_1 - 0.524867724867732*G0_1_1_1_0_0_1_0_0 - 0.524867724867732*G0_1_1_1_0_0_2_0_1 + 0.524867724867732*G0_1_1_1_0_0_3_1_0 + 0.524867724867732*G0_1_1_1_0_0_3_1_1 - 0.524867724867732*G0_1_1_1_0_0_4_1_0 - 0.524867724867732*G0_1_1_1_0_0_5_1_1 + 0.524867724867732*G0_1_1_2_0_1_0_0_0 + 0.524867724867732*G0_1_1_2_0_1_0_0_1 - 0.524867724867732*G0_1_1_2_0_1_1_0_0 - 0.524867724867732*G0_1_1_2_0_1_2_0_1 + 0.524867724867732*G0_1_1_2_0_1_3_1_0 + 0.524867724867732*G0_1_1_2_0_1_3_1_1 - 0.524867724867732*G0_1_1_2_0_1_4_1_0 - 0.524867724867732*G0_1_1_2_0_1_5_1_1 - 0.524867724867732*G0_1_1_3_1_0_0_0_0 - 0.524867724867732*G0_1_1_3_1_0_0_0_1 + 0.524867724867732*G0_1_1_3_1_0_1_0_0 + 0.524867724867732*G0_1_1_3_1_0_2_0_1 - 0.524867724867732*G0_1_1_3_1_0_3_1_0 - 0.524867724867732*G0_1_1_3_1_0_3_1_1 + 0.524867724867732*G0_1_1_3_1_0_4_1_0 + 0.524867724867732*G0_1_1_3_1_0_5_1_1 - 0.524867724867732*G0_1_1_3_1_1_0_0_0 - 0.524867724867732*G0_1_1_3_1_1_0_0_1 + 0.524867724867732*G0_1_1_3_1_1_1_0_0 + 0.524867724867732*G0_1_1_3_1_1_2_0_1 - 0.524867724867732*G0_1_1_3_1_1_3_1_0 - 0.524867724867732*G0_1_1_3_1_1_3_1_1 + 0.524867724867732*G0_1_1_3_1_1_4_1_0 + 0.524867724867732*G0_1_1_3_1_1_5_1_1 + 0.524867724867732*G0_1_1_4_1_0_0_0_0 + 0.524867724867732*G0_1_1_4_1_0_0_0_1 - 0.524867724867732*G0_1_1_4_1_0_1_0_0 - 0.524867724867732*G0_1_1_4_1_0_2_0_1 + 0.524867724867732*G0_1_1_4_1_0_3_1_0 + 0.524867724867732*G0_1_1_4_1_0_3_1_1 - 0.524867724867732*G0_1_1_4_1_0_4_1_0 - 0.524867724867732*G0_1_1_4_1_0_5_1_1 + 0.524867724867732*G0_1_1_5_1_1_0_0_0 + 0.524867724867732*G0_1_1_5_1_1_0_0_1 - 0.524867724867732*G0_1_1_5_1_1_1_0_0 - 0.524867724867732*G0_1_1_5_1_1_2_0_1 + 0.524867724867732*G0_1_1_5_1_1_3_1_0 + 0.524867724867732*G0_1_1_5_1_1_3_1_1 - 0.524867724867732*G0_1_1_5_1_1_4_1_0 - 0.524867724867732*G0_1_1_5_1_1_5_1_1; + A[238] = 0.0; + A[604] = 0.0; + A[715] = -A[625] - 0.220105820105839*G0_1_1_0_0_0_0_0_0 - 0.220105820105839*G0_1_1_0_0_0_0_0_1 + 0.220105820105839*G0_1_1_0_0_0_1_0_0 + 0.220105820105839*G0_1_1_0_0_0_2_0_1 - 0.220105820105839*G0_1_1_0_0_0_3_1_0 - 0.220105820105839*G0_1_1_0_0_0_3_1_1 + 0.220105820105839*G0_1_1_0_0_0_4_1_0 + 0.220105820105839*G0_1_1_0_0_0_5_1_1 - 0.220105820105839*G0_1_1_0_0_1_0_0_0 - 0.220105820105839*G0_1_1_0_0_1_0_0_1 + 0.220105820105839*G0_1_1_0_0_1_1_0_0 + 0.220105820105839*G0_1_1_0_0_1_2_0_1 - 0.220105820105839*G0_1_1_0_0_1_3_1_0 - 0.220105820105839*G0_1_1_0_0_1_3_1_1 + 0.220105820105839*G0_1_1_0_0_1_4_1_0 + 0.220105820105839*G0_1_1_0_0_1_5_1_1 + 0.220105820105839*G0_1_1_1_0_0_0_0_0 + 0.220105820105839*G0_1_1_1_0_0_0_0_1 - 0.220105820105839*G0_1_1_1_0_0_1_0_0 - 0.220105820105839*G0_1_1_1_0_0_2_0_1 + 0.220105820105839*G0_1_1_1_0_0_3_1_0 + 0.220105820105839*G0_1_1_1_0_0_3_1_1 - 0.220105820105839*G0_1_1_1_0_0_4_1_0 - 0.220105820105839*G0_1_1_1_0_0_5_1_1 + 0.220105820105839*G0_1_1_2_0_1_0_0_0 + 0.220105820105839*G0_1_1_2_0_1_0_0_1 - 0.220105820105839*G0_1_1_2_0_1_1_0_0 - 0.220105820105839*G0_1_1_2_0_1_2_0_1 + 0.220105820105839*G0_1_1_2_0_1_3_1_0 + 0.220105820105839*G0_1_1_2_0_1_3_1_1 - 0.220105820105839*G0_1_1_2_0_1_4_1_0 - 0.220105820105839*G0_1_1_2_0_1_5_1_1 - 0.220105820105839*G0_1_1_3_1_0_0_0_0 - 0.220105820105839*G0_1_1_3_1_0_0_0_1 + 0.220105820105839*G0_1_1_3_1_0_1_0_0 + 0.220105820105839*G0_1_1_3_1_0_2_0_1 - 0.220105820105839*G0_1_1_3_1_0_3_1_0 - 0.220105820105839*G0_1_1_3_1_0_3_1_1 + 0.220105820105839*G0_1_1_3_1_0_4_1_0 + 0.220105820105839*G0_1_1_3_1_0_5_1_1 - 0.220105820105839*G0_1_1_3_1_1_0_0_0 - 0.220105820105839*G0_1_1_3_1_1_0_0_1 + 0.220105820105839*G0_1_1_3_1_1_1_0_0 + 0.220105820105839*G0_1_1_3_1_1_2_0_1 - 0.220105820105839*G0_1_1_3_1_1_3_1_0 - 0.220105820105839*G0_1_1_3_1_1_3_1_1 + 0.220105820105839*G0_1_1_3_1_1_4_1_0 + 0.220105820105839*G0_1_1_3_1_1_5_1_1 + 0.220105820105839*G0_1_1_4_1_0_0_0_0 + 0.220105820105839*G0_1_1_4_1_0_0_0_1 - 0.220105820105839*G0_1_1_4_1_0_1_0_0 - 0.220105820105839*G0_1_1_4_1_0_2_0_1 + 0.220105820105839*G0_1_1_4_1_0_3_1_0 + 0.220105820105839*G0_1_1_4_1_0_3_1_1 - 0.220105820105839*G0_1_1_4_1_0_4_1_0 - 0.220105820105839*G0_1_1_4_1_0_5_1_1 + 0.220105820105839*G0_1_1_5_1_1_0_0_0 + 0.220105820105839*G0_1_1_5_1_1_0_0_1 - 0.220105820105839*G0_1_1_5_1_1_1_0_0 - 0.220105820105839*G0_1_1_5_1_1_2_0_1 + 0.220105820105839*G0_1_1_5_1_1_3_1_0 + 0.220105820105839*G0_1_1_5_1_1_3_1_1 - 0.220105820105839*G0_1_1_5_1_1_4_1_0 - 0.220105820105839*G0_1_1_5_1_1_5_1_1; + A[709] = A[715] + 0.761904761904767*G0_0_0_0_0_0_0_0_0 + 0.761904761904767*G0_0_0_0_0_0_0_0_1 - 0.761904761904767*G0_0_0_0_0_0_1_0_0 - 0.761904761904767*G0_0_0_0_0_0_2_0_1 + 0.761904761904767*G0_0_0_0_0_0_3_1_0 + 0.761904761904767*G0_0_0_0_0_0_3_1_1 - 0.761904761904767*G0_0_0_0_0_0_4_1_0 - 0.761904761904767*G0_0_0_0_0_0_5_1_1 + 0.761904761904767*G0_0_0_0_0_1_0_0_0 + 0.761904761904767*G0_0_0_0_0_1_0_0_1 - 0.761904761904767*G0_0_0_0_0_1_1_0_0 - 0.761904761904767*G0_0_0_0_0_1_2_0_1 + 0.761904761904767*G0_0_0_0_0_1_3_1_0 + 0.761904761904767*G0_0_0_0_0_1_3_1_1 - 0.761904761904767*G0_0_0_0_0_1_4_1_0 - 0.761904761904767*G0_0_0_0_0_1_5_1_1 - 0.761904761904767*G0_0_0_1_0_0_0_0_0 - 0.761904761904767*G0_0_0_1_0_0_0_0_1 + 0.761904761904767*G0_0_0_1_0_0_1_0_0 + 0.761904761904767*G0_0_0_1_0_0_2_0_1 - 0.761904761904767*G0_0_0_1_0_0_3_1_0 - 0.761904761904767*G0_0_0_1_0_0_3_1_1 + 0.761904761904767*G0_0_0_1_0_0_4_1_0 + 0.761904761904767*G0_0_0_1_0_0_5_1_1 - 0.761904761904767*G0_0_0_2_0_1_0_0_0 - 0.761904761904767*G0_0_0_2_0_1_0_0_1 + 0.761904761904767*G0_0_0_2_0_1_1_0_0 + 0.761904761904767*G0_0_0_2_0_1_2_0_1 - 0.761904761904767*G0_0_0_2_0_1_3_1_0 - 0.761904761904767*G0_0_0_2_0_1_3_1_1 + 0.761904761904767*G0_0_0_2_0_1_4_1_0 + 0.761904761904767*G0_0_0_2_0_1_5_1_1 + 0.761904761904767*G0_0_0_3_1_0_0_0_0 + 0.761904761904767*G0_0_0_3_1_0_0_0_1 - 0.761904761904767*G0_0_0_3_1_0_1_0_0 - 0.761904761904767*G0_0_0_3_1_0_2_0_1 + 0.761904761904767*G0_0_0_3_1_0_3_1_0 + 0.761904761904767*G0_0_0_3_1_0_3_1_1 - 0.761904761904767*G0_0_0_3_1_0_4_1_0 - 0.761904761904767*G0_0_0_3_1_0_5_1_1 + 0.761904761904767*G0_0_0_3_1_1_0_0_0 + 0.761904761904767*G0_0_0_3_1_1_0_0_1 - 0.761904761904767*G0_0_0_3_1_1_1_0_0 - 0.761904761904767*G0_0_0_3_1_1_2_0_1 + 0.761904761904767*G0_0_0_3_1_1_3_1_0 + 0.761904761904767*G0_0_0_3_1_1_3_1_1 - 0.761904761904767*G0_0_0_3_1_1_4_1_0 - 0.761904761904767*G0_0_0_3_1_1_5_1_1 - 0.761904761904767*G0_0_0_4_1_0_0_0_0 - 0.761904761904767*G0_0_0_4_1_0_0_0_1 + 0.761904761904767*G0_0_0_4_1_0_1_0_0 + 0.761904761904767*G0_0_0_4_1_0_2_0_1 - 0.761904761904767*G0_0_0_4_1_0_3_1_0 - 0.761904761904767*G0_0_0_4_1_0_3_1_1 + 0.761904761904767*G0_0_0_4_1_0_4_1_0 + 0.761904761904767*G0_0_0_4_1_0_5_1_1 - 0.761904761904767*G0_0_0_5_1_1_0_0_0 - 0.761904761904767*G0_0_0_5_1_1_0_0_1 + 0.761904761904767*G0_0_0_5_1_1_1_0_0 + 0.761904761904767*G0_0_0_5_1_1_2_0_1 - 0.761904761904767*G0_0_0_5_1_1_3_1_0 - 0.761904761904767*G0_0_0_5_1_1_3_1_1 + 0.761904761904767*G0_0_0_5_1_1_4_1_0 + 0.761904761904767*G0_0_0_5_1_1_5_1_1 + 0.253968253968253*G0_0_1_0_0_0_0_0_0 + 0.253968253968253*G0_0_1_0_0_0_0_0_1 - 0.253968253968253*G0_0_1_0_0_0_1_0_0 - 0.253968253968253*G0_0_1_0_0_0_2_0_1 + 0.253968253968253*G0_0_1_0_0_0_3_1_0 + 0.253968253968253*G0_0_1_0_0_0_3_1_1 - 0.253968253968253*G0_0_1_0_0_0_4_1_0 - 0.253968253968253*G0_0_1_0_0_0_5_1_1 + 0.253968253968253*G0_0_1_0_0_1_0_0_0 + 0.253968253968253*G0_0_1_0_0_1_0_0_1 - 0.253968253968253*G0_0_1_0_0_1_1_0_0 - 0.253968253968253*G0_0_1_0_0_1_2_0_1 + 0.253968253968253*G0_0_1_0_0_1_3_1_0 + 0.253968253968253*G0_0_1_0_0_1_3_1_1 - 0.253968253968253*G0_0_1_0_0_1_4_1_0 - 0.253968253968253*G0_0_1_0_0_1_5_1_1 - 0.253968253968253*G0_0_1_1_0_0_0_0_0 - 0.253968253968253*G0_0_1_1_0_0_0_0_1 + 0.253968253968253*G0_0_1_1_0_0_1_0_0 + 0.253968253968253*G0_0_1_1_0_0_2_0_1 - 0.253968253968253*G0_0_1_1_0_0_3_1_0 - 0.253968253968253*G0_0_1_1_0_0_3_1_1 + 0.253968253968253*G0_0_1_1_0_0_4_1_0 + 0.253968253968253*G0_0_1_1_0_0_5_1_1 - 0.253968253968253*G0_0_1_2_0_1_0_0_0 - 0.253968253968253*G0_0_1_2_0_1_0_0_1 + 0.253968253968253*G0_0_1_2_0_1_1_0_0 + 0.253968253968253*G0_0_1_2_0_1_2_0_1 - 0.253968253968253*G0_0_1_2_0_1_3_1_0 - 0.253968253968253*G0_0_1_2_0_1_3_1_1 + 0.253968253968253*G0_0_1_2_0_1_4_1_0 + 0.253968253968253*G0_0_1_2_0_1_5_1_1 + 0.253968253968253*G0_0_1_3_1_0_0_0_0 + 0.253968253968253*G0_0_1_3_1_0_0_0_1 - 0.253968253968253*G0_0_1_3_1_0_1_0_0 - 0.253968253968253*G0_0_1_3_1_0_2_0_1 + 0.253968253968253*G0_0_1_3_1_0_3_1_0 + 0.253968253968253*G0_0_1_3_1_0_3_1_1 - 0.253968253968253*G0_0_1_3_1_0_4_1_0 - 0.253968253968253*G0_0_1_3_1_0_5_1_1 + 0.253968253968253*G0_0_1_3_1_1_0_0_0 + 0.253968253968253*G0_0_1_3_1_1_0_0_1 - 0.253968253968253*G0_0_1_3_1_1_1_0_0 - 0.253968253968253*G0_0_1_3_1_1_2_0_1 + 0.253968253968253*G0_0_1_3_1_1_3_1_0 + 0.253968253968253*G0_0_1_3_1_1_3_1_1 - 0.253968253968253*G0_0_1_3_1_1_4_1_0 - 0.253968253968253*G0_0_1_3_1_1_5_1_1 - 0.253968253968253*G0_0_1_4_1_0_0_0_0 - 0.253968253968253*G0_0_1_4_1_0_0_0_1 + 0.253968253968253*G0_0_1_4_1_0_1_0_0 + 0.253968253968253*G0_0_1_4_1_0_2_0_1 - 0.253968253968253*G0_0_1_4_1_0_3_1_0 - 0.253968253968253*G0_0_1_4_1_0_3_1_1 + 0.253968253968253*G0_0_1_4_1_0_4_1_0 + 0.253968253968253*G0_0_1_4_1_0_5_1_1 - 0.253968253968253*G0_0_1_5_1_1_0_0_0 - 0.253968253968253*G0_0_1_5_1_1_0_0_1 + 0.253968253968253*G0_0_1_5_1_1_1_0_0 + 0.253968253968253*G0_0_1_5_1_1_2_0_1 - 0.253968253968253*G0_0_1_5_1_1_3_1_0 - 0.253968253968253*G0_0_1_5_1_1_3_1_1 + 0.253968253968253*G0_0_1_5_1_1_4_1_0 + 0.253968253968253*G0_0_1_5_1_1_5_1_1 + 0.253968253968242*G0_1_0_0_0_0_0_0_0 + 0.253968253968242*G0_1_0_0_0_0_0_0_1 - 0.253968253968242*G0_1_0_0_0_0_1_0_0 - 0.253968253968242*G0_1_0_0_0_0_2_0_1 + 0.253968253968242*G0_1_0_0_0_0_3_1_0 + 0.253968253968242*G0_1_0_0_0_0_3_1_1 - 0.253968253968242*G0_1_0_0_0_0_4_1_0 - 0.253968253968242*G0_1_0_0_0_0_5_1_1 + 0.253968253968242*G0_1_0_0_0_1_0_0_0 + 0.253968253968242*G0_1_0_0_0_1_0_0_1 - 0.253968253968242*G0_1_0_0_0_1_1_0_0 - 0.253968253968242*G0_1_0_0_0_1_2_0_1 + 0.253968253968242*G0_1_0_0_0_1_3_1_0 + 0.253968253968242*G0_1_0_0_0_1_3_1_1 - 0.253968253968242*G0_1_0_0_0_1_4_1_0 - 0.253968253968242*G0_1_0_0_0_1_5_1_1 - 0.253968253968242*G0_1_0_1_0_0_0_0_0 - 0.253968253968242*G0_1_0_1_0_0_0_0_1 + 0.253968253968242*G0_1_0_1_0_0_1_0_0 + 0.253968253968242*G0_1_0_1_0_0_2_0_1 - 0.253968253968242*G0_1_0_1_0_0_3_1_0 - 0.253968253968242*G0_1_0_1_0_0_3_1_1 + 0.253968253968242*G0_1_0_1_0_0_4_1_0 + 0.253968253968242*G0_1_0_1_0_0_5_1_1 - 0.253968253968242*G0_1_0_2_0_1_0_0_0 - 0.253968253968242*G0_1_0_2_0_1_0_0_1 + 0.253968253968242*G0_1_0_2_0_1_1_0_0 + 0.253968253968242*G0_1_0_2_0_1_2_0_1 - 0.253968253968242*G0_1_0_2_0_1_3_1_0 - 0.253968253968242*G0_1_0_2_0_1_3_1_1 + 0.253968253968242*G0_1_0_2_0_1_4_1_0 + 0.253968253968242*G0_1_0_2_0_1_5_1_1 + 0.253968253968242*G0_1_0_3_1_0_0_0_0 + 0.253968253968242*G0_1_0_3_1_0_0_0_1 - 0.253968253968242*G0_1_0_3_1_0_1_0_0 - 0.253968253968242*G0_1_0_3_1_0_2_0_1 + 0.253968253968242*G0_1_0_3_1_0_3_1_0 + 0.253968253968242*G0_1_0_3_1_0_3_1_1 - 0.253968253968242*G0_1_0_3_1_0_4_1_0 - 0.253968253968242*G0_1_0_3_1_0_5_1_1 + 0.253968253968242*G0_1_0_3_1_1_0_0_0 + 0.253968253968242*G0_1_0_3_1_1_0_0_1 - 0.253968253968242*G0_1_0_3_1_1_1_0_0 - 0.253968253968242*G0_1_0_3_1_1_2_0_1 + 0.253968253968242*G0_1_0_3_1_1_3_1_0 + 0.253968253968242*G0_1_0_3_1_1_3_1_1 - 0.253968253968242*G0_1_0_3_1_1_4_1_0 - 0.253968253968242*G0_1_0_3_1_1_5_1_1 - 0.253968253968242*G0_1_0_4_1_0_0_0_0 - 0.253968253968242*G0_1_0_4_1_0_0_0_1 + 0.253968253968242*G0_1_0_4_1_0_1_0_0 + 0.253968253968242*G0_1_0_4_1_0_2_0_1 - 0.253968253968242*G0_1_0_4_1_0_3_1_0 - 0.253968253968242*G0_1_0_4_1_0_3_1_1 + 0.253968253968242*G0_1_0_4_1_0_4_1_0 + 0.253968253968242*G0_1_0_4_1_0_5_1_1 - 0.253968253968242*G0_1_0_5_1_1_0_0_0 - 0.253968253968242*G0_1_0_5_1_1_0_0_1 + 0.253968253968242*G0_1_0_5_1_1_1_0_0 + 0.253968253968242*G0_1_0_5_1_1_2_0_1 - 0.253968253968242*G0_1_0_5_1_1_3_1_0 - 0.253968253968242*G0_1_0_5_1_1_3_1_1 + 0.253968253968242*G0_1_0_5_1_1_4_1_0 + 0.253968253968242*G0_1_0_5_1_1_5_1_1; + A[125] = -A[709] + 1.11746031746033*G0_0_1_0_0_0_0_0_0 + 1.11746031746033*G0_0_1_0_0_0_0_0_1 - 1.11746031746033*G0_0_1_0_0_0_1_0_0 - 1.11746031746033*G0_0_1_0_0_0_2_0_1 + 1.11746031746033*G0_0_1_0_0_0_3_1_0 + 1.11746031746033*G0_0_1_0_0_0_3_1_1 - 1.11746031746033*G0_0_1_0_0_0_4_1_0 - 1.11746031746033*G0_0_1_0_0_0_5_1_1 + 1.11746031746033*G0_0_1_0_0_1_0_0_0 + 1.11746031746033*G0_0_1_0_0_1_0_0_1 - 1.11746031746033*G0_0_1_0_0_1_1_0_0 - 1.11746031746033*G0_0_1_0_0_1_2_0_1 + 1.11746031746033*G0_0_1_0_0_1_3_1_0 + 1.11746031746033*G0_0_1_0_0_1_3_1_1 - 1.11746031746033*G0_0_1_0_0_1_4_1_0 - 1.11746031746033*G0_0_1_0_0_1_5_1_1 - 1.11746031746033*G0_0_1_1_0_0_0_0_0 - 1.11746031746033*G0_0_1_1_0_0_0_0_1 + 1.11746031746033*G0_0_1_1_0_0_1_0_0 + 1.11746031746033*G0_0_1_1_0_0_2_0_1 - 1.11746031746033*G0_0_1_1_0_0_3_1_0 - 1.11746031746033*G0_0_1_1_0_0_3_1_1 + 1.11746031746033*G0_0_1_1_0_0_4_1_0 + 1.11746031746033*G0_0_1_1_0_0_5_1_1 - 1.11746031746033*G0_0_1_2_0_1_0_0_0 - 1.11746031746033*G0_0_1_2_0_1_0_0_1 + 1.11746031746033*G0_0_1_2_0_1_1_0_0 + 1.11746031746033*G0_0_1_2_0_1_2_0_1 - 1.11746031746033*G0_0_1_2_0_1_3_1_0 - 1.11746031746033*G0_0_1_2_0_1_3_1_1 + 1.11746031746033*G0_0_1_2_0_1_4_1_0 + 1.11746031746033*G0_0_1_2_0_1_5_1_1 + 1.11746031746033*G0_0_1_3_1_0_0_0_0 + 1.11746031746033*G0_0_1_3_1_0_0_0_1 - 1.11746031746033*G0_0_1_3_1_0_1_0_0 - 1.11746031746033*G0_0_1_3_1_0_2_0_1 + 1.11746031746033*G0_0_1_3_1_0_3_1_0 + 1.11746031746033*G0_0_1_3_1_0_3_1_1 - 1.11746031746033*G0_0_1_3_1_0_4_1_0 - 1.11746031746033*G0_0_1_3_1_0_5_1_1 + 1.11746031746033*G0_0_1_3_1_1_0_0_0 + 1.11746031746033*G0_0_1_3_1_1_0_0_1 - 1.11746031746033*G0_0_1_3_1_1_1_0_0 - 1.11746031746033*G0_0_1_3_1_1_2_0_1 + 1.11746031746033*G0_0_1_3_1_1_3_1_0 + 1.11746031746033*G0_0_1_3_1_1_3_1_1 - 1.11746031746033*G0_0_1_3_1_1_4_1_0 - 1.11746031746033*G0_0_1_3_1_1_5_1_1 - 1.11746031746033*G0_0_1_4_1_0_0_0_0 - 1.11746031746033*G0_0_1_4_1_0_0_0_1 + 1.11746031746033*G0_0_1_4_1_0_1_0_0 + 1.11746031746033*G0_0_1_4_1_0_2_0_1 - 1.11746031746033*G0_0_1_4_1_0_3_1_0 - 1.11746031746033*G0_0_1_4_1_0_3_1_1 + 1.11746031746033*G0_0_1_4_1_0_4_1_0 + 1.11746031746033*G0_0_1_4_1_0_5_1_1 - 1.11746031746033*G0_0_1_5_1_1_0_0_0 - 1.11746031746033*G0_0_1_5_1_1_0_0_1 + 1.11746031746033*G0_0_1_5_1_1_1_0_0 + 1.11746031746033*G0_0_1_5_1_1_2_0_1 - 1.11746031746033*G0_0_1_5_1_1_3_1_0 - 1.11746031746033*G0_0_1_5_1_1_3_1_1 + 1.11746031746033*G0_0_1_5_1_1_4_1_0 + 1.11746031746033*G0_0_1_5_1_1_5_1_1 - 0.728042328042336*G0_1_1_0_0_0_0_0_0 - 0.728042328042336*G0_1_1_0_0_0_0_0_1 + 0.728042328042336*G0_1_1_0_0_0_1_0_0 + 0.728042328042336*G0_1_1_0_0_0_2_0_1 - 0.728042328042336*G0_1_1_0_0_0_3_1_0 - 0.728042328042336*G0_1_1_0_0_0_3_1_1 + 0.728042328042336*G0_1_1_0_0_0_4_1_0 + 0.728042328042336*G0_1_1_0_0_0_5_1_1 - 0.728042328042336*G0_1_1_0_0_1_0_0_0 - 0.728042328042336*G0_1_1_0_0_1_0_0_1 + 0.728042328042336*G0_1_1_0_0_1_1_0_0 + 0.728042328042336*G0_1_1_0_0_1_2_0_1 - 0.728042328042336*G0_1_1_0_0_1_3_1_0 - 0.728042328042336*G0_1_1_0_0_1_3_1_1 + 0.728042328042336*G0_1_1_0_0_1_4_1_0 + 0.728042328042336*G0_1_1_0_0_1_5_1_1 + 0.728042328042336*G0_1_1_1_0_0_0_0_0 + 0.728042328042336*G0_1_1_1_0_0_0_0_1 - 0.728042328042336*G0_1_1_1_0_0_1_0_0 - 0.728042328042336*G0_1_1_1_0_0_2_0_1 + 0.728042328042336*G0_1_1_1_0_0_3_1_0 + 0.728042328042336*G0_1_1_1_0_0_3_1_1 - 0.728042328042336*G0_1_1_1_0_0_4_1_0 - 0.728042328042336*G0_1_1_1_0_0_5_1_1 + 0.728042328042336*G0_1_1_2_0_1_0_0_0 + 0.728042328042336*G0_1_1_2_0_1_0_0_1 - 0.728042328042336*G0_1_1_2_0_1_1_0_0 - 0.728042328042336*G0_1_1_2_0_1_2_0_1 + 0.728042328042336*G0_1_1_2_0_1_3_1_0 + 0.728042328042336*G0_1_1_2_0_1_3_1_1 - 0.728042328042336*G0_1_1_2_0_1_4_1_0 - 0.728042328042336*G0_1_1_2_0_1_5_1_1 - 0.728042328042336*G0_1_1_3_1_0_0_0_0 - 0.728042328042336*G0_1_1_3_1_0_0_0_1 + 0.728042328042336*G0_1_1_3_1_0_1_0_0 + 0.728042328042336*G0_1_1_3_1_0_2_0_1 - 0.728042328042336*G0_1_1_3_1_0_3_1_0 - 0.728042328042336*G0_1_1_3_1_0_3_1_1 + 0.728042328042336*G0_1_1_3_1_0_4_1_0 + 0.728042328042336*G0_1_1_3_1_0_5_1_1 - 0.728042328042336*G0_1_1_3_1_1_0_0_0 - 0.728042328042336*G0_1_1_3_1_1_0_0_1 + 0.728042328042336*G0_1_1_3_1_1_1_0_0 + 0.728042328042336*G0_1_1_3_1_1_2_0_1 - 0.728042328042336*G0_1_1_3_1_1_3_1_0 - 0.728042328042336*G0_1_1_3_1_1_3_1_1 + 0.728042328042336*G0_1_1_3_1_1_4_1_0 + 0.728042328042336*G0_1_1_3_1_1_5_1_1 + 0.728042328042336*G0_1_1_4_1_0_0_0_0 + 0.728042328042336*G0_1_1_4_1_0_0_0_1 - 0.728042328042336*G0_1_1_4_1_0_1_0_0 - 0.728042328042336*G0_1_1_4_1_0_2_0_1 + 0.728042328042336*G0_1_1_4_1_0_3_1_0 + 0.728042328042336*G0_1_1_4_1_0_3_1_1 - 0.728042328042336*G0_1_1_4_1_0_4_1_0 - 0.728042328042336*G0_1_1_4_1_0_5_1_1 + 0.728042328042336*G0_1_1_5_1_1_0_0_0 + 0.728042328042336*G0_1_1_5_1_1_0_0_1 - 0.728042328042336*G0_1_1_5_1_1_1_0_0 - 0.728042328042336*G0_1_1_5_1_1_2_0_1 + 0.728042328042336*G0_1_1_5_1_1_3_1_0 + 0.728042328042336*G0_1_1_5_1_1_3_1_1 - 0.728042328042336*G0_1_1_5_1_1_4_1_0 - 0.728042328042336*G0_1_1_5_1_1_5_1_1; + A[559] = A[125] + 0.101587301587305*G0_0_0_0_0_0_0_0_0 + 0.101587301587305*G0_0_0_0_0_0_0_0_1 - 0.101587301587305*G0_0_0_0_0_0_1_0_0 - 0.101587301587305*G0_0_0_0_0_0_2_0_1 + 0.101587301587305*G0_0_0_0_0_0_3_1_0 + 0.101587301587305*G0_0_0_0_0_0_3_1_1 - 0.101587301587305*G0_0_0_0_0_0_4_1_0 - 0.101587301587305*G0_0_0_0_0_0_5_1_1 + 0.101587301587305*G0_0_0_0_0_1_0_0_0 + 0.101587301587305*G0_0_0_0_0_1_0_0_1 - 0.101587301587305*G0_0_0_0_0_1_1_0_0 - 0.101587301587305*G0_0_0_0_0_1_2_0_1 + 0.101587301587305*G0_0_0_0_0_1_3_1_0 + 0.101587301587305*G0_0_0_0_0_1_3_1_1 - 0.101587301587305*G0_0_0_0_0_1_4_1_0 - 0.101587301587305*G0_0_0_0_0_1_5_1_1 - 0.101587301587305*G0_0_0_1_0_0_0_0_0 - 0.101587301587305*G0_0_0_1_0_0_0_0_1 + 0.101587301587305*G0_0_0_1_0_0_1_0_0 + 0.101587301587305*G0_0_0_1_0_0_2_0_1 - 0.101587301587305*G0_0_0_1_0_0_3_1_0 - 0.101587301587305*G0_0_0_1_0_0_3_1_1 + 0.101587301587305*G0_0_0_1_0_0_4_1_0 + 0.101587301587305*G0_0_0_1_0_0_5_1_1 - 0.101587301587305*G0_0_0_2_0_1_0_0_0 - 0.101587301587305*G0_0_0_2_0_1_0_0_1 + 0.101587301587305*G0_0_0_2_0_1_1_0_0 + 0.101587301587305*G0_0_0_2_0_1_2_0_1 - 0.101587301587305*G0_0_0_2_0_1_3_1_0 - 0.101587301587305*G0_0_0_2_0_1_3_1_1 + 0.101587301587305*G0_0_0_2_0_1_4_1_0 + 0.101587301587305*G0_0_0_2_0_1_5_1_1 + 0.101587301587305*G0_0_0_3_1_0_0_0_0 + 0.101587301587305*G0_0_0_3_1_0_0_0_1 - 0.101587301587305*G0_0_0_3_1_0_1_0_0 - 0.101587301587305*G0_0_0_3_1_0_2_0_1 + 0.101587301587305*G0_0_0_3_1_0_3_1_0 + 0.101587301587305*G0_0_0_3_1_0_3_1_1 - 0.101587301587305*G0_0_0_3_1_0_4_1_0 - 0.101587301587305*G0_0_0_3_1_0_5_1_1 + 0.101587301587305*G0_0_0_3_1_1_0_0_0 + 0.101587301587305*G0_0_0_3_1_1_0_0_1 - 0.101587301587305*G0_0_0_3_1_1_1_0_0 - 0.101587301587305*G0_0_0_3_1_1_2_0_1 + 0.101587301587305*G0_0_0_3_1_1_3_1_0 + 0.101587301587305*G0_0_0_3_1_1_3_1_1 - 0.101587301587305*G0_0_0_3_1_1_4_1_0 - 0.101587301587305*G0_0_0_3_1_1_5_1_1 - 0.101587301587305*G0_0_0_4_1_0_0_0_0 - 0.101587301587305*G0_0_0_4_1_0_0_0_1 + 0.101587301587305*G0_0_0_4_1_0_1_0_0 + 0.101587301587305*G0_0_0_4_1_0_2_0_1 - 0.101587301587305*G0_0_0_4_1_0_3_1_0 - 0.101587301587305*G0_0_0_4_1_0_3_1_1 + 0.101587301587305*G0_0_0_4_1_0_4_1_0 + 0.101587301587305*G0_0_0_4_1_0_5_1_1 - 0.101587301587305*G0_0_0_5_1_1_0_0_0 - 0.101587301587305*G0_0_0_5_1_1_0_0_1 + 0.101587301587305*G0_0_0_5_1_1_1_0_0 + 0.101587301587305*G0_0_0_5_1_1_2_0_1 - 0.101587301587305*G0_0_0_5_1_1_3_1_0 - 0.101587301587305*G0_0_0_5_1_1_3_1_1 + 0.101587301587305*G0_0_0_5_1_1_4_1_0 + 0.101587301587305*G0_0_0_5_1_1_5_1_1 - 0.101587301587309*G0_1_1_0_0_0_0_0_0 - 0.101587301587309*G0_1_1_0_0_0_0_0_1 + 0.101587301587309*G0_1_1_0_0_0_1_0_0 + 0.101587301587309*G0_1_1_0_0_0_2_0_1 - 0.101587301587309*G0_1_1_0_0_0_3_1_0 - 0.101587301587309*G0_1_1_0_0_0_3_1_1 + 0.101587301587309*G0_1_1_0_0_0_4_1_0 + 0.101587301587309*G0_1_1_0_0_0_5_1_1 - 0.101587301587309*G0_1_1_0_0_1_0_0_0 - 0.101587301587309*G0_1_1_0_0_1_0_0_1 + 0.101587301587309*G0_1_1_0_0_1_1_0_0 + 0.101587301587309*G0_1_1_0_0_1_2_0_1 - 0.101587301587309*G0_1_1_0_0_1_3_1_0 - 0.101587301587309*G0_1_1_0_0_1_3_1_1 + 0.101587301587309*G0_1_1_0_0_1_4_1_0 + 0.101587301587309*G0_1_1_0_0_1_5_1_1 + 0.101587301587309*G0_1_1_1_0_0_0_0_0 + 0.101587301587309*G0_1_1_1_0_0_0_0_1 - 0.101587301587309*G0_1_1_1_0_0_1_0_0 - 0.101587301587309*G0_1_1_1_0_0_2_0_1 + 0.101587301587309*G0_1_1_1_0_0_3_1_0 + 0.101587301587309*G0_1_1_1_0_0_3_1_1 - 0.101587301587309*G0_1_1_1_0_0_4_1_0 - 0.101587301587309*G0_1_1_1_0_0_5_1_1 + 0.101587301587309*G0_1_1_2_0_1_0_0_0 + 0.101587301587309*G0_1_1_2_0_1_0_0_1 - 0.101587301587309*G0_1_1_2_0_1_1_0_0 - 0.101587301587309*G0_1_1_2_0_1_2_0_1 + 0.101587301587309*G0_1_1_2_0_1_3_1_0 + 0.101587301587309*G0_1_1_2_0_1_3_1_1 - 0.101587301587309*G0_1_1_2_0_1_4_1_0 - 0.101587301587309*G0_1_1_2_0_1_5_1_1 - 0.101587301587309*G0_1_1_3_1_0_0_0_0 - 0.101587301587309*G0_1_1_3_1_0_0_0_1 + 0.101587301587309*G0_1_1_3_1_0_1_0_0 + 0.101587301587309*G0_1_1_3_1_0_2_0_1 - 0.101587301587309*G0_1_1_3_1_0_3_1_0 - 0.101587301587309*G0_1_1_3_1_0_3_1_1 + 0.101587301587309*G0_1_1_3_1_0_4_1_0 + 0.101587301587309*G0_1_1_3_1_0_5_1_1 - 0.101587301587309*G0_1_1_3_1_1_0_0_0 - 0.101587301587309*G0_1_1_3_1_1_0_0_1 + 0.101587301587309*G0_1_1_3_1_1_1_0_0 + 0.101587301587309*G0_1_1_3_1_1_2_0_1 - 0.101587301587309*G0_1_1_3_1_1_3_1_0 - 0.101587301587309*G0_1_1_3_1_1_3_1_1 + 0.101587301587309*G0_1_1_3_1_1_4_1_0 + 0.101587301587309*G0_1_1_3_1_1_5_1_1 + 0.101587301587309*G0_1_1_4_1_0_0_0_0 + 0.101587301587309*G0_1_1_4_1_0_0_0_1 - 0.101587301587309*G0_1_1_4_1_0_1_0_0 - 0.101587301587309*G0_1_1_4_1_0_2_0_1 + 0.101587301587309*G0_1_1_4_1_0_3_1_0 + 0.101587301587309*G0_1_1_4_1_0_3_1_1 - 0.101587301587309*G0_1_1_4_1_0_4_1_0 - 0.101587301587309*G0_1_1_4_1_0_5_1_1 + 0.101587301587309*G0_1_1_5_1_1_0_0_0 + 0.101587301587309*G0_1_1_5_1_1_0_0_1 - 0.101587301587309*G0_1_1_5_1_1_1_0_0 - 0.101587301587309*G0_1_1_5_1_1_2_0_1 + 0.101587301587309*G0_1_1_5_1_1_3_1_0 + 0.101587301587309*G0_1_1_5_1_1_3_1_1 - 0.101587301587309*G0_1_1_5_1_1_4_1_0 - 0.101587301587309*G0_1_1_5_1_1_5_1_1; + A[588] = A[559] - 1.11746031746033*G0_0_1_0_0_0_0_0_0 - 1.11746031746033*G0_0_1_0_0_0_0_0_1 + 1.11746031746033*G0_0_1_0_0_0_1_0_0 + 1.11746031746033*G0_0_1_0_0_0_2_0_1 - 1.11746031746033*G0_0_1_0_0_0_3_1_0 - 1.11746031746033*G0_0_1_0_0_0_3_1_1 + 1.11746031746033*G0_0_1_0_0_0_4_1_0 + 1.11746031746033*G0_0_1_0_0_0_5_1_1 - 1.11746031746033*G0_0_1_0_0_1_0_0_0 - 1.11746031746033*G0_0_1_0_0_1_0_0_1 + 1.11746031746033*G0_0_1_0_0_1_1_0_0 + 1.11746031746033*G0_0_1_0_0_1_2_0_1 - 1.11746031746033*G0_0_1_0_0_1_3_1_0 - 1.11746031746033*G0_0_1_0_0_1_3_1_1 + 1.11746031746033*G0_0_1_0_0_1_4_1_0 + 1.11746031746033*G0_0_1_0_0_1_5_1_1 + 1.11746031746033*G0_0_1_1_0_0_0_0_0 + 1.11746031746033*G0_0_1_1_0_0_0_0_1 - 1.11746031746033*G0_0_1_1_0_0_1_0_0 - 1.11746031746033*G0_0_1_1_0_0_2_0_1 + 1.11746031746033*G0_0_1_1_0_0_3_1_0 + 1.11746031746033*G0_0_1_1_0_0_3_1_1 - 1.11746031746033*G0_0_1_1_0_0_4_1_0 - 1.11746031746033*G0_0_1_1_0_0_5_1_1 + 1.11746031746033*G0_0_1_2_0_1_0_0_0 + 1.11746031746033*G0_0_1_2_0_1_0_0_1 - 1.11746031746033*G0_0_1_2_0_1_1_0_0 - 1.11746031746033*G0_0_1_2_0_1_2_0_1 + 1.11746031746033*G0_0_1_2_0_1_3_1_0 + 1.11746031746033*G0_0_1_2_0_1_3_1_1 - 1.11746031746033*G0_0_1_2_0_1_4_1_0 - 1.11746031746033*G0_0_1_2_0_1_5_1_1 - 1.11746031746033*G0_0_1_3_1_0_0_0_0 - 1.11746031746033*G0_0_1_3_1_0_0_0_1 + 1.11746031746033*G0_0_1_3_1_0_1_0_0 + 1.11746031746033*G0_0_1_3_1_0_2_0_1 - 1.11746031746033*G0_0_1_3_1_0_3_1_0 - 1.11746031746033*G0_0_1_3_1_0_3_1_1 + 1.11746031746033*G0_0_1_3_1_0_4_1_0 + 1.11746031746033*G0_0_1_3_1_0_5_1_1 - 1.11746031746033*G0_0_1_3_1_1_0_0_0 - 1.11746031746033*G0_0_1_3_1_1_0_0_1 + 1.11746031746033*G0_0_1_3_1_1_1_0_0 + 1.11746031746033*G0_0_1_3_1_1_2_0_1 - 1.11746031746033*G0_0_1_3_1_1_3_1_0 - 1.11746031746033*G0_0_1_3_1_1_3_1_1 + 1.11746031746033*G0_0_1_3_1_1_4_1_0 + 1.11746031746033*G0_0_1_3_1_1_5_1_1 + 1.11746031746033*G0_0_1_4_1_0_0_0_0 + 1.11746031746033*G0_0_1_4_1_0_0_0_1 - 1.11746031746033*G0_0_1_4_1_0_1_0_0 - 1.11746031746033*G0_0_1_4_1_0_2_0_1 + 1.11746031746033*G0_0_1_4_1_0_3_1_0 + 1.11746031746033*G0_0_1_4_1_0_3_1_1 - 1.11746031746033*G0_0_1_4_1_0_4_1_0 - 1.11746031746033*G0_0_1_4_1_0_5_1_1 + 1.11746031746033*G0_0_1_5_1_1_0_0_0 + 1.11746031746033*G0_0_1_5_1_1_0_0_1 - 1.11746031746033*G0_0_1_5_1_1_1_0_0 - 1.11746031746033*G0_0_1_5_1_1_2_0_1 + 1.11746031746033*G0_0_1_5_1_1_3_1_0 + 1.11746031746033*G0_0_1_5_1_1_3_1_1 - 1.11746031746033*G0_0_1_5_1_1_4_1_0 - 1.11746031746033*G0_0_1_5_1_1_5_1_1 + 1.11746031746033*G0_1_0_0_0_0_0_0_0 + 1.11746031746033*G0_1_0_0_0_0_0_0_1 - 1.11746031746033*G0_1_0_0_0_0_1_0_0 - 1.11746031746033*G0_1_0_0_0_0_2_0_1 + 1.11746031746033*G0_1_0_0_0_0_3_1_0 + 1.11746031746033*G0_1_0_0_0_0_3_1_1 - 1.11746031746033*G0_1_0_0_0_0_4_1_0 - 1.11746031746033*G0_1_0_0_0_0_5_1_1 + 1.11746031746033*G0_1_0_0_0_1_0_0_0 + 1.11746031746033*G0_1_0_0_0_1_0_0_1 - 1.11746031746033*G0_1_0_0_0_1_1_0_0 - 1.11746031746033*G0_1_0_0_0_1_2_0_1 + 1.11746031746033*G0_1_0_0_0_1_3_1_0 + 1.11746031746033*G0_1_0_0_0_1_3_1_1 - 1.11746031746033*G0_1_0_0_0_1_4_1_0 - 1.11746031746033*G0_1_0_0_0_1_5_1_1 - 1.11746031746033*G0_1_0_1_0_0_0_0_0 - 1.11746031746033*G0_1_0_1_0_0_0_0_1 + 1.11746031746033*G0_1_0_1_0_0_1_0_0 + 1.11746031746033*G0_1_0_1_0_0_2_0_1 - 1.11746031746033*G0_1_0_1_0_0_3_1_0 - 1.11746031746033*G0_1_0_1_0_0_3_1_1 + 1.11746031746033*G0_1_0_1_0_0_4_1_0 + 1.11746031746033*G0_1_0_1_0_0_5_1_1 - 1.11746031746033*G0_1_0_2_0_1_0_0_0 - 1.11746031746033*G0_1_0_2_0_1_0_0_1 + 1.11746031746033*G0_1_0_2_0_1_1_0_0 + 1.11746031746033*G0_1_0_2_0_1_2_0_1 - 1.11746031746033*G0_1_0_2_0_1_3_1_0 - 1.11746031746033*G0_1_0_2_0_1_3_1_1 + 1.11746031746033*G0_1_0_2_0_1_4_1_0 + 1.11746031746033*G0_1_0_2_0_1_5_1_1 + 1.11746031746033*G0_1_0_3_1_0_0_0_0 + 1.11746031746033*G0_1_0_3_1_0_0_0_1 - 1.11746031746033*G0_1_0_3_1_0_1_0_0 - 1.11746031746033*G0_1_0_3_1_0_2_0_1 + 1.11746031746033*G0_1_0_3_1_0_3_1_0 + 1.11746031746033*G0_1_0_3_1_0_3_1_1 - 1.11746031746033*G0_1_0_3_1_0_4_1_0 - 1.11746031746033*G0_1_0_3_1_0_5_1_1 + 1.11746031746033*G0_1_0_3_1_1_0_0_0 + 1.11746031746033*G0_1_0_3_1_1_0_0_1 - 1.11746031746033*G0_1_0_3_1_1_1_0_0 - 1.11746031746033*G0_1_0_3_1_1_2_0_1 + 1.11746031746033*G0_1_0_3_1_1_3_1_0 + 1.11746031746033*G0_1_0_3_1_1_3_1_1 - 1.11746031746033*G0_1_0_3_1_1_4_1_0 - 1.11746031746033*G0_1_0_3_1_1_5_1_1 - 1.11746031746033*G0_1_0_4_1_0_0_0_0 - 1.11746031746033*G0_1_0_4_1_0_0_0_1 + 1.11746031746033*G0_1_0_4_1_0_1_0_0 + 1.11746031746033*G0_1_0_4_1_0_2_0_1 - 1.11746031746033*G0_1_0_4_1_0_3_1_0 - 1.11746031746033*G0_1_0_4_1_0_3_1_1 + 1.11746031746033*G0_1_0_4_1_0_4_1_0 + 1.11746031746033*G0_1_0_4_1_0_5_1_1 - 1.11746031746033*G0_1_0_5_1_1_0_0_0 - 1.11746031746033*G0_1_0_5_1_1_0_0_1 + 1.11746031746033*G0_1_0_5_1_1_1_0_0 + 1.11746031746033*G0_1_0_5_1_1_2_0_1 - 1.11746031746033*G0_1_0_5_1_1_3_1_0 - 1.11746031746033*G0_1_0_5_1_1_3_1_1 + 1.11746031746033*G0_1_0_5_1_1_4_1_0 + 1.11746031746033*G0_1_0_5_1_1_5_1_1; + A[309] = A[125] - 1.1851851851852*G0_0_0_0_0_0_0_0_0 - 1.1851851851852*G0_0_0_0_0_0_0_0_1 + 1.1851851851852*G0_0_0_0_0_0_1_0_0 + 1.1851851851852*G0_0_0_0_0_0_2_0_1 - 1.1851851851852*G0_0_0_0_0_0_3_1_0 - 1.1851851851852*G0_0_0_0_0_0_3_1_1 + 1.1851851851852*G0_0_0_0_0_0_4_1_0 + 1.1851851851852*G0_0_0_0_0_0_5_1_1 - 1.1851851851852*G0_0_0_0_0_1_0_0_0 - 1.1851851851852*G0_0_0_0_0_1_0_0_1 + 1.1851851851852*G0_0_0_0_0_1_1_0_0 + 1.1851851851852*G0_0_0_0_0_1_2_0_1 - 1.1851851851852*G0_0_0_0_0_1_3_1_0 - 1.1851851851852*G0_0_0_0_0_1_3_1_1 + 1.1851851851852*G0_0_0_0_0_1_4_1_0 + 1.1851851851852*G0_0_0_0_0_1_5_1_1 + 1.1851851851852*G0_0_0_1_0_0_0_0_0 + 1.1851851851852*G0_0_0_1_0_0_0_0_1 - 1.1851851851852*G0_0_0_1_0_0_1_0_0 - 1.1851851851852*G0_0_0_1_0_0_2_0_1 + 1.1851851851852*G0_0_0_1_0_0_3_1_0 + 1.1851851851852*G0_0_0_1_0_0_3_1_1 - 1.1851851851852*G0_0_0_1_0_0_4_1_0 - 1.1851851851852*G0_0_0_1_0_0_5_1_1 + 1.1851851851852*G0_0_0_2_0_1_0_0_0 + 1.1851851851852*G0_0_0_2_0_1_0_0_1 - 1.1851851851852*G0_0_0_2_0_1_1_0_0 - 1.1851851851852*G0_0_0_2_0_1_2_0_1 + 1.1851851851852*G0_0_0_2_0_1_3_1_0 + 1.1851851851852*G0_0_0_2_0_1_3_1_1 - 1.1851851851852*G0_0_0_2_0_1_4_1_0 - 1.1851851851852*G0_0_0_2_0_1_5_1_1 - 1.1851851851852*G0_0_0_3_1_0_0_0_0 - 1.1851851851852*G0_0_0_3_1_0_0_0_1 + 1.1851851851852*G0_0_0_3_1_0_1_0_0 + 1.1851851851852*G0_0_0_3_1_0_2_0_1 - 1.1851851851852*G0_0_0_3_1_0_3_1_0 - 1.1851851851852*G0_0_0_3_1_0_3_1_1 + 1.1851851851852*G0_0_0_3_1_0_4_1_0 + 1.1851851851852*G0_0_0_3_1_0_5_1_1 - 1.1851851851852*G0_0_0_3_1_1_0_0_0 - 1.1851851851852*G0_0_0_3_1_1_0_0_1 + 1.1851851851852*G0_0_0_3_1_1_1_0_0 + 1.1851851851852*G0_0_0_3_1_1_2_0_1 - 1.1851851851852*G0_0_0_3_1_1_3_1_0 - 1.1851851851852*G0_0_0_3_1_1_3_1_1 + 1.1851851851852*G0_0_0_3_1_1_4_1_0 + 1.1851851851852*G0_0_0_3_1_1_5_1_1 + 1.1851851851852*G0_0_0_4_1_0_0_0_0 + 1.1851851851852*G0_0_0_4_1_0_0_0_1 - 1.1851851851852*G0_0_0_4_1_0_1_0_0 - 1.1851851851852*G0_0_0_4_1_0_2_0_1 + 1.1851851851852*G0_0_0_4_1_0_3_1_0 + 1.1851851851852*G0_0_0_4_1_0_3_1_1 - 1.1851851851852*G0_0_0_4_1_0_4_1_0 - 1.1851851851852*G0_0_0_4_1_0_5_1_1 + 1.1851851851852*G0_0_0_5_1_1_0_0_0 + 1.1851851851852*G0_0_0_5_1_1_0_0_1 - 1.1851851851852*G0_0_0_5_1_1_1_0_0 - 1.1851851851852*G0_0_0_5_1_1_2_0_1 + 1.1851851851852*G0_0_0_5_1_1_3_1_0 + 1.1851851851852*G0_0_0_5_1_1_3_1_1 - 1.1851851851852*G0_0_0_5_1_1_4_1_0 - 1.1851851851852*G0_0_0_5_1_1_5_1_1 - 2.30264550264553*G0_0_1_0_0_0_0_0_0 - 2.30264550264553*G0_0_1_0_0_0_0_0_1 + 2.30264550264553*G0_0_1_0_0_0_1_0_0 + 2.30264550264553*G0_0_1_0_0_0_2_0_1 - 2.30264550264553*G0_0_1_0_0_0_3_1_0 - 2.30264550264553*G0_0_1_0_0_0_3_1_1 + 2.30264550264553*G0_0_1_0_0_0_4_1_0 + 2.30264550264553*G0_0_1_0_0_0_5_1_1 - 2.30264550264553*G0_0_1_0_0_1_0_0_0 - 2.30264550264553*G0_0_1_0_0_1_0_0_1 + 2.30264550264553*G0_0_1_0_0_1_1_0_0 + 2.30264550264553*G0_0_1_0_0_1_2_0_1 - 2.30264550264553*G0_0_1_0_0_1_3_1_0 - 2.30264550264553*G0_0_1_0_0_1_3_1_1 + 2.30264550264553*G0_0_1_0_0_1_4_1_0 + 2.30264550264553*G0_0_1_0_0_1_5_1_1 + 2.30264550264553*G0_0_1_1_0_0_0_0_0 + 2.30264550264553*G0_0_1_1_0_0_0_0_1 - 2.30264550264553*G0_0_1_1_0_0_1_0_0 - 2.30264550264553*G0_0_1_1_0_0_2_0_1 + 2.30264550264553*G0_0_1_1_0_0_3_1_0 + 2.30264550264553*G0_0_1_1_0_0_3_1_1 - 2.30264550264553*G0_0_1_1_0_0_4_1_0 - 2.30264550264553*G0_0_1_1_0_0_5_1_1 + 2.30264550264553*G0_0_1_2_0_1_0_0_0 + 2.30264550264553*G0_0_1_2_0_1_0_0_1 - 2.30264550264553*G0_0_1_2_0_1_1_0_0 - 2.30264550264553*G0_0_1_2_0_1_2_0_1 + 2.30264550264553*G0_0_1_2_0_1_3_1_0 + 2.30264550264553*G0_0_1_2_0_1_3_1_1 - 2.30264550264553*G0_0_1_2_0_1_4_1_0 - 2.30264550264553*G0_0_1_2_0_1_5_1_1 - 2.30264550264553*G0_0_1_3_1_0_0_0_0 - 2.30264550264553*G0_0_1_3_1_0_0_0_1 + 2.30264550264553*G0_0_1_3_1_0_1_0_0 + 2.30264550264553*G0_0_1_3_1_0_2_0_1 - 2.30264550264553*G0_0_1_3_1_0_3_1_0 - 2.30264550264553*G0_0_1_3_1_0_3_1_1 + 2.30264550264553*G0_0_1_3_1_0_4_1_0 + 2.30264550264553*G0_0_1_3_1_0_5_1_1 - 2.30264550264553*G0_0_1_3_1_1_0_0_0 - 2.30264550264553*G0_0_1_3_1_1_0_0_1 + 2.30264550264553*G0_0_1_3_1_1_1_0_0 + 2.30264550264553*G0_0_1_3_1_1_2_0_1 - 2.30264550264553*G0_0_1_3_1_1_3_1_0 - 2.30264550264553*G0_0_1_3_1_1_3_1_1 + 2.30264550264553*G0_0_1_3_1_1_4_1_0 + 2.30264550264553*G0_0_1_3_1_1_5_1_1 + 2.30264550264553*G0_0_1_4_1_0_0_0_0 + 2.30264550264553*G0_0_1_4_1_0_0_0_1 - 2.30264550264553*G0_0_1_4_1_0_1_0_0 - 2.30264550264553*G0_0_1_4_1_0_2_0_1 + 2.30264550264553*G0_0_1_4_1_0_3_1_0 + 2.30264550264553*G0_0_1_4_1_0_3_1_1 - 2.30264550264553*G0_0_1_4_1_0_4_1_0 - 2.30264550264553*G0_0_1_4_1_0_5_1_1 + 2.30264550264553*G0_0_1_5_1_1_0_0_0 + 2.30264550264553*G0_0_1_5_1_1_0_0_1 - 2.30264550264553*G0_0_1_5_1_1_1_0_0 - 2.30264550264553*G0_0_1_5_1_1_2_0_1 + 2.30264550264553*G0_0_1_5_1_1_3_1_0 + 2.30264550264553*G0_0_1_5_1_1_3_1_1 - 2.30264550264553*G0_0_1_5_1_1_4_1_0 - 2.30264550264553*G0_0_1_5_1_1_5_1_1 - 0.0677248677248741*G0_1_0_0_0_0_0_0_0 - 0.0677248677248741*G0_1_0_0_0_0_0_0_1 + 0.0677248677248741*G0_1_0_0_0_0_1_0_0 + 0.0677248677248741*G0_1_0_0_0_0_2_0_1 - 0.0677248677248741*G0_1_0_0_0_0_3_1_0 - 0.0677248677248741*G0_1_0_0_0_0_3_1_1 + 0.0677248677248741*G0_1_0_0_0_0_4_1_0 + 0.0677248677248741*G0_1_0_0_0_0_5_1_1 - 0.0677248677248741*G0_1_0_0_0_1_0_0_0 - 0.0677248677248741*G0_1_0_0_0_1_0_0_1 + 0.0677248677248741*G0_1_0_0_0_1_1_0_0 + 0.0677248677248741*G0_1_0_0_0_1_2_0_1 - 0.0677248677248741*G0_1_0_0_0_1_3_1_0 - 0.0677248677248741*G0_1_0_0_0_1_3_1_1 + 0.0677248677248741*G0_1_0_0_0_1_4_1_0 + 0.0677248677248741*G0_1_0_0_0_1_5_1_1 + 0.0677248677248741*G0_1_0_1_0_0_0_0_0 + 0.0677248677248741*G0_1_0_1_0_0_0_0_1 - 0.0677248677248741*G0_1_0_1_0_0_1_0_0 - 0.0677248677248741*G0_1_0_1_0_0_2_0_1 + 0.0677248677248741*G0_1_0_1_0_0_3_1_0 + 0.0677248677248741*G0_1_0_1_0_0_3_1_1 - 0.0677248677248741*G0_1_0_1_0_0_4_1_0 - 0.0677248677248741*G0_1_0_1_0_0_5_1_1 + 0.0677248677248741*G0_1_0_2_0_1_0_0_0 + 0.0677248677248741*G0_1_0_2_0_1_0_0_1 - 0.0677248677248741*G0_1_0_2_0_1_1_0_0 - 0.0677248677248741*G0_1_0_2_0_1_2_0_1 + 0.0677248677248741*G0_1_0_2_0_1_3_1_0 + 0.0677248677248741*G0_1_0_2_0_1_3_1_1 - 0.0677248677248741*G0_1_0_2_0_1_4_1_0 - 0.0677248677248741*G0_1_0_2_0_1_5_1_1 - 0.0677248677248741*G0_1_0_3_1_0_0_0_0 - 0.0677248677248741*G0_1_0_3_1_0_0_0_1 + 0.0677248677248741*G0_1_0_3_1_0_1_0_0 + 0.0677248677248741*G0_1_0_3_1_0_2_0_1 - 0.0677248677248741*G0_1_0_3_1_0_3_1_0 - 0.0677248677248741*G0_1_0_3_1_0_3_1_1 + 0.0677248677248741*G0_1_0_3_1_0_4_1_0 + 0.0677248677248741*G0_1_0_3_1_0_5_1_1 - 0.0677248677248741*G0_1_0_3_1_1_0_0_0 - 0.0677248677248741*G0_1_0_3_1_1_0_0_1 + 0.0677248677248741*G0_1_0_3_1_1_1_0_0 + 0.0677248677248741*G0_1_0_3_1_1_2_0_1 - 0.0677248677248741*G0_1_0_3_1_1_3_1_0 - 0.0677248677248741*G0_1_0_3_1_1_3_1_1 + 0.0677248677248741*G0_1_0_3_1_1_4_1_0 + 0.0677248677248741*G0_1_0_3_1_1_5_1_1 + 0.0677248677248741*G0_1_0_4_1_0_0_0_0 + 0.0677248677248741*G0_1_0_4_1_0_0_0_1 - 0.0677248677248741*G0_1_0_4_1_0_1_0_0 - 0.0677248677248741*G0_1_0_4_1_0_2_0_1 + 0.0677248677248741*G0_1_0_4_1_0_3_1_0 + 0.0677248677248741*G0_1_0_4_1_0_3_1_1 - 0.0677248677248741*G0_1_0_4_1_0_4_1_0 - 0.0677248677248741*G0_1_0_4_1_0_5_1_1 + 0.0677248677248741*G0_1_0_5_1_1_0_0_0 + 0.0677248677248741*G0_1_0_5_1_1_0_0_1 - 0.0677248677248741*G0_1_0_5_1_1_1_0_0 - 0.0677248677248741*G0_1_0_5_1_1_2_0_1 + 0.0677248677248741*G0_1_0_5_1_1_3_1_0 + 0.0677248677248741*G0_1_0_5_1_1_3_1_1 - 0.0677248677248741*G0_1_0_5_1_1_4_1_0 - 0.0677248677248741*G0_1_0_5_1_1_5_1_1; + A[334] = A[709] - 0.829629629629638*G0_0_0_0_0_0_0_0_0 - 0.829629629629638*G0_0_0_0_0_0_0_0_1 + 0.829629629629638*G0_0_0_0_0_0_1_0_0 + 0.829629629629638*G0_0_0_0_0_0_2_0_1 - 0.829629629629638*G0_0_0_0_0_0_3_1_0 - 0.829629629629638*G0_0_0_0_0_0_3_1_1 + 0.829629629629638*G0_0_0_0_0_0_4_1_0 + 0.829629629629638*G0_0_0_0_0_0_5_1_1 - 0.829629629629638*G0_0_0_0_0_1_0_0_0 - 0.829629629629638*G0_0_0_0_0_1_0_0_1 + 0.829629629629638*G0_0_0_0_0_1_1_0_0 + 0.829629629629638*G0_0_0_0_0_1_2_0_1 - 0.829629629629638*G0_0_0_0_0_1_3_1_0 - 0.829629629629638*G0_0_0_0_0_1_3_1_1 + 0.829629629629638*G0_0_0_0_0_1_4_1_0 + 0.829629629629638*G0_0_0_0_0_1_5_1_1 + 0.829629629629638*G0_0_0_1_0_0_0_0_0 + 0.829629629629638*G0_0_0_1_0_0_0_0_1 - 0.829629629629638*G0_0_0_1_0_0_1_0_0 - 0.829629629629638*G0_0_0_1_0_0_2_0_1 + 0.829629629629638*G0_0_0_1_0_0_3_1_0 + 0.829629629629638*G0_0_0_1_0_0_3_1_1 - 0.829629629629638*G0_0_0_1_0_0_4_1_0 - 0.829629629629638*G0_0_0_1_0_0_5_1_1 + 0.829629629629638*G0_0_0_2_0_1_0_0_0 + 0.829629629629638*G0_0_0_2_0_1_0_0_1 - 0.829629629629638*G0_0_0_2_0_1_1_0_0 - 0.829629629629638*G0_0_0_2_0_1_2_0_1 + 0.829629629629638*G0_0_0_2_0_1_3_1_0 + 0.829629629629638*G0_0_0_2_0_1_3_1_1 - 0.829629629629638*G0_0_0_2_0_1_4_1_0 - 0.829629629629638*G0_0_0_2_0_1_5_1_1 - 0.829629629629638*G0_0_0_3_1_0_0_0_0 - 0.829629629629638*G0_0_0_3_1_0_0_0_1 + 0.829629629629638*G0_0_0_3_1_0_1_0_0 + 0.829629629629638*G0_0_0_3_1_0_2_0_1 - 0.829629629629638*G0_0_0_3_1_0_3_1_0 - 0.829629629629638*G0_0_0_3_1_0_3_1_1 + 0.829629629629638*G0_0_0_3_1_0_4_1_0 + 0.829629629629638*G0_0_0_3_1_0_5_1_1 - 0.829629629629638*G0_0_0_3_1_1_0_0_0 - 0.829629629629638*G0_0_0_3_1_1_0_0_1 + 0.829629629629638*G0_0_0_3_1_1_1_0_0 + 0.829629629629638*G0_0_0_3_1_1_2_0_1 - 0.829629629629638*G0_0_0_3_1_1_3_1_0 - 0.829629629629638*G0_0_0_3_1_1_3_1_1 + 0.829629629629638*G0_0_0_3_1_1_4_1_0 + 0.829629629629638*G0_0_0_3_1_1_5_1_1 + 0.829629629629638*G0_0_0_4_1_0_0_0_0 + 0.829629629629638*G0_0_0_4_1_0_0_0_1 - 0.829629629629638*G0_0_0_4_1_0_1_0_0 - 0.829629629629638*G0_0_0_4_1_0_2_0_1 + 0.829629629629638*G0_0_0_4_1_0_3_1_0 + 0.829629629629638*G0_0_0_4_1_0_3_1_1 - 0.829629629629638*G0_0_0_4_1_0_4_1_0 - 0.829629629629638*G0_0_0_4_1_0_5_1_1 + 0.829629629629638*G0_0_0_5_1_1_0_0_0 + 0.829629629629638*G0_0_0_5_1_1_0_0_1 - 0.829629629629638*G0_0_0_5_1_1_1_0_0 - 0.829629629629638*G0_0_0_5_1_1_2_0_1 + 0.829629629629638*G0_0_0_5_1_1_3_1_0 + 0.829629629629638*G0_0_0_5_1_1_3_1_1 - 0.829629629629638*G0_0_0_5_1_1_4_1_0 - 0.829629629629638*G0_0_0_5_1_1_5_1_1 + 0.829629629629645*G0_1_1_0_0_0_0_0_0 + 0.829629629629645*G0_1_1_0_0_0_0_0_1 - 0.829629629629645*G0_1_1_0_0_0_1_0_0 - 0.829629629629645*G0_1_1_0_0_0_2_0_1 + 0.829629629629645*G0_1_1_0_0_0_3_1_0 + 0.829629629629645*G0_1_1_0_0_0_3_1_1 - 0.829629629629645*G0_1_1_0_0_0_4_1_0 - 0.829629629629645*G0_1_1_0_0_0_5_1_1 + 0.829629629629645*G0_1_1_0_0_1_0_0_0 + 0.829629629629645*G0_1_1_0_0_1_0_0_1 - 0.829629629629645*G0_1_1_0_0_1_1_0_0 - 0.829629629629645*G0_1_1_0_0_1_2_0_1 + 0.829629629629645*G0_1_1_0_0_1_3_1_0 + 0.829629629629645*G0_1_1_0_0_1_3_1_1 - 0.829629629629645*G0_1_1_0_0_1_4_1_0 - 0.829629629629645*G0_1_1_0_0_1_5_1_1 - 0.829629629629645*G0_1_1_1_0_0_0_0_0 - 0.829629629629645*G0_1_1_1_0_0_0_0_1 + 0.829629629629645*G0_1_1_1_0_0_1_0_0 + 0.829629629629645*G0_1_1_1_0_0_2_0_1 - 0.829629629629645*G0_1_1_1_0_0_3_1_0 - 0.829629629629645*G0_1_1_1_0_0_3_1_1 + 0.829629629629645*G0_1_1_1_0_0_4_1_0 + 0.829629629629645*G0_1_1_1_0_0_5_1_1 - 0.829629629629645*G0_1_1_2_0_1_0_0_0 - 0.829629629629645*G0_1_1_2_0_1_0_0_1 + 0.829629629629645*G0_1_1_2_0_1_1_0_0 + 0.829629629629645*G0_1_1_2_0_1_2_0_1 - 0.829629629629645*G0_1_1_2_0_1_3_1_0 - 0.829629629629645*G0_1_1_2_0_1_3_1_1 + 0.829629629629645*G0_1_1_2_0_1_4_1_0 + 0.829629629629645*G0_1_1_2_0_1_5_1_1 + 0.829629629629645*G0_1_1_3_1_0_0_0_0 + 0.829629629629645*G0_1_1_3_1_0_0_0_1 - 0.829629629629645*G0_1_1_3_1_0_1_0_0 - 0.829629629629645*G0_1_1_3_1_0_2_0_1 + 0.829629629629645*G0_1_1_3_1_0_3_1_0 + 0.829629629629645*G0_1_1_3_1_0_3_1_1 - 0.829629629629645*G0_1_1_3_1_0_4_1_0 - 0.829629629629645*G0_1_1_3_1_0_5_1_1 + 0.829629629629645*G0_1_1_3_1_1_0_0_0 + 0.829629629629645*G0_1_1_3_1_1_0_0_1 - 0.829629629629645*G0_1_1_3_1_1_1_0_0 - 0.829629629629645*G0_1_1_3_1_1_2_0_1 + 0.829629629629645*G0_1_1_3_1_1_3_1_0 + 0.829629629629645*G0_1_1_3_1_1_3_1_1 - 0.829629629629645*G0_1_1_3_1_1_4_1_0 - 0.829629629629645*G0_1_1_3_1_1_5_1_1 - 0.829629629629645*G0_1_1_4_1_0_0_0_0 - 0.829629629629645*G0_1_1_4_1_0_0_0_1 + 0.829629629629645*G0_1_1_4_1_0_1_0_0 + 0.829629629629645*G0_1_1_4_1_0_2_0_1 - 0.829629629629645*G0_1_1_4_1_0_3_1_0 - 0.829629629629645*G0_1_1_4_1_0_3_1_1 + 0.829629629629645*G0_1_1_4_1_0_4_1_0 + 0.829629629629645*G0_1_1_4_1_0_5_1_1 - 0.829629629629645*G0_1_1_5_1_1_0_0_0 - 0.829629629629645*G0_1_1_5_1_1_0_0_1 + 0.829629629629645*G0_1_1_5_1_1_1_0_0 + 0.829629629629645*G0_1_1_5_1_1_2_0_1 - 0.829629629629645*G0_1_1_5_1_1_3_1_0 - 0.829629629629645*G0_1_1_5_1_1_3_1_1 + 0.829629629629645*G0_1_1_5_1_1_4_1_0 + 0.829629629629645*G0_1_1_5_1_1_5_1_1; + A[131] = A[334]; + A[805] = A[559] - 1.28677248677251*G0_0_0_0_0_0_0_0_0 - 1.28677248677251*G0_0_0_0_0_0_0_0_1 + 1.28677248677251*G0_0_0_0_0_0_1_0_0 + 1.28677248677251*G0_0_0_0_0_0_2_0_1 - 1.28677248677251*G0_0_0_0_0_0_3_1_0 - 1.28677248677251*G0_0_0_0_0_0_3_1_1 + 1.28677248677251*G0_0_0_0_0_0_4_1_0 + 1.28677248677251*G0_0_0_0_0_0_5_1_1 - 1.28677248677251*G0_0_0_0_0_1_0_0_0 - 1.28677248677251*G0_0_0_0_0_1_0_0_1 + 1.28677248677251*G0_0_0_0_0_1_1_0_0 + 1.28677248677251*G0_0_0_0_0_1_2_0_1 - 1.28677248677251*G0_0_0_0_0_1_3_1_0 - 1.28677248677251*G0_0_0_0_0_1_3_1_1 + 1.28677248677251*G0_0_0_0_0_1_4_1_0 + 1.28677248677251*G0_0_0_0_0_1_5_1_1 + 1.28677248677251*G0_0_0_1_0_0_0_0_0 + 1.28677248677251*G0_0_0_1_0_0_0_0_1 - 1.28677248677251*G0_0_0_1_0_0_1_0_0 - 1.28677248677251*G0_0_0_1_0_0_2_0_1 + 1.28677248677251*G0_0_0_1_0_0_3_1_0 + 1.28677248677251*G0_0_0_1_0_0_3_1_1 - 1.28677248677251*G0_0_0_1_0_0_4_1_0 - 1.28677248677251*G0_0_0_1_0_0_5_1_1 + 1.28677248677251*G0_0_0_2_0_1_0_0_0 + 1.28677248677251*G0_0_0_2_0_1_0_0_1 - 1.28677248677251*G0_0_0_2_0_1_1_0_0 - 1.28677248677251*G0_0_0_2_0_1_2_0_1 + 1.28677248677251*G0_0_0_2_0_1_3_1_0 + 1.28677248677251*G0_0_0_2_0_1_3_1_1 - 1.28677248677251*G0_0_0_2_0_1_4_1_0 - 1.28677248677251*G0_0_0_2_0_1_5_1_1 - 1.28677248677251*G0_0_0_3_1_0_0_0_0 - 1.28677248677251*G0_0_0_3_1_0_0_0_1 + 1.28677248677251*G0_0_0_3_1_0_1_0_0 + 1.28677248677251*G0_0_0_3_1_0_2_0_1 - 1.28677248677251*G0_0_0_3_1_0_3_1_0 - 1.28677248677251*G0_0_0_3_1_0_3_1_1 + 1.28677248677251*G0_0_0_3_1_0_4_1_0 + 1.28677248677251*G0_0_0_3_1_0_5_1_1 - 1.28677248677251*G0_0_0_3_1_1_0_0_0 - 1.28677248677251*G0_0_0_3_1_1_0_0_1 + 1.28677248677251*G0_0_0_3_1_1_1_0_0 + 1.28677248677251*G0_0_0_3_1_1_2_0_1 - 1.28677248677251*G0_0_0_3_1_1_3_1_0 - 1.28677248677251*G0_0_0_3_1_1_3_1_1 + 1.28677248677251*G0_0_0_3_1_1_4_1_0 + 1.28677248677251*G0_0_0_3_1_1_5_1_1 + 1.28677248677251*G0_0_0_4_1_0_0_0_0 + 1.28677248677251*G0_0_0_4_1_0_0_0_1 - 1.28677248677251*G0_0_0_4_1_0_1_0_0 - 1.28677248677251*G0_0_0_4_1_0_2_0_1 + 1.28677248677251*G0_0_0_4_1_0_3_1_0 + 1.28677248677251*G0_0_0_4_1_0_3_1_1 - 1.28677248677251*G0_0_0_4_1_0_4_1_0 - 1.28677248677251*G0_0_0_4_1_0_5_1_1 + 1.28677248677251*G0_0_0_5_1_1_0_0_0 + 1.28677248677251*G0_0_0_5_1_1_0_0_1 - 1.28677248677251*G0_0_0_5_1_1_1_0_0 - 1.28677248677251*G0_0_0_5_1_1_2_0_1 + 1.28677248677251*G0_0_0_5_1_1_3_1_0 + 1.28677248677251*G0_0_0_5_1_1_3_1_1 - 1.28677248677251*G0_0_0_5_1_1_4_1_0 - 1.28677248677251*G0_0_0_5_1_1_5_1_1 - 2.40423280423284*G0_0_1_0_0_0_0_0_0 - 2.40423280423284*G0_0_1_0_0_0_0_0_1 + 2.40423280423284*G0_0_1_0_0_0_1_0_0 + 2.40423280423284*G0_0_1_0_0_0_2_0_1 - 2.40423280423284*G0_0_1_0_0_0_3_1_0 - 2.40423280423284*G0_0_1_0_0_0_3_1_1 + 2.40423280423284*G0_0_1_0_0_0_4_1_0 + 2.40423280423284*G0_0_1_0_0_0_5_1_1 - 2.40423280423284*G0_0_1_0_0_1_0_0_0 - 2.40423280423284*G0_0_1_0_0_1_0_0_1 + 2.40423280423284*G0_0_1_0_0_1_1_0_0 + 2.40423280423284*G0_0_1_0_0_1_2_0_1 - 2.40423280423284*G0_0_1_0_0_1_3_1_0 - 2.40423280423284*G0_0_1_0_0_1_3_1_1 + 2.40423280423284*G0_0_1_0_0_1_4_1_0 + 2.40423280423284*G0_0_1_0_0_1_5_1_1 + 2.40423280423284*G0_0_1_1_0_0_0_0_0 + 2.40423280423284*G0_0_1_1_0_0_0_0_1 - 2.40423280423284*G0_0_1_1_0_0_1_0_0 - 2.40423280423284*G0_0_1_1_0_0_2_0_1 + 2.40423280423284*G0_0_1_1_0_0_3_1_0 + 2.40423280423284*G0_0_1_1_0_0_3_1_1 - 2.40423280423284*G0_0_1_1_0_0_4_1_0 - 2.40423280423284*G0_0_1_1_0_0_5_1_1 + 2.40423280423284*G0_0_1_2_0_1_0_0_0 + 2.40423280423284*G0_0_1_2_0_1_0_0_1 - 2.40423280423284*G0_0_1_2_0_1_1_0_0 - 2.40423280423284*G0_0_1_2_0_1_2_0_1 + 2.40423280423284*G0_0_1_2_0_1_3_1_0 + 2.40423280423284*G0_0_1_2_0_1_3_1_1 - 2.40423280423284*G0_0_1_2_0_1_4_1_0 - 2.40423280423284*G0_0_1_2_0_1_5_1_1 - 2.40423280423284*G0_0_1_3_1_0_0_0_0 - 2.40423280423284*G0_0_1_3_1_0_0_0_1 + 2.40423280423284*G0_0_1_3_1_0_1_0_0 + 2.40423280423284*G0_0_1_3_1_0_2_0_1 - 2.40423280423284*G0_0_1_3_1_0_3_1_0 - 2.40423280423284*G0_0_1_3_1_0_3_1_1 + 2.40423280423284*G0_0_1_3_1_0_4_1_0 + 2.40423280423284*G0_0_1_3_1_0_5_1_1 - 2.40423280423284*G0_0_1_3_1_1_0_0_0 - 2.40423280423284*G0_0_1_3_1_1_0_0_1 + 2.40423280423284*G0_0_1_3_1_1_1_0_0 + 2.40423280423284*G0_0_1_3_1_1_2_0_1 - 2.40423280423284*G0_0_1_3_1_1_3_1_0 - 2.40423280423284*G0_0_1_3_1_1_3_1_1 + 2.40423280423284*G0_0_1_3_1_1_4_1_0 + 2.40423280423284*G0_0_1_3_1_1_5_1_1 + 2.40423280423284*G0_0_1_4_1_0_0_0_0 + 2.40423280423284*G0_0_1_4_1_0_0_0_1 - 2.40423280423284*G0_0_1_4_1_0_1_0_0 - 2.40423280423284*G0_0_1_4_1_0_2_0_1 + 2.40423280423284*G0_0_1_4_1_0_3_1_0 + 2.40423280423284*G0_0_1_4_1_0_3_1_1 - 2.40423280423284*G0_0_1_4_1_0_4_1_0 - 2.40423280423284*G0_0_1_4_1_0_5_1_1 + 2.40423280423284*G0_0_1_5_1_1_0_0_0 + 2.40423280423284*G0_0_1_5_1_1_0_0_1 - 2.40423280423284*G0_0_1_5_1_1_1_0_0 - 2.40423280423284*G0_0_1_5_1_1_2_0_1 + 2.40423280423284*G0_0_1_5_1_1_3_1_0 + 2.40423280423284*G0_0_1_5_1_1_3_1_1 - 2.40423280423284*G0_0_1_5_1_1_4_1_0 - 2.40423280423284*G0_0_1_5_1_1_5_1_1 - 0.169312169312178*G0_1_0_0_0_0_0_0_0 - 0.169312169312178*G0_1_0_0_0_0_0_0_1 + 0.169312169312178*G0_1_0_0_0_0_1_0_0 + 0.169312169312178*G0_1_0_0_0_0_2_0_1 - 0.169312169312178*G0_1_0_0_0_0_3_1_0 - 0.169312169312178*G0_1_0_0_0_0_3_1_1 + 0.169312169312178*G0_1_0_0_0_0_4_1_0 + 0.169312169312178*G0_1_0_0_0_0_5_1_1 - 0.169312169312178*G0_1_0_0_0_1_0_0_0 - 0.169312169312178*G0_1_0_0_0_1_0_0_1 + 0.169312169312178*G0_1_0_0_0_1_1_0_0 + 0.169312169312178*G0_1_0_0_0_1_2_0_1 - 0.169312169312178*G0_1_0_0_0_1_3_1_0 - 0.169312169312178*G0_1_0_0_0_1_3_1_1 + 0.169312169312178*G0_1_0_0_0_1_4_1_0 + 0.169312169312178*G0_1_0_0_0_1_5_1_1 + 0.169312169312178*G0_1_0_1_0_0_0_0_0 + 0.169312169312178*G0_1_0_1_0_0_0_0_1 - 0.169312169312178*G0_1_0_1_0_0_1_0_0 - 0.169312169312178*G0_1_0_1_0_0_2_0_1 + 0.169312169312178*G0_1_0_1_0_0_3_1_0 + 0.169312169312178*G0_1_0_1_0_0_3_1_1 - 0.169312169312178*G0_1_0_1_0_0_4_1_0 - 0.169312169312178*G0_1_0_1_0_0_5_1_1 + 0.169312169312178*G0_1_0_2_0_1_0_0_0 + 0.169312169312178*G0_1_0_2_0_1_0_0_1 - 0.169312169312178*G0_1_0_2_0_1_1_0_0 - 0.169312169312178*G0_1_0_2_0_1_2_0_1 + 0.169312169312178*G0_1_0_2_0_1_3_1_0 + 0.169312169312178*G0_1_0_2_0_1_3_1_1 - 0.169312169312178*G0_1_0_2_0_1_4_1_0 - 0.169312169312178*G0_1_0_2_0_1_5_1_1 - 0.169312169312178*G0_1_0_3_1_0_0_0_0 - 0.169312169312178*G0_1_0_3_1_0_0_0_1 + 0.169312169312178*G0_1_0_3_1_0_1_0_0 + 0.169312169312178*G0_1_0_3_1_0_2_0_1 - 0.169312169312178*G0_1_0_3_1_0_3_1_0 - 0.169312169312178*G0_1_0_3_1_0_3_1_1 + 0.169312169312178*G0_1_0_3_1_0_4_1_0 + 0.169312169312178*G0_1_0_3_1_0_5_1_1 - 0.169312169312178*G0_1_0_3_1_1_0_0_0 - 0.169312169312178*G0_1_0_3_1_1_0_0_1 + 0.169312169312178*G0_1_0_3_1_1_1_0_0 + 0.169312169312178*G0_1_0_3_1_1_2_0_1 - 0.169312169312178*G0_1_0_3_1_1_3_1_0 - 0.169312169312178*G0_1_0_3_1_1_3_1_1 + 0.169312169312178*G0_1_0_3_1_1_4_1_0 + 0.169312169312178*G0_1_0_3_1_1_5_1_1 + 0.169312169312178*G0_1_0_4_1_0_0_0_0 + 0.169312169312178*G0_1_0_4_1_0_0_0_1 - 0.169312169312178*G0_1_0_4_1_0_1_0_0 - 0.169312169312178*G0_1_0_4_1_0_2_0_1 + 0.169312169312178*G0_1_0_4_1_0_3_1_0 + 0.169312169312178*G0_1_0_4_1_0_3_1_1 - 0.169312169312178*G0_1_0_4_1_0_4_1_0 - 0.169312169312178*G0_1_0_4_1_0_5_1_1 + 0.169312169312178*G0_1_0_5_1_1_0_0_0 + 0.169312169312178*G0_1_0_5_1_1_0_0_1 - 0.169312169312178*G0_1_0_5_1_1_1_0_0 - 0.169312169312178*G0_1_0_5_1_1_2_0_1 + 0.169312169312178*G0_1_0_5_1_1_3_1_0 + 0.169312169312178*G0_1_0_5_1_1_3_1_1 - 0.169312169312178*G0_1_0_5_1_1_4_1_0 - 0.169312169312178*G0_1_0_5_1_1_5_1_1; + A[94] = A[559]; + A[590] = A[125]; + A[652] = A[309] + 1.28677248677251*G0_0_0_0_0_0_0_0_0 + 1.28677248677251*G0_0_0_0_0_0_0_0_1 - 1.28677248677251*G0_0_0_0_0_0_1_0_0 - 1.28677248677251*G0_0_0_0_0_0_2_0_1 + 1.28677248677251*G0_0_0_0_0_0_3_1_0 + 1.28677248677251*G0_0_0_0_0_0_3_1_1 - 1.28677248677251*G0_0_0_0_0_0_4_1_0 - 1.28677248677251*G0_0_0_0_0_0_5_1_1 + 1.28677248677251*G0_0_0_0_0_1_0_0_0 + 1.28677248677251*G0_0_0_0_0_1_0_0_1 - 1.28677248677251*G0_0_0_0_0_1_1_0_0 - 1.28677248677251*G0_0_0_0_0_1_2_0_1 + 1.28677248677251*G0_0_0_0_0_1_3_1_0 + 1.28677248677251*G0_0_0_0_0_1_3_1_1 - 1.28677248677251*G0_0_0_0_0_1_4_1_0 - 1.28677248677251*G0_0_0_0_0_1_5_1_1 - 1.28677248677251*G0_0_0_1_0_0_0_0_0 - 1.28677248677251*G0_0_0_1_0_0_0_0_1 + 1.28677248677251*G0_0_0_1_0_0_1_0_0 + 1.28677248677251*G0_0_0_1_0_0_2_0_1 - 1.28677248677251*G0_0_0_1_0_0_3_1_0 - 1.28677248677251*G0_0_0_1_0_0_3_1_1 + 1.28677248677251*G0_0_0_1_0_0_4_1_0 + 1.28677248677251*G0_0_0_1_0_0_5_1_1 - 1.28677248677251*G0_0_0_2_0_1_0_0_0 - 1.28677248677251*G0_0_0_2_0_1_0_0_1 + 1.28677248677251*G0_0_0_2_0_1_1_0_0 + 1.28677248677251*G0_0_0_2_0_1_2_0_1 - 1.28677248677251*G0_0_0_2_0_1_3_1_0 - 1.28677248677251*G0_0_0_2_0_1_3_1_1 + 1.28677248677251*G0_0_0_2_0_1_4_1_0 + 1.28677248677251*G0_0_0_2_0_1_5_1_1 + 1.28677248677251*G0_0_0_3_1_0_0_0_0 + 1.28677248677251*G0_0_0_3_1_0_0_0_1 - 1.28677248677251*G0_0_0_3_1_0_1_0_0 - 1.28677248677251*G0_0_0_3_1_0_2_0_1 + 1.28677248677251*G0_0_0_3_1_0_3_1_0 + 1.28677248677251*G0_0_0_3_1_0_3_1_1 - 1.28677248677251*G0_0_0_3_1_0_4_1_0 - 1.28677248677251*G0_0_0_3_1_0_5_1_1 + 1.28677248677251*G0_0_0_3_1_1_0_0_0 + 1.28677248677251*G0_0_0_3_1_1_0_0_1 - 1.28677248677251*G0_0_0_3_1_1_1_0_0 - 1.28677248677251*G0_0_0_3_1_1_2_0_1 + 1.28677248677251*G0_0_0_3_1_1_3_1_0 + 1.28677248677251*G0_0_0_3_1_1_3_1_1 - 1.28677248677251*G0_0_0_3_1_1_4_1_0 - 1.28677248677251*G0_0_0_3_1_1_5_1_1 - 1.28677248677251*G0_0_0_4_1_0_0_0_0 - 1.28677248677251*G0_0_0_4_1_0_0_0_1 + 1.28677248677251*G0_0_0_4_1_0_1_0_0 + 1.28677248677251*G0_0_0_4_1_0_2_0_1 - 1.28677248677251*G0_0_0_4_1_0_3_1_0 - 1.28677248677251*G0_0_0_4_1_0_3_1_1 + 1.28677248677251*G0_0_0_4_1_0_4_1_0 + 1.28677248677251*G0_0_0_4_1_0_5_1_1 - 1.28677248677251*G0_0_0_5_1_1_0_0_0 - 1.28677248677251*G0_0_0_5_1_1_0_0_1 + 1.28677248677251*G0_0_0_5_1_1_1_0_0 + 1.28677248677251*G0_0_0_5_1_1_2_0_1 - 1.28677248677251*G0_0_0_5_1_1_3_1_0 - 1.28677248677251*G0_0_0_5_1_1_3_1_1 + 1.28677248677251*G0_0_0_5_1_1_4_1_0 + 1.28677248677251*G0_0_0_5_1_1_5_1_1 - 1.28677248677251*G0_1_1_0_0_0_0_0_0 - 1.28677248677251*G0_1_1_0_0_0_0_0_1 + 1.28677248677251*G0_1_1_0_0_0_1_0_0 + 1.28677248677251*G0_1_1_0_0_0_2_0_1 - 1.28677248677251*G0_1_1_0_0_0_3_1_0 - 1.28677248677251*G0_1_1_0_0_0_3_1_1 + 1.28677248677251*G0_1_1_0_0_0_4_1_0 + 1.28677248677251*G0_1_1_0_0_0_5_1_1 - 1.28677248677251*G0_1_1_0_0_1_0_0_0 - 1.28677248677251*G0_1_1_0_0_1_0_0_1 + 1.28677248677251*G0_1_1_0_0_1_1_0_0 + 1.28677248677251*G0_1_1_0_0_1_2_0_1 - 1.28677248677251*G0_1_1_0_0_1_3_1_0 - 1.28677248677251*G0_1_1_0_0_1_3_1_1 + 1.28677248677251*G0_1_1_0_0_1_4_1_0 + 1.28677248677251*G0_1_1_0_0_1_5_1_1 + 1.28677248677251*G0_1_1_1_0_0_0_0_0 + 1.28677248677251*G0_1_1_1_0_0_0_0_1 - 1.28677248677251*G0_1_1_1_0_0_1_0_0 - 1.28677248677251*G0_1_1_1_0_0_2_0_1 + 1.28677248677251*G0_1_1_1_0_0_3_1_0 + 1.28677248677251*G0_1_1_1_0_0_3_1_1 - 1.28677248677251*G0_1_1_1_0_0_4_1_0 - 1.28677248677251*G0_1_1_1_0_0_5_1_1 + 1.28677248677251*G0_1_1_2_0_1_0_0_0 + 1.28677248677251*G0_1_1_2_0_1_0_0_1 - 1.28677248677251*G0_1_1_2_0_1_1_0_0 - 1.28677248677251*G0_1_1_2_0_1_2_0_1 + 1.28677248677251*G0_1_1_2_0_1_3_1_0 + 1.28677248677251*G0_1_1_2_0_1_3_1_1 - 1.28677248677251*G0_1_1_2_0_1_4_1_0 - 1.28677248677251*G0_1_1_2_0_1_5_1_1 - 1.28677248677251*G0_1_1_3_1_0_0_0_0 - 1.28677248677251*G0_1_1_3_1_0_0_0_1 + 1.28677248677251*G0_1_1_3_1_0_1_0_0 + 1.28677248677251*G0_1_1_3_1_0_2_0_1 - 1.28677248677251*G0_1_1_3_1_0_3_1_0 - 1.28677248677251*G0_1_1_3_1_0_3_1_1 + 1.28677248677251*G0_1_1_3_1_0_4_1_0 + 1.28677248677251*G0_1_1_3_1_0_5_1_1 - 1.28677248677251*G0_1_1_3_1_1_0_0_0 - 1.28677248677251*G0_1_1_3_1_1_0_0_1 + 1.28677248677251*G0_1_1_3_1_1_1_0_0 + 1.28677248677251*G0_1_1_3_1_1_2_0_1 - 1.28677248677251*G0_1_1_3_1_1_3_1_0 - 1.28677248677251*G0_1_1_3_1_1_3_1_1 + 1.28677248677251*G0_1_1_3_1_1_4_1_0 + 1.28677248677251*G0_1_1_3_1_1_5_1_1 + 1.28677248677251*G0_1_1_4_1_0_0_0_0 + 1.28677248677251*G0_1_1_4_1_0_0_0_1 - 1.28677248677251*G0_1_1_4_1_0_1_0_0 - 1.28677248677251*G0_1_1_4_1_0_2_0_1 + 1.28677248677251*G0_1_1_4_1_0_3_1_0 + 1.28677248677251*G0_1_1_4_1_0_3_1_1 - 1.28677248677251*G0_1_1_4_1_0_4_1_0 - 1.28677248677251*G0_1_1_4_1_0_5_1_1 + 1.28677248677251*G0_1_1_5_1_1_0_0_0 + 1.28677248677251*G0_1_1_5_1_1_0_0_1 - 1.28677248677251*G0_1_1_5_1_1_1_0_0 - 1.28677248677251*G0_1_1_5_1_1_2_0_1 + 1.28677248677251*G0_1_1_5_1_1_3_1_0 + 1.28677248677251*G0_1_1_5_1_1_3_1_1 - 1.28677248677251*G0_1_1_5_1_1_4_1_0 - 1.28677248677251*G0_1_1_5_1_1_5_1_1; + A[187] = A[652]; + A[216] = A[652] + 1.11746031746033*G0_0_1_0_0_0_0_0_0 + 1.11746031746033*G0_0_1_0_0_0_0_0_1 - 1.11746031746033*G0_0_1_0_0_0_1_0_0 - 1.11746031746033*G0_0_1_0_0_0_2_0_1 + 1.11746031746033*G0_0_1_0_0_0_3_1_0 + 1.11746031746033*G0_0_1_0_0_0_3_1_1 - 1.11746031746033*G0_0_1_0_0_0_4_1_0 - 1.11746031746033*G0_0_1_0_0_0_5_1_1 + 1.11746031746033*G0_0_1_0_0_1_0_0_0 + 1.11746031746033*G0_0_1_0_0_1_0_0_1 - 1.11746031746033*G0_0_1_0_0_1_1_0_0 - 1.11746031746033*G0_0_1_0_0_1_2_0_1 + 1.11746031746033*G0_0_1_0_0_1_3_1_0 + 1.11746031746033*G0_0_1_0_0_1_3_1_1 - 1.11746031746033*G0_0_1_0_0_1_4_1_0 - 1.11746031746033*G0_0_1_0_0_1_5_1_1 - 1.11746031746033*G0_0_1_1_0_0_0_0_0 - 1.11746031746033*G0_0_1_1_0_0_0_0_1 + 1.11746031746033*G0_0_1_1_0_0_1_0_0 + 1.11746031746033*G0_0_1_1_0_0_2_0_1 - 1.11746031746033*G0_0_1_1_0_0_3_1_0 - 1.11746031746033*G0_0_1_1_0_0_3_1_1 + 1.11746031746033*G0_0_1_1_0_0_4_1_0 + 1.11746031746033*G0_0_1_1_0_0_5_1_1 - 1.11746031746033*G0_0_1_2_0_1_0_0_0 - 1.11746031746033*G0_0_1_2_0_1_0_0_1 + 1.11746031746033*G0_0_1_2_0_1_1_0_0 + 1.11746031746033*G0_0_1_2_0_1_2_0_1 - 1.11746031746033*G0_0_1_2_0_1_3_1_0 - 1.11746031746033*G0_0_1_2_0_1_3_1_1 + 1.11746031746033*G0_0_1_2_0_1_4_1_0 + 1.11746031746033*G0_0_1_2_0_1_5_1_1 + 1.11746031746033*G0_0_1_3_1_0_0_0_0 + 1.11746031746033*G0_0_1_3_1_0_0_0_1 - 1.11746031746033*G0_0_1_3_1_0_1_0_0 - 1.11746031746033*G0_0_1_3_1_0_2_0_1 + 1.11746031746033*G0_0_1_3_1_0_3_1_0 + 1.11746031746033*G0_0_1_3_1_0_3_1_1 - 1.11746031746033*G0_0_1_3_1_0_4_1_0 - 1.11746031746033*G0_0_1_3_1_0_5_1_1 + 1.11746031746033*G0_0_1_3_1_1_0_0_0 + 1.11746031746033*G0_0_1_3_1_1_0_0_1 - 1.11746031746033*G0_0_1_3_1_1_1_0_0 - 1.11746031746033*G0_0_1_3_1_1_2_0_1 + 1.11746031746033*G0_0_1_3_1_1_3_1_0 + 1.11746031746033*G0_0_1_3_1_1_3_1_1 - 1.11746031746033*G0_0_1_3_1_1_4_1_0 - 1.11746031746033*G0_0_1_3_1_1_5_1_1 - 1.11746031746033*G0_0_1_4_1_0_0_0_0 - 1.11746031746033*G0_0_1_4_1_0_0_0_1 + 1.11746031746033*G0_0_1_4_1_0_1_0_0 + 1.11746031746033*G0_0_1_4_1_0_2_0_1 - 1.11746031746033*G0_0_1_4_1_0_3_1_0 - 1.11746031746033*G0_0_1_4_1_0_3_1_1 + 1.11746031746033*G0_0_1_4_1_0_4_1_0 + 1.11746031746033*G0_0_1_4_1_0_5_1_1 - 1.11746031746033*G0_0_1_5_1_1_0_0_0 - 1.11746031746033*G0_0_1_5_1_1_0_0_1 + 1.11746031746033*G0_0_1_5_1_1_1_0_0 + 1.11746031746033*G0_0_1_5_1_1_2_0_1 - 1.11746031746033*G0_0_1_5_1_1_3_1_0 - 1.11746031746033*G0_0_1_5_1_1_3_1_1 + 1.11746031746033*G0_0_1_5_1_1_4_1_0 + 1.11746031746033*G0_0_1_5_1_1_5_1_1 - 1.11746031746033*G0_1_0_0_0_0_0_0_0 - 1.11746031746033*G0_1_0_0_0_0_0_0_1 + 1.11746031746033*G0_1_0_0_0_0_1_0_0 + 1.11746031746033*G0_1_0_0_0_0_2_0_1 - 1.11746031746033*G0_1_0_0_0_0_3_1_0 - 1.11746031746033*G0_1_0_0_0_0_3_1_1 + 1.11746031746033*G0_1_0_0_0_0_4_1_0 + 1.11746031746033*G0_1_0_0_0_0_5_1_1 - 1.11746031746033*G0_1_0_0_0_1_0_0_0 - 1.11746031746033*G0_1_0_0_0_1_0_0_1 + 1.11746031746033*G0_1_0_0_0_1_1_0_0 + 1.11746031746033*G0_1_0_0_0_1_2_0_1 - 1.11746031746033*G0_1_0_0_0_1_3_1_0 - 1.11746031746033*G0_1_0_0_0_1_3_1_1 + 1.11746031746033*G0_1_0_0_0_1_4_1_0 + 1.11746031746033*G0_1_0_0_0_1_5_1_1 + 1.11746031746033*G0_1_0_1_0_0_0_0_0 + 1.11746031746033*G0_1_0_1_0_0_0_0_1 - 1.11746031746033*G0_1_0_1_0_0_1_0_0 - 1.11746031746033*G0_1_0_1_0_0_2_0_1 + 1.11746031746033*G0_1_0_1_0_0_3_1_0 + 1.11746031746033*G0_1_0_1_0_0_3_1_1 - 1.11746031746033*G0_1_0_1_0_0_4_1_0 - 1.11746031746033*G0_1_0_1_0_0_5_1_1 + 1.11746031746033*G0_1_0_2_0_1_0_0_0 + 1.11746031746033*G0_1_0_2_0_1_0_0_1 - 1.11746031746033*G0_1_0_2_0_1_1_0_0 - 1.11746031746033*G0_1_0_2_0_1_2_0_1 + 1.11746031746033*G0_1_0_2_0_1_3_1_0 + 1.11746031746033*G0_1_0_2_0_1_3_1_1 - 1.11746031746033*G0_1_0_2_0_1_4_1_0 - 1.11746031746033*G0_1_0_2_0_1_5_1_1 - 1.11746031746033*G0_1_0_3_1_0_0_0_0 - 1.11746031746033*G0_1_0_3_1_0_0_0_1 + 1.11746031746033*G0_1_0_3_1_0_1_0_0 + 1.11746031746033*G0_1_0_3_1_0_2_0_1 - 1.11746031746033*G0_1_0_3_1_0_3_1_0 - 1.11746031746033*G0_1_0_3_1_0_3_1_1 + 1.11746031746033*G0_1_0_3_1_0_4_1_0 + 1.11746031746033*G0_1_0_3_1_0_5_1_1 - 1.11746031746033*G0_1_0_3_1_1_0_0_0 - 1.11746031746033*G0_1_0_3_1_1_0_0_1 + 1.11746031746033*G0_1_0_3_1_1_1_0_0 + 1.11746031746033*G0_1_0_3_1_1_2_0_1 - 1.11746031746033*G0_1_0_3_1_1_3_1_0 - 1.11746031746033*G0_1_0_3_1_1_3_1_1 + 1.11746031746033*G0_1_0_3_1_1_4_1_0 + 1.11746031746033*G0_1_0_3_1_1_5_1_1 + 1.11746031746033*G0_1_0_4_1_0_0_0_0 + 1.11746031746033*G0_1_0_4_1_0_0_0_1 - 1.11746031746033*G0_1_0_4_1_0_1_0_0 - 1.11746031746033*G0_1_0_4_1_0_2_0_1 + 1.11746031746033*G0_1_0_4_1_0_3_1_0 + 1.11746031746033*G0_1_0_4_1_0_3_1_1 - 1.11746031746033*G0_1_0_4_1_0_4_1_0 - 1.11746031746033*G0_1_0_4_1_0_5_1_1 + 1.11746031746033*G0_1_0_5_1_1_0_0_0 + 1.11746031746033*G0_1_0_5_1_1_0_0_1 - 1.11746031746033*G0_1_0_5_1_1_1_0_0 - 1.11746031746033*G0_1_0_5_1_1_2_0_1 + 1.11746031746033*G0_1_0_5_1_1_3_1_0 + 1.11746031746033*G0_1_0_5_1_1_3_1_1 - 1.11746031746033*G0_1_0_5_1_1_4_1_0 - 1.11746031746033*G0_1_0_5_1_1_5_1_1; + A[242] = -0.778835978835986*G0_0_1_0_0_0_0_0_0 - 0.778835978835986*G0_0_1_0_0_0_0_0_1 + 0.778835978835986*G0_0_1_0_0_0_1_0_0 + 0.778835978835986*G0_0_1_0_0_0_2_0_1 - 0.778835978835986*G0_0_1_0_0_0_3_1_0 - 0.778835978835986*G0_0_1_0_0_0_3_1_1 + 0.778835978835986*G0_0_1_0_0_0_4_1_0 + 0.778835978835986*G0_0_1_0_0_0_5_1_1 - 0.778835978835986*G0_0_1_0_0_1_0_0_0 - 0.778835978835986*G0_0_1_0_0_1_0_0_1 + 0.778835978835986*G0_0_1_0_0_1_1_0_0 + 0.778835978835986*G0_0_1_0_0_1_2_0_1 - 0.778835978835986*G0_0_1_0_0_1_3_1_0 - 0.778835978835986*G0_0_1_0_0_1_3_1_1 + 0.778835978835986*G0_0_1_0_0_1_4_1_0 + 0.778835978835986*G0_0_1_0_0_1_5_1_1 + 0.778835978835986*G0_0_1_1_0_0_0_0_0 + 0.778835978835986*G0_0_1_1_0_0_0_0_1 - 0.778835978835986*G0_0_1_1_0_0_1_0_0 - 0.778835978835986*G0_0_1_1_0_0_2_0_1 + 0.778835978835986*G0_0_1_1_0_0_3_1_0 + 0.778835978835986*G0_0_1_1_0_0_3_1_1 - 0.778835978835986*G0_0_1_1_0_0_4_1_0 - 0.778835978835986*G0_0_1_1_0_0_5_1_1 + 0.778835978835986*G0_0_1_2_0_1_0_0_0 + 0.778835978835986*G0_0_1_2_0_1_0_0_1 - 0.778835978835986*G0_0_1_2_0_1_1_0_0 - 0.778835978835986*G0_0_1_2_0_1_2_0_1 + 0.778835978835986*G0_0_1_2_0_1_3_1_0 + 0.778835978835986*G0_0_1_2_0_1_3_1_1 - 0.778835978835986*G0_0_1_2_0_1_4_1_0 - 0.778835978835986*G0_0_1_2_0_1_5_1_1 - 0.778835978835986*G0_0_1_3_1_0_0_0_0 - 0.778835978835986*G0_0_1_3_1_0_0_0_1 + 0.778835978835986*G0_0_1_3_1_0_1_0_0 + 0.778835978835986*G0_0_1_3_1_0_2_0_1 - 0.778835978835986*G0_0_1_3_1_0_3_1_0 - 0.778835978835986*G0_0_1_3_1_0_3_1_1 + 0.778835978835986*G0_0_1_3_1_0_4_1_0 + 0.778835978835986*G0_0_1_3_1_0_5_1_1 - 0.778835978835986*G0_0_1_3_1_1_0_0_0 - 0.778835978835986*G0_0_1_3_1_1_0_0_1 + 0.778835978835986*G0_0_1_3_1_1_1_0_0 + 0.778835978835986*G0_0_1_3_1_1_2_0_1 - 0.778835978835986*G0_0_1_3_1_1_3_1_0 - 0.778835978835986*G0_0_1_3_1_1_3_1_1 + 0.778835978835986*G0_0_1_3_1_1_4_1_0 + 0.778835978835986*G0_0_1_3_1_1_5_1_1 + 0.778835978835986*G0_0_1_4_1_0_0_0_0 + 0.778835978835986*G0_0_1_4_1_0_0_0_1 - 0.778835978835986*G0_0_1_4_1_0_1_0_0 - 0.778835978835986*G0_0_1_4_1_0_2_0_1 + 0.778835978835986*G0_0_1_4_1_0_3_1_0 + 0.778835978835986*G0_0_1_4_1_0_3_1_1 - 0.778835978835986*G0_0_1_4_1_0_4_1_0 - 0.778835978835986*G0_0_1_4_1_0_5_1_1 + 0.778835978835986*G0_0_1_5_1_1_0_0_0 + 0.778835978835986*G0_0_1_5_1_1_0_0_1 - 0.778835978835986*G0_0_1_5_1_1_1_0_0 - 0.778835978835986*G0_0_1_5_1_1_2_0_1 + 0.778835978835986*G0_0_1_5_1_1_3_1_0 + 0.778835978835986*G0_0_1_5_1_1_3_1_1 - 0.778835978835986*G0_0_1_5_1_1_4_1_0 - 0.778835978835986*G0_0_1_5_1_1_5_1_1 - 0.65185185185186*G0_1_1_0_0_0_0_0_0 - 0.65185185185186*G0_1_1_0_0_0_0_0_1 + 0.65185185185186*G0_1_1_0_0_0_1_0_0 + 0.65185185185186*G0_1_1_0_0_0_2_0_1 - 0.65185185185186*G0_1_1_0_0_0_3_1_0 - 0.65185185185186*G0_1_1_0_0_0_3_1_1 + 0.65185185185186*G0_1_1_0_0_0_4_1_0 + 0.65185185185186*G0_1_1_0_0_0_5_1_1 - 0.65185185185186*G0_1_1_0_0_1_0_0_0 - 0.65185185185186*G0_1_1_0_0_1_0_0_1 + 0.65185185185186*G0_1_1_0_0_1_1_0_0 + 0.65185185185186*G0_1_1_0_0_1_2_0_1 - 0.65185185185186*G0_1_1_0_0_1_3_1_0 - 0.65185185185186*G0_1_1_0_0_1_3_1_1 + 0.65185185185186*G0_1_1_0_0_1_4_1_0 + 0.65185185185186*G0_1_1_0_0_1_5_1_1 + 0.65185185185186*G0_1_1_1_0_0_0_0_0 + 0.65185185185186*G0_1_1_1_0_0_0_0_1 - 0.65185185185186*G0_1_1_1_0_0_1_0_0 - 0.65185185185186*G0_1_1_1_0_0_2_0_1 + 0.65185185185186*G0_1_1_1_0_0_3_1_0 + 0.65185185185186*G0_1_1_1_0_0_3_1_1 - 0.65185185185186*G0_1_1_1_0_0_4_1_0 - 0.65185185185186*G0_1_1_1_0_0_5_1_1 + 0.65185185185186*G0_1_1_2_0_1_0_0_0 + 0.65185185185186*G0_1_1_2_0_1_0_0_1 - 0.65185185185186*G0_1_1_2_0_1_1_0_0 - 0.65185185185186*G0_1_1_2_0_1_2_0_1 + 0.65185185185186*G0_1_1_2_0_1_3_1_0 + 0.65185185185186*G0_1_1_2_0_1_3_1_1 - 0.65185185185186*G0_1_1_2_0_1_4_1_0 - 0.65185185185186*G0_1_1_2_0_1_5_1_1 - 0.65185185185186*G0_1_1_3_1_0_0_0_0 - 0.65185185185186*G0_1_1_3_1_0_0_0_1 + 0.65185185185186*G0_1_1_3_1_0_1_0_0 + 0.65185185185186*G0_1_1_3_1_0_2_0_1 - 0.65185185185186*G0_1_1_3_1_0_3_1_0 - 0.65185185185186*G0_1_1_3_1_0_3_1_1 + 0.65185185185186*G0_1_1_3_1_0_4_1_0 + 0.65185185185186*G0_1_1_3_1_0_5_1_1 - 0.65185185185186*G0_1_1_3_1_1_0_0_0 - 0.65185185185186*G0_1_1_3_1_1_0_0_1 + 0.65185185185186*G0_1_1_3_1_1_1_0_0 + 0.65185185185186*G0_1_1_3_1_1_2_0_1 - 0.65185185185186*G0_1_1_3_1_1_3_1_0 - 0.65185185185186*G0_1_1_3_1_1_3_1_1 + 0.65185185185186*G0_1_1_3_1_1_4_1_0 + 0.65185185185186*G0_1_1_3_1_1_5_1_1 + 0.65185185185186*G0_1_1_4_1_0_0_0_0 + 0.65185185185186*G0_1_1_4_1_0_0_0_1 - 0.65185185185186*G0_1_1_4_1_0_1_0_0 - 0.65185185185186*G0_1_1_4_1_0_2_0_1 + 0.65185185185186*G0_1_1_4_1_0_3_1_0 + 0.65185185185186*G0_1_1_4_1_0_3_1_1 - 0.65185185185186*G0_1_1_4_1_0_4_1_0 - 0.65185185185186*G0_1_1_4_1_0_5_1_1 + 0.65185185185186*G0_1_1_5_1_1_0_0_0 + 0.65185185185186*G0_1_1_5_1_1_0_0_1 - 0.65185185185186*G0_1_1_5_1_1_1_0_0 - 0.65185185185186*G0_1_1_5_1_1_2_0_1 + 0.65185185185186*G0_1_1_5_1_1_3_1_0 + 0.65185185185186*G0_1_1_5_1_1_3_1_1 - 0.65185185185186*G0_1_1_5_1_1_4_1_0 - 0.65185185185186*G0_1_1_5_1_1_5_1_1; + A[273] = A[621] + 0.203174603174598*G0_0_0_0_0_0_0_0_0 + 0.203174603174598*G0_0_0_0_0_0_0_0_1 - 0.203174603174598*G0_0_0_0_0_0_1_0_0 - 0.203174603174598*G0_0_0_0_0_0_2_0_1 + 0.203174603174598*G0_0_0_0_0_0_3_1_0 + 0.203174603174598*G0_0_0_0_0_0_3_1_1 - 0.203174603174598*G0_0_0_0_0_0_4_1_0 - 0.203174603174598*G0_0_0_0_0_0_5_1_1 + 0.203174603174598*G0_0_0_0_0_1_0_0_0 + 0.203174603174598*G0_0_0_0_0_1_0_0_1 - 0.203174603174598*G0_0_0_0_0_1_1_0_0 - 0.203174603174598*G0_0_0_0_0_1_2_0_1 + 0.203174603174598*G0_0_0_0_0_1_3_1_0 + 0.203174603174598*G0_0_0_0_0_1_3_1_1 - 0.203174603174598*G0_0_0_0_0_1_4_1_0 - 0.203174603174598*G0_0_0_0_0_1_5_1_1 - 0.203174603174598*G0_0_0_1_0_0_0_0_0 - 0.203174603174598*G0_0_0_1_0_0_0_0_1 + 0.203174603174598*G0_0_0_1_0_0_1_0_0 + 0.203174603174598*G0_0_0_1_0_0_2_0_1 - 0.203174603174598*G0_0_0_1_0_0_3_1_0 - 0.203174603174598*G0_0_0_1_0_0_3_1_1 + 0.203174603174598*G0_0_0_1_0_0_4_1_0 + 0.203174603174598*G0_0_0_1_0_0_5_1_1 - 0.203174603174598*G0_0_0_2_0_1_0_0_0 - 0.203174603174598*G0_0_0_2_0_1_0_0_1 + 0.203174603174598*G0_0_0_2_0_1_1_0_0 + 0.203174603174598*G0_0_0_2_0_1_2_0_1 - 0.203174603174598*G0_0_0_2_0_1_3_1_0 - 0.203174603174598*G0_0_0_2_0_1_3_1_1 + 0.203174603174598*G0_0_0_2_0_1_4_1_0 + 0.203174603174598*G0_0_0_2_0_1_5_1_1 + 0.203174603174598*G0_0_0_3_1_0_0_0_0 + 0.203174603174598*G0_0_0_3_1_0_0_0_1 - 0.203174603174598*G0_0_0_3_1_0_1_0_0 - 0.203174603174598*G0_0_0_3_1_0_2_0_1 + 0.203174603174598*G0_0_0_3_1_0_3_1_0 + 0.203174603174598*G0_0_0_3_1_0_3_1_1 - 0.203174603174598*G0_0_0_3_1_0_4_1_0 - 0.203174603174598*G0_0_0_3_1_0_5_1_1 + 0.203174603174598*G0_0_0_3_1_1_0_0_0 + 0.203174603174598*G0_0_0_3_1_1_0_0_1 - 0.203174603174598*G0_0_0_3_1_1_1_0_0 - 0.203174603174598*G0_0_0_3_1_1_2_0_1 + 0.203174603174598*G0_0_0_3_1_1_3_1_0 + 0.203174603174598*G0_0_0_3_1_1_3_1_1 - 0.203174603174598*G0_0_0_3_1_1_4_1_0 - 0.203174603174598*G0_0_0_3_1_1_5_1_1 - 0.203174603174598*G0_0_0_4_1_0_0_0_0 - 0.203174603174598*G0_0_0_4_1_0_0_0_1 + 0.203174603174598*G0_0_0_4_1_0_1_0_0 + 0.203174603174598*G0_0_0_4_1_0_2_0_1 - 0.203174603174598*G0_0_0_4_1_0_3_1_0 - 0.203174603174598*G0_0_0_4_1_0_3_1_1 + 0.203174603174598*G0_0_0_4_1_0_4_1_0 + 0.203174603174598*G0_0_0_4_1_0_5_1_1 - 0.203174603174598*G0_0_0_5_1_1_0_0_0 - 0.203174603174598*G0_0_0_5_1_1_0_0_1 + 0.203174603174598*G0_0_0_5_1_1_1_0_0 + 0.203174603174598*G0_0_0_5_1_1_2_0_1 - 0.203174603174598*G0_0_0_5_1_1_3_1_0 - 0.203174603174598*G0_0_0_5_1_1_3_1_1 + 0.203174603174598*G0_0_0_5_1_1_4_1_0 + 0.203174603174598*G0_0_0_5_1_1_5_1_1 - 0.203174603174598*G0_1_1_0_0_0_0_0_0 - 0.203174603174598*G0_1_1_0_0_0_0_0_1 + 0.203174603174598*G0_1_1_0_0_0_1_0_0 + 0.203174603174598*G0_1_1_0_0_0_2_0_1 - 0.203174603174598*G0_1_1_0_0_0_3_1_0 - 0.203174603174598*G0_1_1_0_0_0_3_1_1 + 0.203174603174598*G0_1_1_0_0_0_4_1_0 + 0.203174603174598*G0_1_1_0_0_0_5_1_1 - 0.203174603174598*G0_1_1_0_0_1_0_0_0 - 0.203174603174598*G0_1_1_0_0_1_0_0_1 + 0.203174603174598*G0_1_1_0_0_1_1_0_0 + 0.203174603174598*G0_1_1_0_0_1_2_0_1 - 0.203174603174598*G0_1_1_0_0_1_3_1_0 - 0.203174603174598*G0_1_1_0_0_1_3_1_1 + 0.203174603174598*G0_1_1_0_0_1_4_1_0 + 0.203174603174598*G0_1_1_0_0_1_5_1_1 + 0.203174603174598*G0_1_1_1_0_0_0_0_0 + 0.203174603174598*G0_1_1_1_0_0_0_0_1 - 0.203174603174598*G0_1_1_1_0_0_1_0_0 - 0.203174603174598*G0_1_1_1_0_0_2_0_1 + 0.203174603174598*G0_1_1_1_0_0_3_1_0 + 0.203174603174598*G0_1_1_1_0_0_3_1_1 - 0.203174603174598*G0_1_1_1_0_0_4_1_0 - 0.203174603174598*G0_1_1_1_0_0_5_1_1 + 0.203174603174598*G0_1_1_2_0_1_0_0_0 + 0.203174603174598*G0_1_1_2_0_1_0_0_1 - 0.203174603174598*G0_1_1_2_0_1_1_0_0 - 0.203174603174598*G0_1_1_2_0_1_2_0_1 + 0.203174603174598*G0_1_1_2_0_1_3_1_0 + 0.203174603174598*G0_1_1_2_0_1_3_1_1 - 0.203174603174598*G0_1_1_2_0_1_4_1_0 - 0.203174603174598*G0_1_1_2_0_1_5_1_1 - 0.203174603174598*G0_1_1_3_1_0_0_0_0 - 0.203174603174598*G0_1_1_3_1_0_0_0_1 + 0.203174603174598*G0_1_1_3_1_0_1_0_0 + 0.203174603174598*G0_1_1_3_1_0_2_0_1 - 0.203174603174598*G0_1_1_3_1_0_3_1_0 - 0.203174603174598*G0_1_1_3_1_0_3_1_1 + 0.203174603174598*G0_1_1_3_1_0_4_1_0 + 0.203174603174598*G0_1_1_3_1_0_5_1_1 - 0.203174603174598*G0_1_1_3_1_1_0_0_0 - 0.203174603174598*G0_1_1_3_1_1_0_0_1 + 0.203174603174598*G0_1_1_3_1_1_1_0_0 + 0.203174603174598*G0_1_1_3_1_1_2_0_1 - 0.203174603174598*G0_1_1_3_1_1_3_1_0 - 0.203174603174598*G0_1_1_3_1_1_3_1_1 + 0.203174603174598*G0_1_1_3_1_1_4_1_0 + 0.203174603174598*G0_1_1_3_1_1_5_1_1 + 0.203174603174598*G0_1_1_4_1_0_0_0_0 + 0.203174603174598*G0_1_1_4_1_0_0_0_1 - 0.203174603174598*G0_1_1_4_1_0_1_0_0 - 0.203174603174598*G0_1_1_4_1_0_2_0_1 + 0.203174603174598*G0_1_1_4_1_0_3_1_0 + 0.203174603174598*G0_1_1_4_1_0_3_1_1 - 0.203174603174598*G0_1_1_4_1_0_4_1_0 - 0.203174603174598*G0_1_1_4_1_0_5_1_1 + 0.203174603174598*G0_1_1_5_1_1_0_0_0 + 0.203174603174598*G0_1_1_5_1_1_0_0_1 - 0.203174603174598*G0_1_1_5_1_1_1_0_0 - 0.203174603174598*G0_1_1_5_1_1_2_0_1 + 0.203174603174598*G0_1_1_5_1_1_3_1_0 + 0.203174603174598*G0_1_1_5_1_1_3_1_1 - 0.203174603174598*G0_1_1_5_1_1_4_1_0 - 0.203174603174598*G0_1_1_5_1_1_5_1_1; + A[444] = 0.0; + A[324] = 0.0; + A[479] = A[14]; + A[351] = 0.0; + A[731] = 0.0; + A[422] = A[887]; + A[382] = 0.0; + A[760] = 0.0; + A[413] = 0.0; + A[857] = A[887]; + A[88] = 0.0; + A[781] = 0.0; + A[890] = -A[428] - 2.30264550264554*G0_1_1_0_0_0_0_0_0 - 2.30264550264554*G0_1_1_0_0_0_0_0_1 + 2.30264550264554*G0_1_1_0_0_0_1_0_0 + 2.30264550264554*G0_1_1_0_0_0_2_0_1 - 2.30264550264554*G0_1_1_0_0_0_3_1_0 - 2.30264550264554*G0_1_1_0_0_0_3_1_1 + 2.30264550264554*G0_1_1_0_0_0_4_1_0 + 2.30264550264554*G0_1_1_0_0_0_5_1_1 - 2.30264550264554*G0_1_1_0_0_1_0_0_0 - 2.30264550264554*G0_1_1_0_0_1_0_0_1 + 2.30264550264554*G0_1_1_0_0_1_1_0_0 + 2.30264550264554*G0_1_1_0_0_1_2_0_1 - 2.30264550264554*G0_1_1_0_0_1_3_1_0 - 2.30264550264554*G0_1_1_0_0_1_3_1_1 + 2.30264550264554*G0_1_1_0_0_1_4_1_0 + 2.30264550264554*G0_1_1_0_0_1_5_1_1 + 2.30264550264554*G0_1_1_1_0_0_0_0_0 + 2.30264550264554*G0_1_1_1_0_0_0_0_1 - 2.30264550264554*G0_1_1_1_0_0_1_0_0 - 2.30264550264554*G0_1_1_1_0_0_2_0_1 + 2.30264550264554*G0_1_1_1_0_0_3_1_0 + 2.30264550264554*G0_1_1_1_0_0_3_1_1 - 2.30264550264554*G0_1_1_1_0_0_4_1_0 - 2.30264550264554*G0_1_1_1_0_0_5_1_1 + 2.30264550264554*G0_1_1_2_0_1_0_0_0 + 2.30264550264554*G0_1_1_2_0_1_0_0_1 - 2.30264550264554*G0_1_1_2_0_1_1_0_0 - 2.30264550264554*G0_1_1_2_0_1_2_0_1 + 2.30264550264554*G0_1_1_2_0_1_3_1_0 + 2.30264550264554*G0_1_1_2_0_1_3_1_1 - 2.30264550264554*G0_1_1_2_0_1_4_1_0 - 2.30264550264554*G0_1_1_2_0_1_5_1_1 - 2.30264550264554*G0_1_1_3_1_0_0_0_0 - 2.30264550264554*G0_1_1_3_1_0_0_0_1 + 2.30264550264554*G0_1_1_3_1_0_1_0_0 + 2.30264550264554*G0_1_1_3_1_0_2_0_1 - 2.30264550264554*G0_1_1_3_1_0_3_1_0 - 2.30264550264554*G0_1_1_3_1_0_3_1_1 + 2.30264550264554*G0_1_1_3_1_0_4_1_0 + 2.30264550264554*G0_1_1_3_1_0_5_1_1 - 2.30264550264554*G0_1_1_3_1_1_0_0_0 - 2.30264550264554*G0_1_1_3_1_1_0_0_1 + 2.30264550264554*G0_1_1_3_1_1_1_0_0 + 2.30264550264554*G0_1_1_3_1_1_2_0_1 - 2.30264550264554*G0_1_1_3_1_1_3_1_0 - 2.30264550264554*G0_1_1_3_1_1_3_1_1 + 2.30264550264554*G0_1_1_3_1_1_4_1_0 + 2.30264550264554*G0_1_1_3_1_1_5_1_1 + 2.30264550264554*G0_1_1_4_1_0_0_0_0 + 2.30264550264554*G0_1_1_4_1_0_0_0_1 - 2.30264550264554*G0_1_1_4_1_0_1_0_0 - 2.30264550264554*G0_1_1_4_1_0_2_0_1 + 2.30264550264554*G0_1_1_4_1_0_3_1_0 + 2.30264550264554*G0_1_1_4_1_0_3_1_1 - 2.30264550264554*G0_1_1_4_1_0_4_1_0 - 2.30264550264554*G0_1_1_4_1_0_5_1_1 + 2.30264550264554*G0_1_1_5_1_1_0_0_0 + 2.30264550264554*G0_1_1_5_1_1_0_0_1 - 2.30264550264554*G0_1_1_5_1_1_1_0_0 - 2.30264550264554*G0_1_1_5_1_1_2_0_1 + 2.30264550264554*G0_1_1_5_1_1_3_1_0 + 2.30264550264554*G0_1_1_5_1_1_3_1_1 - 2.30264550264554*G0_1_1_5_1_1_4_1_0 - 2.30264550264554*G0_1_1_5_1_1_5_1_1; + A[91] = -A[331] - 0.524867724867733*G0_0_0_0_0_0_0_0_0 - 0.524867724867733*G0_0_0_0_0_0_0_0_1 + 0.524867724867733*G0_0_0_0_0_0_1_0_0 + 0.524867724867733*G0_0_0_0_0_0_2_0_1 - 0.524867724867733*G0_0_0_0_0_0_3_1_0 - 0.524867724867733*G0_0_0_0_0_0_3_1_1 + 0.524867724867733*G0_0_0_0_0_0_4_1_0 + 0.524867724867733*G0_0_0_0_0_0_5_1_1 - 0.524867724867733*G0_0_0_0_0_1_0_0_0 - 0.524867724867733*G0_0_0_0_0_1_0_0_1 + 0.524867724867733*G0_0_0_0_0_1_1_0_0 + 0.524867724867733*G0_0_0_0_0_1_2_0_1 - 0.524867724867733*G0_0_0_0_0_1_3_1_0 - 0.524867724867733*G0_0_0_0_0_1_3_1_1 + 0.524867724867733*G0_0_0_0_0_1_4_1_0 + 0.524867724867733*G0_0_0_0_0_1_5_1_1 + 0.524867724867733*G0_0_0_1_0_0_0_0_0 + 0.524867724867733*G0_0_0_1_0_0_0_0_1 - 0.524867724867733*G0_0_0_1_0_0_1_0_0 - 0.524867724867733*G0_0_0_1_0_0_2_0_1 + 0.524867724867733*G0_0_0_1_0_0_3_1_0 + 0.524867724867733*G0_0_0_1_0_0_3_1_1 - 0.524867724867733*G0_0_0_1_0_0_4_1_0 - 0.524867724867733*G0_0_0_1_0_0_5_1_1 + 0.524867724867733*G0_0_0_2_0_1_0_0_0 + 0.524867724867733*G0_0_0_2_0_1_0_0_1 - 0.524867724867733*G0_0_0_2_0_1_1_0_0 - 0.524867724867733*G0_0_0_2_0_1_2_0_1 + 0.524867724867733*G0_0_0_2_0_1_3_1_0 + 0.524867724867733*G0_0_0_2_0_1_3_1_1 - 0.524867724867733*G0_0_0_2_0_1_4_1_0 - 0.524867724867733*G0_0_0_2_0_1_5_1_1 - 0.524867724867733*G0_0_0_3_1_0_0_0_0 - 0.524867724867733*G0_0_0_3_1_0_0_0_1 + 0.524867724867733*G0_0_0_3_1_0_1_0_0 + 0.524867724867733*G0_0_0_3_1_0_2_0_1 - 0.524867724867733*G0_0_0_3_1_0_3_1_0 - 0.524867724867733*G0_0_0_3_1_0_3_1_1 + 0.524867724867733*G0_0_0_3_1_0_4_1_0 + 0.524867724867733*G0_0_0_3_1_0_5_1_1 - 0.524867724867733*G0_0_0_3_1_1_0_0_0 - 0.524867724867733*G0_0_0_3_1_1_0_0_1 + 0.524867724867733*G0_0_0_3_1_1_1_0_0 + 0.524867724867733*G0_0_0_3_1_1_2_0_1 - 0.524867724867733*G0_0_0_3_1_1_3_1_0 - 0.524867724867733*G0_0_0_3_1_1_3_1_1 + 0.524867724867733*G0_0_0_3_1_1_4_1_0 + 0.524867724867733*G0_0_0_3_1_1_5_1_1 + 0.524867724867733*G0_0_0_4_1_0_0_0_0 + 0.524867724867733*G0_0_0_4_1_0_0_0_1 - 0.524867724867733*G0_0_0_4_1_0_1_0_0 - 0.524867724867733*G0_0_0_4_1_0_2_0_1 + 0.524867724867733*G0_0_0_4_1_0_3_1_0 + 0.524867724867733*G0_0_0_4_1_0_3_1_1 - 0.524867724867733*G0_0_0_4_1_0_4_1_0 - 0.524867724867733*G0_0_0_4_1_0_5_1_1 + 0.524867724867733*G0_0_0_5_1_1_0_0_0 + 0.524867724867733*G0_0_0_5_1_1_0_0_1 - 0.524867724867733*G0_0_0_5_1_1_1_0_0 - 0.524867724867733*G0_0_0_5_1_1_2_0_1 + 0.524867724867733*G0_0_0_5_1_1_3_1_0 + 0.524867724867733*G0_0_0_5_1_1_3_1_1 - 0.524867724867733*G0_0_0_5_1_1_4_1_0 - 0.524867724867733*G0_0_0_5_1_1_5_1_1; + A[822] = 0.0; + A[146] = 0.0; + A[855] = A[14]; + A[177] = 0.0; + A[884] = 0.0; + A[493] = 0.0; + A[196] = 0.0; + A[654] = A[741]; + A[578] = 0.0; + A[518] = 0.0; + A[231] = 0.0; + A[683] = A[805] + 1.1851851851852*G0_0_0_0_0_0_0_0_0 + 1.1851851851852*G0_0_0_0_0_0_0_0_1 - 1.1851851851852*G0_0_0_0_0_0_1_0_0 - 1.1851851851852*G0_0_0_0_0_0_2_0_1 + 1.1851851851852*G0_0_0_0_0_0_3_1_0 + 1.1851851851852*G0_0_0_0_0_0_3_1_1 - 1.1851851851852*G0_0_0_0_0_0_4_1_0 - 1.1851851851852*G0_0_0_0_0_0_5_1_1 + 1.1851851851852*G0_0_0_0_0_1_0_0_0 + 1.1851851851852*G0_0_0_0_0_1_0_0_1 - 1.1851851851852*G0_0_0_0_0_1_1_0_0 - 1.1851851851852*G0_0_0_0_0_1_2_0_1 + 1.1851851851852*G0_0_0_0_0_1_3_1_0 + 1.1851851851852*G0_0_0_0_0_1_3_1_1 - 1.1851851851852*G0_0_0_0_0_1_4_1_0 - 1.1851851851852*G0_0_0_0_0_1_5_1_1 - 1.1851851851852*G0_0_0_1_0_0_0_0_0 - 1.1851851851852*G0_0_0_1_0_0_0_0_1 + 1.1851851851852*G0_0_0_1_0_0_1_0_0 + 1.1851851851852*G0_0_0_1_0_0_2_0_1 - 1.1851851851852*G0_0_0_1_0_0_3_1_0 - 1.1851851851852*G0_0_0_1_0_0_3_1_1 + 1.1851851851852*G0_0_0_1_0_0_4_1_0 + 1.1851851851852*G0_0_0_1_0_0_5_1_1 - 1.1851851851852*G0_0_0_2_0_1_0_0_0 - 1.1851851851852*G0_0_0_2_0_1_0_0_1 + 1.1851851851852*G0_0_0_2_0_1_1_0_0 + 1.1851851851852*G0_0_0_2_0_1_2_0_1 - 1.1851851851852*G0_0_0_2_0_1_3_1_0 - 1.1851851851852*G0_0_0_2_0_1_3_1_1 + 1.1851851851852*G0_0_0_2_0_1_4_1_0 + 1.1851851851852*G0_0_0_2_0_1_5_1_1 + 1.1851851851852*G0_0_0_3_1_0_0_0_0 + 1.1851851851852*G0_0_0_3_1_0_0_0_1 - 1.1851851851852*G0_0_0_3_1_0_1_0_0 - 1.1851851851852*G0_0_0_3_1_0_2_0_1 + 1.1851851851852*G0_0_0_3_1_0_3_1_0 + 1.1851851851852*G0_0_0_3_1_0_3_1_1 - 1.1851851851852*G0_0_0_3_1_0_4_1_0 - 1.1851851851852*G0_0_0_3_1_0_5_1_1 + 1.1851851851852*G0_0_0_3_1_1_0_0_0 + 1.1851851851852*G0_0_0_3_1_1_0_0_1 - 1.1851851851852*G0_0_0_3_1_1_1_0_0 - 1.1851851851852*G0_0_0_3_1_1_2_0_1 + 1.1851851851852*G0_0_0_3_1_1_3_1_0 + 1.1851851851852*G0_0_0_3_1_1_3_1_1 - 1.1851851851852*G0_0_0_3_1_1_4_1_0 - 1.1851851851852*G0_0_0_3_1_1_5_1_1 - 1.1851851851852*G0_0_0_4_1_0_0_0_0 - 1.1851851851852*G0_0_0_4_1_0_0_0_1 + 1.1851851851852*G0_0_0_4_1_0_1_0_0 + 1.1851851851852*G0_0_0_4_1_0_2_0_1 - 1.1851851851852*G0_0_0_4_1_0_3_1_0 - 1.1851851851852*G0_0_0_4_1_0_3_1_1 + 1.1851851851852*G0_0_0_4_1_0_4_1_0 + 1.1851851851852*G0_0_0_4_1_0_5_1_1 - 1.1851851851852*G0_0_0_5_1_1_0_0_0 - 1.1851851851852*G0_0_0_5_1_1_0_0_1 + 1.1851851851852*G0_0_0_5_1_1_1_0_0 + 1.1851851851852*G0_0_0_5_1_1_2_0_1 - 1.1851851851852*G0_0_0_5_1_1_3_1_0 - 1.1851851851852*G0_0_0_5_1_1_3_1_1 + 1.1851851851852*G0_0_0_5_1_1_4_1_0 + 1.1851851851852*G0_0_0_5_1_1_5_1_1 - 1.1851851851852*G0_1_1_0_0_0_0_0_0 - 1.1851851851852*G0_1_1_0_0_0_0_0_1 + 1.1851851851852*G0_1_1_0_0_0_1_0_0 + 1.1851851851852*G0_1_1_0_0_0_2_0_1 - 1.1851851851852*G0_1_1_0_0_0_3_1_0 - 1.1851851851852*G0_1_1_0_0_0_3_1_1 + 1.1851851851852*G0_1_1_0_0_0_4_1_0 + 1.1851851851852*G0_1_1_0_0_0_5_1_1 - 1.1851851851852*G0_1_1_0_0_1_0_0_0 - 1.1851851851852*G0_1_1_0_0_1_0_0_1 + 1.1851851851852*G0_1_1_0_0_1_1_0_0 + 1.1851851851852*G0_1_1_0_0_1_2_0_1 - 1.1851851851852*G0_1_1_0_0_1_3_1_0 - 1.1851851851852*G0_1_1_0_0_1_3_1_1 + 1.1851851851852*G0_1_1_0_0_1_4_1_0 + 1.1851851851852*G0_1_1_0_0_1_5_1_1 + 1.1851851851852*G0_1_1_1_0_0_0_0_0 + 1.1851851851852*G0_1_1_1_0_0_0_0_1 - 1.1851851851852*G0_1_1_1_0_0_1_0_0 - 1.1851851851852*G0_1_1_1_0_0_2_0_1 + 1.1851851851852*G0_1_1_1_0_0_3_1_0 + 1.1851851851852*G0_1_1_1_0_0_3_1_1 - 1.1851851851852*G0_1_1_1_0_0_4_1_0 - 1.1851851851852*G0_1_1_1_0_0_5_1_1 + 1.1851851851852*G0_1_1_2_0_1_0_0_0 + 1.1851851851852*G0_1_1_2_0_1_0_0_1 - 1.1851851851852*G0_1_1_2_0_1_1_0_0 - 1.1851851851852*G0_1_1_2_0_1_2_0_1 + 1.1851851851852*G0_1_1_2_0_1_3_1_0 + 1.1851851851852*G0_1_1_2_0_1_3_1_1 - 1.1851851851852*G0_1_1_2_0_1_4_1_0 - 1.1851851851852*G0_1_1_2_0_1_5_1_1 - 1.1851851851852*G0_1_1_3_1_0_0_0_0 - 1.1851851851852*G0_1_1_3_1_0_0_0_1 + 1.1851851851852*G0_1_1_3_1_0_1_0_0 + 1.1851851851852*G0_1_1_3_1_0_2_0_1 - 1.1851851851852*G0_1_1_3_1_0_3_1_0 - 1.1851851851852*G0_1_1_3_1_0_3_1_1 + 1.1851851851852*G0_1_1_3_1_0_4_1_0 + 1.1851851851852*G0_1_1_3_1_0_5_1_1 - 1.1851851851852*G0_1_1_3_1_1_0_0_0 - 1.1851851851852*G0_1_1_3_1_1_0_0_1 + 1.1851851851852*G0_1_1_3_1_1_1_0_0 + 1.1851851851852*G0_1_1_3_1_1_2_0_1 - 1.1851851851852*G0_1_1_3_1_1_3_1_0 - 1.1851851851852*G0_1_1_3_1_1_3_1_1 + 1.1851851851852*G0_1_1_3_1_1_4_1_0 + 1.1851851851852*G0_1_1_3_1_1_5_1_1 + 1.1851851851852*G0_1_1_4_1_0_0_0_0 + 1.1851851851852*G0_1_1_4_1_0_0_0_1 - 1.1851851851852*G0_1_1_4_1_0_1_0_0 - 1.1851851851852*G0_1_1_4_1_0_2_0_1 + 1.1851851851852*G0_1_1_4_1_0_3_1_0 + 1.1851851851852*G0_1_1_4_1_0_3_1_1 - 1.1851851851852*G0_1_1_4_1_0_4_1_0 - 1.1851851851852*G0_1_1_4_1_0_5_1_1 + 1.1851851851852*G0_1_1_5_1_1_0_0_0 + 1.1851851851852*G0_1_1_5_1_1_0_0_1 - 1.1851851851852*G0_1_1_5_1_1_1_0_0 - 1.1851851851852*G0_1_1_5_1_1_2_0_1 + 1.1851851851852*G0_1_1_5_1_1_3_1_0 + 1.1851851851852*G0_1_1_5_1_1_3_1_1 - 1.1851851851852*G0_1_1_5_1_1_4_1_0 - 1.1851851851852*G0_1_1_5_1_1_5_1_1; + A[247] = A[683] + 1.11746031746033*G0_0_1_0_0_0_0_0_0 + 1.11746031746033*G0_0_1_0_0_0_0_0_1 - 1.11746031746033*G0_0_1_0_0_0_1_0_0 - 1.11746031746033*G0_0_1_0_0_0_2_0_1 + 1.11746031746033*G0_0_1_0_0_0_3_1_0 + 1.11746031746033*G0_0_1_0_0_0_3_1_1 - 1.11746031746033*G0_0_1_0_0_0_4_1_0 - 1.11746031746033*G0_0_1_0_0_0_5_1_1 + 1.11746031746033*G0_0_1_0_0_1_0_0_0 + 1.11746031746033*G0_0_1_0_0_1_0_0_1 - 1.11746031746033*G0_0_1_0_0_1_1_0_0 - 1.11746031746033*G0_0_1_0_0_1_2_0_1 + 1.11746031746033*G0_0_1_0_0_1_3_1_0 + 1.11746031746033*G0_0_1_0_0_1_3_1_1 - 1.11746031746033*G0_0_1_0_0_1_4_1_0 - 1.11746031746033*G0_0_1_0_0_1_5_1_1 - 1.11746031746033*G0_0_1_1_0_0_0_0_0 - 1.11746031746033*G0_0_1_1_0_0_0_0_1 + 1.11746031746033*G0_0_1_1_0_0_1_0_0 + 1.11746031746033*G0_0_1_1_0_0_2_0_1 - 1.11746031746033*G0_0_1_1_0_0_3_1_0 - 1.11746031746033*G0_0_1_1_0_0_3_1_1 + 1.11746031746033*G0_0_1_1_0_0_4_1_0 + 1.11746031746033*G0_0_1_1_0_0_5_1_1 - 1.11746031746033*G0_0_1_2_0_1_0_0_0 - 1.11746031746033*G0_0_1_2_0_1_0_0_1 + 1.11746031746033*G0_0_1_2_0_1_1_0_0 + 1.11746031746033*G0_0_1_2_0_1_2_0_1 - 1.11746031746033*G0_0_1_2_0_1_3_1_0 - 1.11746031746033*G0_0_1_2_0_1_3_1_1 + 1.11746031746033*G0_0_1_2_0_1_4_1_0 + 1.11746031746033*G0_0_1_2_0_1_5_1_1 + 1.11746031746033*G0_0_1_3_1_0_0_0_0 + 1.11746031746033*G0_0_1_3_1_0_0_0_1 - 1.11746031746033*G0_0_1_3_1_0_1_0_0 - 1.11746031746033*G0_0_1_3_1_0_2_0_1 + 1.11746031746033*G0_0_1_3_1_0_3_1_0 + 1.11746031746033*G0_0_1_3_1_0_3_1_1 - 1.11746031746033*G0_0_1_3_1_0_4_1_0 - 1.11746031746033*G0_0_1_3_1_0_5_1_1 + 1.11746031746033*G0_0_1_3_1_1_0_0_0 + 1.11746031746033*G0_0_1_3_1_1_0_0_1 - 1.11746031746033*G0_0_1_3_1_1_1_0_0 - 1.11746031746033*G0_0_1_3_1_1_2_0_1 + 1.11746031746033*G0_0_1_3_1_1_3_1_0 + 1.11746031746033*G0_0_1_3_1_1_3_1_1 - 1.11746031746033*G0_0_1_3_1_1_4_1_0 - 1.11746031746033*G0_0_1_3_1_1_5_1_1 - 1.11746031746033*G0_0_1_4_1_0_0_0_0 - 1.11746031746033*G0_0_1_4_1_0_0_0_1 + 1.11746031746033*G0_0_1_4_1_0_1_0_0 + 1.11746031746033*G0_0_1_4_1_0_2_0_1 - 1.11746031746033*G0_0_1_4_1_0_3_1_0 - 1.11746031746033*G0_0_1_4_1_0_3_1_1 + 1.11746031746033*G0_0_1_4_1_0_4_1_0 + 1.11746031746033*G0_0_1_4_1_0_5_1_1 - 1.11746031746033*G0_0_1_5_1_1_0_0_0 - 1.11746031746033*G0_0_1_5_1_1_0_0_1 + 1.11746031746033*G0_0_1_5_1_1_1_0_0 + 1.11746031746033*G0_0_1_5_1_1_2_0_1 - 1.11746031746033*G0_0_1_5_1_1_3_1_0 - 1.11746031746033*G0_0_1_5_1_1_3_1_1 + 1.11746031746033*G0_0_1_5_1_1_4_1_0 + 1.11746031746033*G0_0_1_5_1_1_5_1_1 - 1.11746031746033*G0_1_0_0_0_0_0_0_0 - 1.11746031746033*G0_1_0_0_0_0_0_0_1 + 1.11746031746033*G0_1_0_0_0_0_1_0_0 + 1.11746031746033*G0_1_0_0_0_0_2_0_1 - 1.11746031746033*G0_1_0_0_0_0_3_1_0 - 1.11746031746033*G0_1_0_0_0_0_3_1_1 + 1.11746031746033*G0_1_0_0_0_0_4_1_0 + 1.11746031746033*G0_1_0_0_0_0_5_1_1 - 1.11746031746033*G0_1_0_0_0_1_0_0_0 - 1.11746031746033*G0_1_0_0_0_1_0_0_1 + 1.11746031746033*G0_1_0_0_0_1_1_0_0 + 1.11746031746033*G0_1_0_0_0_1_2_0_1 - 1.11746031746033*G0_1_0_0_0_1_3_1_0 - 1.11746031746033*G0_1_0_0_0_1_3_1_1 + 1.11746031746033*G0_1_0_0_0_1_4_1_0 + 1.11746031746033*G0_1_0_0_0_1_5_1_1 + 1.11746031746033*G0_1_0_1_0_0_0_0_0 + 1.11746031746033*G0_1_0_1_0_0_0_0_1 - 1.11746031746033*G0_1_0_1_0_0_1_0_0 - 1.11746031746033*G0_1_0_1_0_0_2_0_1 + 1.11746031746033*G0_1_0_1_0_0_3_1_0 + 1.11746031746033*G0_1_0_1_0_0_3_1_1 - 1.11746031746033*G0_1_0_1_0_0_4_1_0 - 1.11746031746033*G0_1_0_1_0_0_5_1_1 + 1.11746031746033*G0_1_0_2_0_1_0_0_0 + 1.11746031746033*G0_1_0_2_0_1_0_0_1 - 1.11746031746033*G0_1_0_2_0_1_1_0_0 - 1.11746031746033*G0_1_0_2_0_1_2_0_1 + 1.11746031746033*G0_1_0_2_0_1_3_1_0 + 1.11746031746033*G0_1_0_2_0_1_3_1_1 - 1.11746031746033*G0_1_0_2_0_1_4_1_0 - 1.11746031746033*G0_1_0_2_0_1_5_1_1 - 1.11746031746033*G0_1_0_3_1_0_0_0_0 - 1.11746031746033*G0_1_0_3_1_0_0_0_1 + 1.11746031746033*G0_1_0_3_1_0_1_0_0 + 1.11746031746033*G0_1_0_3_1_0_2_0_1 - 1.11746031746033*G0_1_0_3_1_0_3_1_0 - 1.11746031746033*G0_1_0_3_1_0_3_1_1 + 1.11746031746033*G0_1_0_3_1_0_4_1_0 + 1.11746031746033*G0_1_0_3_1_0_5_1_1 - 1.11746031746033*G0_1_0_3_1_1_0_0_0 - 1.11746031746033*G0_1_0_3_1_1_0_0_1 + 1.11746031746033*G0_1_0_3_1_1_1_0_0 + 1.11746031746033*G0_1_0_3_1_1_2_0_1 - 1.11746031746033*G0_1_0_3_1_1_3_1_0 - 1.11746031746033*G0_1_0_3_1_1_3_1_1 + 1.11746031746033*G0_1_0_3_1_1_4_1_0 + 1.11746031746033*G0_1_0_3_1_1_5_1_1 + 1.11746031746033*G0_1_0_4_1_0_0_0_0 + 1.11746031746033*G0_1_0_4_1_0_0_0_1 - 1.11746031746033*G0_1_0_4_1_0_1_0_0 - 1.11746031746033*G0_1_0_4_1_0_2_0_1 + 1.11746031746033*G0_1_0_4_1_0_3_1_0 + 1.11746031746033*G0_1_0_4_1_0_3_1_1 - 1.11746031746033*G0_1_0_4_1_0_4_1_0 - 1.11746031746033*G0_1_0_4_1_0_5_1_1 + 1.11746031746033*G0_1_0_5_1_1_0_0_0 + 1.11746031746033*G0_1_0_5_1_1_0_0_1 - 1.11746031746033*G0_1_0_5_1_1_1_0_0 - 1.11746031746033*G0_1_0_5_1_1_2_0_1 + 1.11746031746033*G0_1_0_5_1_1_3_1_0 + 1.11746031746033*G0_1_0_5_1_1_3_1_1 - 1.11746031746033*G0_1_0_5_1_1_4_1_0 - 1.11746031746033*G0_1_0_5_1_1_5_1_1; + A[603] = 0.0; + A[555] = A[5]; + A[712] = A[247]; + A[632] = 0.0; + A[249] = A[743]; + A[669] = 0.0; + A[702] = 0.0; + A[303] = -A[805] - 1.84550264550266*G0_0_0_0_0_0_0_0_0 - 1.84550264550266*G0_0_0_0_0_0_0_0_1 + 1.84550264550266*G0_0_0_0_0_0_1_0_0 + 1.84550264550266*G0_0_0_0_0_0_2_0_1 - 1.84550264550266*G0_0_0_0_0_0_3_1_0 - 1.84550264550266*G0_0_0_0_0_0_3_1_1 + 1.84550264550266*G0_0_0_0_0_0_4_1_0 + 1.84550264550266*G0_0_0_0_0_0_5_1_1 - 1.84550264550266*G0_0_0_0_0_1_0_0_0 - 1.84550264550266*G0_0_0_0_0_1_0_0_1 + 1.84550264550266*G0_0_0_0_0_1_1_0_0 + 1.84550264550266*G0_0_0_0_0_1_2_0_1 - 1.84550264550266*G0_0_0_0_0_1_3_1_0 - 1.84550264550266*G0_0_0_0_0_1_3_1_1 + 1.84550264550266*G0_0_0_0_0_1_4_1_0 + 1.84550264550266*G0_0_0_0_0_1_5_1_1 + 1.84550264550266*G0_0_0_1_0_0_0_0_0 + 1.84550264550266*G0_0_0_1_0_0_0_0_1 - 1.84550264550266*G0_0_0_1_0_0_1_0_0 - 1.84550264550266*G0_0_0_1_0_0_2_0_1 + 1.84550264550266*G0_0_0_1_0_0_3_1_0 + 1.84550264550266*G0_0_0_1_0_0_3_1_1 - 1.84550264550266*G0_0_0_1_0_0_4_1_0 - 1.84550264550266*G0_0_0_1_0_0_5_1_1 + 1.84550264550266*G0_0_0_2_0_1_0_0_0 + 1.84550264550266*G0_0_0_2_0_1_0_0_1 - 1.84550264550266*G0_0_0_2_0_1_1_0_0 - 1.84550264550266*G0_0_0_2_0_1_2_0_1 + 1.84550264550266*G0_0_0_2_0_1_3_1_0 + 1.84550264550266*G0_0_0_2_0_1_3_1_1 - 1.84550264550266*G0_0_0_2_0_1_4_1_0 - 1.84550264550266*G0_0_0_2_0_1_5_1_1 - 1.84550264550266*G0_0_0_3_1_0_0_0_0 - 1.84550264550266*G0_0_0_3_1_0_0_0_1 + 1.84550264550266*G0_0_0_3_1_0_1_0_0 + 1.84550264550266*G0_0_0_3_1_0_2_0_1 - 1.84550264550266*G0_0_0_3_1_0_3_1_0 - 1.84550264550266*G0_0_0_3_1_0_3_1_1 + 1.84550264550266*G0_0_0_3_1_0_4_1_0 + 1.84550264550266*G0_0_0_3_1_0_5_1_1 - 1.84550264550266*G0_0_0_3_1_1_0_0_0 - 1.84550264550266*G0_0_0_3_1_1_0_0_1 + 1.84550264550266*G0_0_0_3_1_1_1_0_0 + 1.84550264550266*G0_0_0_3_1_1_2_0_1 - 1.84550264550266*G0_0_0_3_1_1_3_1_0 - 1.84550264550266*G0_0_0_3_1_1_3_1_1 + 1.84550264550266*G0_0_0_3_1_1_4_1_0 + 1.84550264550266*G0_0_0_3_1_1_5_1_1 + 1.84550264550266*G0_0_0_4_1_0_0_0_0 + 1.84550264550266*G0_0_0_4_1_0_0_0_1 - 1.84550264550266*G0_0_0_4_1_0_1_0_0 - 1.84550264550266*G0_0_0_4_1_0_2_0_1 + 1.84550264550266*G0_0_0_4_1_0_3_1_0 + 1.84550264550266*G0_0_0_4_1_0_3_1_1 - 1.84550264550266*G0_0_0_4_1_0_4_1_0 - 1.84550264550266*G0_0_0_4_1_0_5_1_1 + 1.84550264550266*G0_0_0_5_1_1_0_0_0 + 1.84550264550266*G0_0_0_5_1_1_0_0_1 - 1.84550264550266*G0_0_0_5_1_1_1_0_0 - 1.84550264550266*G0_0_0_5_1_1_2_0_1 + 1.84550264550266*G0_0_0_5_1_1_3_1_0 + 1.84550264550266*G0_0_0_5_1_1_3_1_1 - 1.84550264550266*G0_0_0_5_1_1_4_1_0 - 1.84550264550266*G0_0_0_5_1_1_5_1_1 - 1.11746031746033*G0_0_1_0_0_0_0_0_0 - 1.11746031746033*G0_0_1_0_0_0_0_0_1 + 1.11746031746033*G0_0_1_0_0_0_1_0_0 + 1.11746031746033*G0_0_1_0_0_0_2_0_1 - 1.11746031746033*G0_0_1_0_0_0_3_1_0 - 1.11746031746033*G0_0_1_0_0_0_3_1_1 + 1.11746031746033*G0_0_1_0_0_0_4_1_0 + 1.11746031746033*G0_0_1_0_0_0_5_1_1 - 1.11746031746033*G0_0_1_0_0_1_0_0_0 - 1.11746031746033*G0_0_1_0_0_1_0_0_1 + 1.11746031746033*G0_0_1_0_0_1_1_0_0 + 1.11746031746033*G0_0_1_0_0_1_2_0_1 - 1.11746031746033*G0_0_1_0_0_1_3_1_0 - 1.11746031746033*G0_0_1_0_0_1_3_1_1 + 1.11746031746033*G0_0_1_0_0_1_4_1_0 + 1.11746031746033*G0_0_1_0_0_1_5_1_1 + 1.11746031746033*G0_0_1_1_0_0_0_0_0 + 1.11746031746033*G0_0_1_1_0_0_0_0_1 - 1.11746031746033*G0_0_1_1_0_0_1_0_0 - 1.11746031746033*G0_0_1_1_0_0_2_0_1 + 1.11746031746033*G0_0_1_1_0_0_3_1_0 + 1.11746031746033*G0_0_1_1_0_0_3_1_1 - 1.11746031746033*G0_0_1_1_0_0_4_1_0 - 1.11746031746033*G0_0_1_1_0_0_5_1_1 + 1.11746031746033*G0_0_1_2_0_1_0_0_0 + 1.11746031746033*G0_0_1_2_0_1_0_0_1 - 1.11746031746033*G0_0_1_2_0_1_1_0_0 - 1.11746031746033*G0_0_1_2_0_1_2_0_1 + 1.11746031746033*G0_0_1_2_0_1_3_1_0 + 1.11746031746033*G0_0_1_2_0_1_3_1_1 - 1.11746031746033*G0_0_1_2_0_1_4_1_0 - 1.11746031746033*G0_0_1_2_0_1_5_1_1 - 1.11746031746033*G0_0_1_3_1_0_0_0_0 - 1.11746031746033*G0_0_1_3_1_0_0_0_1 + 1.11746031746033*G0_0_1_3_1_0_1_0_0 + 1.11746031746033*G0_0_1_3_1_0_2_0_1 - 1.11746031746033*G0_0_1_3_1_0_3_1_0 - 1.11746031746033*G0_0_1_3_1_0_3_1_1 + 1.11746031746033*G0_0_1_3_1_0_4_1_0 + 1.11746031746033*G0_0_1_3_1_0_5_1_1 - 1.11746031746033*G0_0_1_3_1_1_0_0_0 - 1.11746031746033*G0_0_1_3_1_1_0_0_1 + 1.11746031746033*G0_0_1_3_1_1_1_0_0 + 1.11746031746033*G0_0_1_3_1_1_2_0_1 - 1.11746031746033*G0_0_1_3_1_1_3_1_0 - 1.11746031746033*G0_0_1_3_1_1_3_1_1 + 1.11746031746033*G0_0_1_3_1_1_4_1_0 + 1.11746031746033*G0_0_1_3_1_1_5_1_1 + 1.11746031746033*G0_0_1_4_1_0_0_0_0 + 1.11746031746033*G0_0_1_4_1_0_0_0_1 - 1.11746031746033*G0_0_1_4_1_0_1_0_0 - 1.11746031746033*G0_0_1_4_1_0_2_0_1 + 1.11746031746033*G0_0_1_4_1_0_3_1_0 + 1.11746031746033*G0_0_1_4_1_0_3_1_1 - 1.11746031746033*G0_0_1_4_1_0_4_1_0 - 1.11746031746033*G0_0_1_4_1_0_5_1_1 + 1.11746031746033*G0_0_1_5_1_1_0_0_0 + 1.11746031746033*G0_0_1_5_1_1_0_0_1 - 1.11746031746033*G0_0_1_5_1_1_1_0_0 - 1.11746031746033*G0_0_1_5_1_1_2_0_1 + 1.11746031746033*G0_0_1_5_1_1_3_1_0 + 1.11746031746033*G0_0_1_5_1_1_3_1_1 - 1.11746031746033*G0_0_1_5_1_1_4_1_0 - 1.11746031746033*G0_0_1_5_1_1_5_1_1; + A[314] = -A[303] + 0.414814814814821*G0_0_1_0_0_0_0_0_0 + 0.414814814814821*G0_0_1_0_0_0_0_0_1 - 0.414814814814821*G0_0_1_0_0_0_1_0_0 - 0.414814814814821*G0_0_1_0_0_0_2_0_1 + 0.414814814814821*G0_0_1_0_0_0_3_1_0 + 0.414814814814821*G0_0_1_0_0_0_3_1_1 - 0.414814814814821*G0_0_1_0_0_0_4_1_0 - 0.414814814814821*G0_0_1_0_0_0_5_1_1 + 0.414814814814821*G0_0_1_0_0_1_0_0_0 + 0.414814814814821*G0_0_1_0_0_1_0_0_1 - 0.414814814814821*G0_0_1_0_0_1_1_0_0 - 0.414814814814821*G0_0_1_0_0_1_2_0_1 + 0.414814814814821*G0_0_1_0_0_1_3_1_0 + 0.414814814814821*G0_0_1_0_0_1_3_1_1 - 0.414814814814821*G0_0_1_0_0_1_4_1_0 - 0.414814814814821*G0_0_1_0_0_1_5_1_1 - 0.414814814814821*G0_0_1_1_0_0_0_0_0 - 0.414814814814821*G0_0_1_1_0_0_0_0_1 + 0.414814814814821*G0_0_1_1_0_0_1_0_0 + 0.414814814814821*G0_0_1_1_0_0_2_0_1 - 0.414814814814821*G0_0_1_1_0_0_3_1_0 - 0.414814814814821*G0_0_1_1_0_0_3_1_1 + 0.414814814814821*G0_0_1_1_0_0_4_1_0 + 0.414814814814821*G0_0_1_1_0_0_5_1_1 - 0.414814814814821*G0_0_1_2_0_1_0_0_0 - 0.414814814814821*G0_0_1_2_0_1_0_0_1 + 0.414814814814821*G0_0_1_2_0_1_1_0_0 + 0.414814814814821*G0_0_1_2_0_1_2_0_1 - 0.414814814814821*G0_0_1_2_0_1_3_1_0 - 0.414814814814821*G0_0_1_2_0_1_3_1_1 + 0.414814814814821*G0_0_1_2_0_1_4_1_0 + 0.414814814814821*G0_0_1_2_0_1_5_1_1 + 0.414814814814821*G0_0_1_3_1_0_0_0_0 + 0.414814814814821*G0_0_1_3_1_0_0_0_1 - 0.414814814814821*G0_0_1_3_1_0_1_0_0 - 0.414814814814821*G0_0_1_3_1_0_2_0_1 + 0.414814814814821*G0_0_1_3_1_0_3_1_0 + 0.414814814814821*G0_0_1_3_1_0_3_1_1 - 0.414814814814821*G0_0_1_3_1_0_4_1_0 - 0.414814814814821*G0_0_1_3_1_0_5_1_1 + 0.414814814814821*G0_0_1_3_1_1_0_0_0 + 0.414814814814821*G0_0_1_3_1_1_0_0_1 - 0.414814814814821*G0_0_1_3_1_1_1_0_0 - 0.414814814814821*G0_0_1_3_1_1_2_0_1 + 0.414814814814821*G0_0_1_3_1_1_3_1_0 + 0.414814814814821*G0_0_1_3_1_1_3_1_1 - 0.414814814814821*G0_0_1_3_1_1_4_1_0 - 0.414814814814821*G0_0_1_3_1_1_5_1_1 - 0.414814814814821*G0_0_1_4_1_0_0_0_0 - 0.414814814814821*G0_0_1_4_1_0_0_0_1 + 0.414814814814821*G0_0_1_4_1_0_1_0_0 + 0.414814814814821*G0_0_1_4_1_0_2_0_1 - 0.414814814814821*G0_0_1_4_1_0_3_1_0 - 0.414814814814821*G0_0_1_4_1_0_3_1_1 + 0.414814814814821*G0_0_1_4_1_0_4_1_0 + 0.414814814814821*G0_0_1_4_1_0_5_1_1 - 0.414814814814821*G0_0_1_5_1_1_0_0_0 - 0.414814814814821*G0_0_1_5_1_1_0_0_1 + 0.414814814814821*G0_0_1_5_1_1_1_0_0 + 0.414814814814821*G0_0_1_5_1_1_2_0_1 - 0.414814814814821*G0_0_1_5_1_1_3_1_0 - 0.414814814814821*G0_0_1_5_1_1_3_1_1 + 0.414814814814821*G0_0_1_5_1_1_4_1_0 + 0.414814814814821*G0_0_1_5_1_1_5_1_1 + 0.414814814814826*G0_1_0_0_0_0_0_0_0 + 0.414814814814826*G0_1_0_0_0_0_0_0_1 - 0.414814814814826*G0_1_0_0_0_0_1_0_0 - 0.414814814814826*G0_1_0_0_0_0_2_0_1 + 0.414814814814826*G0_1_0_0_0_0_3_1_0 + 0.414814814814826*G0_1_0_0_0_0_3_1_1 - 0.414814814814826*G0_1_0_0_0_0_4_1_0 - 0.414814814814826*G0_1_0_0_0_0_5_1_1 + 0.414814814814826*G0_1_0_0_0_1_0_0_0 + 0.414814814814826*G0_1_0_0_0_1_0_0_1 - 0.414814814814826*G0_1_0_0_0_1_1_0_0 - 0.414814814814826*G0_1_0_0_0_1_2_0_1 + 0.414814814814826*G0_1_0_0_0_1_3_1_0 + 0.414814814814826*G0_1_0_0_0_1_3_1_1 - 0.414814814814826*G0_1_0_0_0_1_4_1_0 - 0.414814814814826*G0_1_0_0_0_1_5_1_1 - 0.414814814814826*G0_1_0_1_0_0_0_0_0 - 0.414814814814826*G0_1_0_1_0_0_0_0_1 + 0.414814814814826*G0_1_0_1_0_0_1_0_0 + 0.414814814814826*G0_1_0_1_0_0_2_0_1 - 0.414814814814826*G0_1_0_1_0_0_3_1_0 - 0.414814814814826*G0_1_0_1_0_0_3_1_1 + 0.414814814814826*G0_1_0_1_0_0_4_1_0 + 0.414814814814826*G0_1_0_1_0_0_5_1_1 - 0.414814814814826*G0_1_0_2_0_1_0_0_0 - 0.414814814814826*G0_1_0_2_0_1_0_0_1 + 0.414814814814826*G0_1_0_2_0_1_1_0_0 + 0.414814814814826*G0_1_0_2_0_1_2_0_1 - 0.414814814814826*G0_1_0_2_0_1_3_1_0 - 0.414814814814826*G0_1_0_2_0_1_3_1_1 + 0.414814814814826*G0_1_0_2_0_1_4_1_0 + 0.414814814814826*G0_1_0_2_0_1_5_1_1 + 0.414814814814826*G0_1_0_3_1_0_0_0_0 + 0.414814814814826*G0_1_0_3_1_0_0_0_1 - 0.414814814814826*G0_1_0_3_1_0_1_0_0 - 0.414814814814826*G0_1_0_3_1_0_2_0_1 + 0.414814814814826*G0_1_0_3_1_0_3_1_0 + 0.414814814814826*G0_1_0_3_1_0_3_1_1 - 0.414814814814826*G0_1_0_3_1_0_4_1_0 - 0.414814814814826*G0_1_0_3_1_0_5_1_1 + 0.414814814814826*G0_1_0_3_1_1_0_0_0 + 0.414814814814826*G0_1_0_3_1_1_0_0_1 - 0.414814814814826*G0_1_0_3_1_1_1_0_0 - 0.414814814814826*G0_1_0_3_1_1_2_0_1 + 0.414814814814826*G0_1_0_3_1_1_3_1_0 + 0.414814814814826*G0_1_0_3_1_1_3_1_1 - 0.414814814814826*G0_1_0_3_1_1_4_1_0 - 0.414814814814826*G0_1_0_3_1_1_5_1_1 - 0.414814814814826*G0_1_0_4_1_0_0_0_0 - 0.414814814814826*G0_1_0_4_1_0_0_0_1 + 0.414814814814826*G0_1_0_4_1_0_1_0_0 + 0.414814814814826*G0_1_0_4_1_0_2_0_1 - 0.414814814814826*G0_1_0_4_1_0_3_1_0 - 0.414814814814826*G0_1_0_4_1_0_3_1_1 + 0.414814814814826*G0_1_0_4_1_0_4_1_0 + 0.414814814814826*G0_1_0_4_1_0_5_1_1 - 0.414814814814826*G0_1_0_5_1_1_0_0_0 - 0.414814814814826*G0_1_0_5_1_1_0_0_1 + 0.414814814814826*G0_1_0_5_1_1_1_0_0 + 0.414814814814826*G0_1_0_5_1_1_2_0_1 - 0.414814814814826*G0_1_0_5_1_1_3_1_0 - 0.414814814814826*G0_1_0_5_1_1_3_1_1 + 0.414814814814826*G0_1_0_5_1_1_4_1_0 + 0.414814814814826*G0_1_0_5_1_1_5_1_1 + 1.168253968254*G0_1_1_0_0_0_0_0_0 + 1.168253968254*G0_1_1_0_0_0_0_0_1 - 1.168253968254*G0_1_1_0_0_0_1_0_0 - 1.168253968254*G0_1_1_0_0_0_2_0_1 + 1.168253968254*G0_1_1_0_0_0_3_1_0 + 1.168253968254*G0_1_1_0_0_0_3_1_1 - 1.168253968254*G0_1_1_0_0_0_4_1_0 - 1.168253968254*G0_1_1_0_0_0_5_1_1 + 1.168253968254*G0_1_1_0_0_1_0_0_0 + 1.168253968254*G0_1_1_0_0_1_0_0_1 - 1.168253968254*G0_1_1_0_0_1_1_0_0 - 1.168253968254*G0_1_1_0_0_1_2_0_1 + 1.168253968254*G0_1_1_0_0_1_3_1_0 + 1.168253968254*G0_1_1_0_0_1_3_1_1 - 1.168253968254*G0_1_1_0_0_1_4_1_0 - 1.168253968254*G0_1_1_0_0_1_5_1_1 - 1.168253968254*G0_1_1_1_0_0_0_0_0 - 1.168253968254*G0_1_1_1_0_0_0_0_1 + 1.168253968254*G0_1_1_1_0_0_1_0_0 + 1.168253968254*G0_1_1_1_0_0_2_0_1 - 1.168253968254*G0_1_1_1_0_0_3_1_0 - 1.168253968254*G0_1_1_1_0_0_3_1_1 + 1.168253968254*G0_1_1_1_0_0_4_1_0 + 1.168253968254*G0_1_1_1_0_0_5_1_1 - 1.168253968254*G0_1_1_2_0_1_0_0_0 - 1.168253968254*G0_1_1_2_0_1_0_0_1 + 1.168253968254*G0_1_1_2_0_1_1_0_0 + 1.168253968254*G0_1_1_2_0_1_2_0_1 - 1.168253968254*G0_1_1_2_0_1_3_1_0 - 1.168253968254*G0_1_1_2_0_1_3_1_1 + 1.168253968254*G0_1_1_2_0_1_4_1_0 + 1.168253968254*G0_1_1_2_0_1_5_1_1 + 1.168253968254*G0_1_1_3_1_0_0_0_0 + 1.168253968254*G0_1_1_3_1_0_0_0_1 - 1.168253968254*G0_1_1_3_1_0_1_0_0 - 1.168253968254*G0_1_1_3_1_0_2_0_1 + 1.168253968254*G0_1_1_3_1_0_3_1_0 + 1.168253968254*G0_1_1_3_1_0_3_1_1 - 1.168253968254*G0_1_1_3_1_0_4_1_0 - 1.168253968254*G0_1_1_3_1_0_5_1_1 + 1.168253968254*G0_1_1_3_1_1_0_0_0 + 1.168253968254*G0_1_1_3_1_1_0_0_1 - 1.168253968254*G0_1_1_3_1_1_1_0_0 - 1.168253968254*G0_1_1_3_1_1_2_0_1 + 1.168253968254*G0_1_1_3_1_1_3_1_0 + 1.168253968254*G0_1_1_3_1_1_3_1_1 - 1.168253968254*G0_1_1_3_1_1_4_1_0 - 1.168253968254*G0_1_1_3_1_1_5_1_1 - 1.168253968254*G0_1_1_4_1_0_0_0_0 - 1.168253968254*G0_1_1_4_1_0_0_0_1 + 1.168253968254*G0_1_1_4_1_0_1_0_0 + 1.168253968254*G0_1_1_4_1_0_2_0_1 - 1.168253968254*G0_1_1_4_1_0_3_1_0 - 1.168253968254*G0_1_1_4_1_0_3_1_1 + 1.168253968254*G0_1_1_4_1_0_4_1_0 + 1.168253968254*G0_1_1_4_1_0_5_1_1 - 1.168253968254*G0_1_1_5_1_1_0_0_0 - 1.168253968254*G0_1_1_5_1_1_0_0_1 + 1.168253968254*G0_1_1_5_1_1_1_0_0 + 1.168253968254*G0_1_1_5_1_1_2_0_1 - 1.168253968254*G0_1_1_5_1_1_3_1_0 - 1.168253968254*G0_1_1_5_1_1_3_1_1 + 1.168253968254*G0_1_1_5_1_1_4_1_0 + 1.168253968254*G0_1_1_5_1_1_5_1_1; + A[132] = A[314] + 0.507936507936544*G0_0_0_0_0_0_0_0_0 + 0.507936507936544*G0_0_0_0_0_0_0_0_1 - 0.507936507936544*G0_0_0_0_0_0_1_0_0 - 0.507936507936544*G0_0_0_0_0_0_2_0_1 + 0.507936507936544*G0_0_0_0_0_0_3_1_0 + 0.507936507936544*G0_0_0_0_0_0_3_1_1 - 0.507936507936544*G0_0_0_0_0_0_4_1_0 - 0.507936507936544*G0_0_0_0_0_0_5_1_1 + 0.507936507936544*G0_0_0_0_0_1_0_0_0 + 0.507936507936544*G0_0_0_0_0_1_0_0_1 - 0.507936507936544*G0_0_0_0_0_1_1_0_0 - 0.507936507936544*G0_0_0_0_0_1_2_0_1 + 0.507936507936544*G0_0_0_0_0_1_3_1_0 + 0.507936507936544*G0_0_0_0_0_1_3_1_1 - 0.507936507936544*G0_0_0_0_0_1_4_1_0 - 0.507936507936544*G0_0_0_0_0_1_5_1_1 - 0.507936507936544*G0_0_0_1_0_0_0_0_0 - 0.507936507936544*G0_0_0_1_0_0_0_0_1 + 0.507936507936544*G0_0_0_1_0_0_1_0_0 + 0.507936507936544*G0_0_0_1_0_0_2_0_1 - 0.507936507936544*G0_0_0_1_0_0_3_1_0 - 0.507936507936544*G0_0_0_1_0_0_3_1_1 + 0.507936507936544*G0_0_0_1_0_0_4_1_0 + 0.507936507936544*G0_0_0_1_0_0_5_1_1 - 0.507936507936544*G0_0_0_2_0_1_0_0_0 - 0.507936507936544*G0_0_0_2_0_1_0_0_1 + 0.507936507936544*G0_0_0_2_0_1_1_0_0 + 0.507936507936544*G0_0_0_2_0_1_2_0_1 - 0.507936507936544*G0_0_0_2_0_1_3_1_0 - 0.507936507936544*G0_0_0_2_0_1_3_1_1 + 0.507936507936544*G0_0_0_2_0_1_4_1_0 + 0.507936507936544*G0_0_0_2_0_1_5_1_1 + 0.507936507936544*G0_0_0_3_1_0_0_0_0 + 0.507936507936544*G0_0_0_3_1_0_0_0_1 - 0.507936507936544*G0_0_0_3_1_0_1_0_0 - 0.507936507936544*G0_0_0_3_1_0_2_0_1 + 0.507936507936544*G0_0_0_3_1_0_3_1_0 + 0.507936507936544*G0_0_0_3_1_0_3_1_1 - 0.507936507936544*G0_0_0_3_1_0_4_1_0 - 0.507936507936544*G0_0_0_3_1_0_5_1_1 + 0.507936507936544*G0_0_0_3_1_1_0_0_0 + 0.507936507936544*G0_0_0_3_1_1_0_0_1 - 0.507936507936544*G0_0_0_3_1_1_1_0_0 - 0.507936507936544*G0_0_0_3_1_1_2_0_1 + 0.507936507936544*G0_0_0_3_1_1_3_1_0 + 0.507936507936544*G0_0_0_3_1_1_3_1_1 - 0.507936507936544*G0_0_0_3_1_1_4_1_0 - 0.507936507936544*G0_0_0_3_1_1_5_1_1 - 0.507936507936544*G0_0_0_4_1_0_0_0_0 - 0.507936507936544*G0_0_0_4_1_0_0_0_1 + 0.507936507936544*G0_0_0_4_1_0_1_0_0 + 0.507936507936544*G0_0_0_4_1_0_2_0_1 - 0.507936507936544*G0_0_0_4_1_0_3_1_0 - 0.507936507936544*G0_0_0_4_1_0_3_1_1 + 0.507936507936544*G0_0_0_4_1_0_4_1_0 + 0.507936507936544*G0_0_0_4_1_0_5_1_1 - 0.507936507936544*G0_0_0_5_1_1_0_0_0 - 0.507936507936544*G0_0_0_5_1_1_0_0_1 + 0.507936507936544*G0_0_0_5_1_1_1_0_0 + 0.507936507936544*G0_0_0_5_1_1_2_0_1 - 0.507936507936544*G0_0_0_5_1_1_3_1_0 - 0.507936507936544*G0_0_0_5_1_1_3_1_1 + 0.507936507936544*G0_0_0_5_1_1_4_1_0 + 0.507936507936544*G0_0_0_5_1_1_5_1_1 + 0.507936507936544*G0_0_1_0_0_0_0_0_0 + 0.507936507936544*G0_0_1_0_0_0_0_0_1 - 0.507936507936544*G0_0_1_0_0_0_1_0_0 - 0.507936507936544*G0_0_1_0_0_0_2_0_1 + 0.507936507936544*G0_0_1_0_0_0_3_1_0 + 0.507936507936544*G0_0_1_0_0_0_3_1_1 - 0.507936507936544*G0_0_1_0_0_0_4_1_0 - 0.507936507936544*G0_0_1_0_0_0_5_1_1 + 0.507936507936544*G0_0_1_0_0_1_0_0_0 + 0.507936507936544*G0_0_1_0_0_1_0_0_1 - 0.507936507936544*G0_0_1_0_0_1_1_0_0 - 0.507936507936544*G0_0_1_0_0_1_2_0_1 + 0.507936507936544*G0_0_1_0_0_1_3_1_0 + 0.507936507936544*G0_0_1_0_0_1_3_1_1 - 0.507936507936544*G0_0_1_0_0_1_4_1_0 - 0.507936507936544*G0_0_1_0_0_1_5_1_1 - 0.507936507936544*G0_0_1_1_0_0_0_0_0 - 0.507936507936544*G0_0_1_1_0_0_0_0_1 + 0.507936507936544*G0_0_1_1_0_0_1_0_0 + 0.507936507936544*G0_0_1_1_0_0_2_0_1 - 0.507936507936544*G0_0_1_1_0_0_3_1_0 - 0.507936507936544*G0_0_1_1_0_0_3_1_1 + 0.507936507936544*G0_0_1_1_0_0_4_1_0 + 0.507936507936544*G0_0_1_1_0_0_5_1_1 - 0.507936507936544*G0_0_1_2_0_1_0_0_0 - 0.507936507936544*G0_0_1_2_0_1_0_0_1 + 0.507936507936544*G0_0_1_2_0_1_1_0_0 + 0.507936507936544*G0_0_1_2_0_1_2_0_1 - 0.507936507936544*G0_0_1_2_0_1_3_1_0 - 0.507936507936544*G0_0_1_2_0_1_3_1_1 + 0.507936507936544*G0_0_1_2_0_1_4_1_0 + 0.507936507936544*G0_0_1_2_0_1_5_1_1 + 0.507936507936544*G0_0_1_3_1_0_0_0_0 + 0.507936507936544*G0_0_1_3_1_0_0_0_1 - 0.507936507936544*G0_0_1_3_1_0_1_0_0 - 0.507936507936544*G0_0_1_3_1_0_2_0_1 + 0.507936507936544*G0_0_1_3_1_0_3_1_0 + 0.507936507936544*G0_0_1_3_1_0_3_1_1 - 0.507936507936544*G0_0_1_3_1_0_4_1_0 - 0.507936507936544*G0_0_1_3_1_0_5_1_1 + 0.507936507936544*G0_0_1_3_1_1_0_0_0 + 0.507936507936544*G0_0_1_3_1_1_0_0_1 - 0.507936507936544*G0_0_1_3_1_1_1_0_0 - 0.507936507936544*G0_0_1_3_1_1_2_0_1 + 0.507936507936544*G0_0_1_3_1_1_3_1_0 + 0.507936507936544*G0_0_1_3_1_1_3_1_1 - 0.507936507936544*G0_0_1_3_1_1_4_1_0 - 0.507936507936544*G0_0_1_3_1_1_5_1_1 - 0.507936507936544*G0_0_1_4_1_0_0_0_0 - 0.507936507936544*G0_0_1_4_1_0_0_0_1 + 0.507936507936544*G0_0_1_4_1_0_1_0_0 + 0.507936507936544*G0_0_1_4_1_0_2_0_1 - 0.507936507936544*G0_0_1_4_1_0_3_1_0 - 0.507936507936544*G0_0_1_4_1_0_3_1_1 + 0.507936507936544*G0_0_1_4_1_0_4_1_0 + 0.507936507936544*G0_0_1_4_1_0_5_1_1 - 0.507936507936544*G0_0_1_5_1_1_0_0_0 - 0.507936507936544*G0_0_1_5_1_1_0_0_1 + 0.507936507936544*G0_0_1_5_1_1_1_0_0 + 0.507936507936544*G0_0_1_5_1_1_2_0_1 - 0.507936507936544*G0_0_1_5_1_1_3_1_0 - 0.507936507936544*G0_0_1_5_1_1_3_1_1 + 0.507936507936544*G0_0_1_5_1_1_4_1_0 + 0.507936507936544*G0_0_1_5_1_1_5_1_1 + 0.50793650793654*G0_1_0_0_0_0_0_0_0 + 0.50793650793654*G0_1_0_0_0_0_0_0_1 - 0.50793650793654*G0_1_0_0_0_0_1_0_0 - 0.50793650793654*G0_1_0_0_0_0_2_0_1 + 0.50793650793654*G0_1_0_0_0_0_3_1_0 + 0.50793650793654*G0_1_0_0_0_0_3_1_1 - 0.50793650793654*G0_1_0_0_0_0_4_1_0 - 0.50793650793654*G0_1_0_0_0_0_5_1_1 + 0.50793650793654*G0_1_0_0_0_1_0_0_0 + 0.50793650793654*G0_1_0_0_0_1_0_0_1 - 0.50793650793654*G0_1_0_0_0_1_1_0_0 - 0.50793650793654*G0_1_0_0_0_1_2_0_1 + 0.50793650793654*G0_1_0_0_0_1_3_1_0 + 0.50793650793654*G0_1_0_0_0_1_3_1_1 - 0.50793650793654*G0_1_0_0_0_1_4_1_0 - 0.50793650793654*G0_1_0_0_0_1_5_1_1 - 0.50793650793654*G0_1_0_1_0_0_0_0_0 - 0.50793650793654*G0_1_0_1_0_0_0_0_1 + 0.50793650793654*G0_1_0_1_0_0_1_0_0 + 0.50793650793654*G0_1_0_1_0_0_2_0_1 - 0.50793650793654*G0_1_0_1_0_0_3_1_0 - 0.50793650793654*G0_1_0_1_0_0_3_1_1 + 0.50793650793654*G0_1_0_1_0_0_4_1_0 + 0.50793650793654*G0_1_0_1_0_0_5_1_1 - 0.50793650793654*G0_1_0_2_0_1_0_0_0 - 0.50793650793654*G0_1_0_2_0_1_0_0_1 + 0.50793650793654*G0_1_0_2_0_1_1_0_0 + 0.50793650793654*G0_1_0_2_0_1_2_0_1 - 0.50793650793654*G0_1_0_2_0_1_3_1_0 - 0.50793650793654*G0_1_0_2_0_1_3_1_1 + 0.50793650793654*G0_1_0_2_0_1_4_1_0 + 0.50793650793654*G0_1_0_2_0_1_5_1_1 + 0.50793650793654*G0_1_0_3_1_0_0_0_0 + 0.50793650793654*G0_1_0_3_1_0_0_0_1 - 0.50793650793654*G0_1_0_3_1_0_1_0_0 - 0.50793650793654*G0_1_0_3_1_0_2_0_1 + 0.50793650793654*G0_1_0_3_1_0_3_1_0 + 0.50793650793654*G0_1_0_3_1_0_3_1_1 - 0.50793650793654*G0_1_0_3_1_0_4_1_0 - 0.50793650793654*G0_1_0_3_1_0_5_1_1 + 0.50793650793654*G0_1_0_3_1_1_0_0_0 + 0.50793650793654*G0_1_0_3_1_1_0_0_1 - 0.50793650793654*G0_1_0_3_1_1_1_0_0 - 0.50793650793654*G0_1_0_3_1_1_2_0_1 + 0.50793650793654*G0_1_0_3_1_1_3_1_0 + 0.50793650793654*G0_1_0_3_1_1_3_1_1 - 0.50793650793654*G0_1_0_3_1_1_4_1_0 - 0.50793650793654*G0_1_0_3_1_1_5_1_1 - 0.50793650793654*G0_1_0_4_1_0_0_0_0 - 0.50793650793654*G0_1_0_4_1_0_0_0_1 + 0.50793650793654*G0_1_0_4_1_0_1_0_0 + 0.50793650793654*G0_1_0_4_1_0_2_0_1 - 0.50793650793654*G0_1_0_4_1_0_3_1_0 - 0.50793650793654*G0_1_0_4_1_0_3_1_1 + 0.50793650793654*G0_1_0_4_1_0_4_1_0 + 0.50793650793654*G0_1_0_4_1_0_5_1_1 - 0.50793650793654*G0_1_0_5_1_1_0_0_0 - 0.50793650793654*G0_1_0_5_1_1_0_0_1 + 0.50793650793654*G0_1_0_5_1_1_1_0_0 + 0.50793650793654*G0_1_0_5_1_1_2_0_1 - 0.50793650793654*G0_1_0_5_1_1_3_1_0 - 0.50793650793654*G0_1_0_5_1_1_3_1_1 + 0.50793650793654*G0_1_0_5_1_1_4_1_0 + 0.50793650793654*G0_1_0_5_1_1_5_1_1; + A[597] = A[132]; + A[312] = A[314] + 1.62539682539685*G0_0_1_0_0_0_0_0_0 + 1.62539682539685*G0_0_1_0_0_0_0_0_1 - 1.62539682539685*G0_0_1_0_0_0_1_0_0 - 1.62539682539685*G0_0_1_0_0_0_2_0_1 + 1.62539682539685*G0_0_1_0_0_0_3_1_0 + 1.62539682539685*G0_0_1_0_0_0_3_1_1 - 1.62539682539685*G0_0_1_0_0_0_4_1_0 - 1.62539682539685*G0_0_1_0_0_0_5_1_1 + 1.62539682539685*G0_0_1_0_0_1_0_0_0 + 1.62539682539685*G0_0_1_0_0_1_0_0_1 - 1.62539682539685*G0_0_1_0_0_1_1_0_0 - 1.62539682539685*G0_0_1_0_0_1_2_0_1 + 1.62539682539685*G0_0_1_0_0_1_3_1_0 + 1.62539682539685*G0_0_1_0_0_1_3_1_1 - 1.62539682539685*G0_0_1_0_0_1_4_1_0 - 1.62539682539685*G0_0_1_0_0_1_5_1_1 - 1.62539682539685*G0_0_1_1_0_0_0_0_0 - 1.62539682539685*G0_0_1_1_0_0_0_0_1 + 1.62539682539685*G0_0_1_1_0_0_1_0_0 + 1.62539682539685*G0_0_1_1_0_0_2_0_1 - 1.62539682539685*G0_0_1_1_0_0_3_1_0 - 1.62539682539685*G0_0_1_1_0_0_3_1_1 + 1.62539682539685*G0_0_1_1_0_0_4_1_0 + 1.62539682539685*G0_0_1_1_0_0_5_1_1 - 1.62539682539685*G0_0_1_2_0_1_0_0_0 - 1.62539682539685*G0_0_1_2_0_1_0_0_1 + 1.62539682539685*G0_0_1_2_0_1_1_0_0 + 1.62539682539685*G0_0_1_2_0_1_2_0_1 - 1.62539682539685*G0_0_1_2_0_1_3_1_0 - 1.62539682539685*G0_0_1_2_0_1_3_1_1 + 1.62539682539685*G0_0_1_2_0_1_4_1_0 + 1.62539682539685*G0_0_1_2_0_1_5_1_1 + 1.62539682539685*G0_0_1_3_1_0_0_0_0 + 1.62539682539685*G0_0_1_3_1_0_0_0_1 - 1.62539682539685*G0_0_1_3_1_0_1_0_0 - 1.62539682539685*G0_0_1_3_1_0_2_0_1 + 1.62539682539685*G0_0_1_3_1_0_3_1_0 + 1.62539682539685*G0_0_1_3_1_0_3_1_1 - 1.62539682539685*G0_0_1_3_1_0_4_1_0 - 1.62539682539685*G0_0_1_3_1_0_5_1_1 + 1.62539682539685*G0_0_1_3_1_1_0_0_0 + 1.62539682539685*G0_0_1_3_1_1_0_0_1 - 1.62539682539685*G0_0_1_3_1_1_1_0_0 - 1.62539682539685*G0_0_1_3_1_1_2_0_1 + 1.62539682539685*G0_0_1_3_1_1_3_1_0 + 1.62539682539685*G0_0_1_3_1_1_3_1_1 - 1.62539682539685*G0_0_1_3_1_1_4_1_0 - 1.62539682539685*G0_0_1_3_1_1_5_1_1 - 1.62539682539685*G0_0_1_4_1_0_0_0_0 - 1.62539682539685*G0_0_1_4_1_0_0_0_1 + 1.62539682539685*G0_0_1_4_1_0_1_0_0 + 1.62539682539685*G0_0_1_4_1_0_2_0_1 - 1.62539682539685*G0_0_1_4_1_0_3_1_0 - 1.62539682539685*G0_0_1_4_1_0_3_1_1 + 1.62539682539685*G0_0_1_4_1_0_4_1_0 + 1.62539682539685*G0_0_1_4_1_0_5_1_1 - 1.62539682539685*G0_0_1_5_1_1_0_0_0 - 1.62539682539685*G0_0_1_5_1_1_0_0_1 + 1.62539682539685*G0_0_1_5_1_1_1_0_0 + 1.62539682539685*G0_0_1_5_1_1_2_0_1 - 1.62539682539685*G0_0_1_5_1_1_3_1_0 - 1.62539682539685*G0_0_1_5_1_1_3_1_1 + 1.62539682539685*G0_0_1_5_1_1_4_1_0 + 1.62539682539685*G0_0_1_5_1_1_5_1_1 + 1.62539682539684*G0_1_0_0_0_0_0_0_0 + 1.62539682539684*G0_1_0_0_0_0_0_0_1 - 1.62539682539684*G0_1_0_0_0_0_1_0_0 - 1.62539682539684*G0_1_0_0_0_0_2_0_1 + 1.62539682539684*G0_1_0_0_0_0_3_1_0 + 1.62539682539684*G0_1_0_0_0_0_3_1_1 - 1.62539682539684*G0_1_0_0_0_0_4_1_0 - 1.62539682539684*G0_1_0_0_0_0_5_1_1 + 1.62539682539684*G0_1_0_0_0_1_0_0_0 + 1.62539682539684*G0_1_0_0_0_1_0_0_1 - 1.62539682539684*G0_1_0_0_0_1_1_0_0 - 1.62539682539684*G0_1_0_0_0_1_2_0_1 + 1.62539682539684*G0_1_0_0_0_1_3_1_0 + 1.62539682539684*G0_1_0_0_0_1_3_1_1 - 1.62539682539684*G0_1_0_0_0_1_4_1_0 - 1.62539682539684*G0_1_0_0_0_1_5_1_1 - 1.62539682539684*G0_1_0_1_0_0_0_0_0 - 1.62539682539684*G0_1_0_1_0_0_0_0_1 + 1.62539682539684*G0_1_0_1_0_0_1_0_0 + 1.62539682539684*G0_1_0_1_0_0_2_0_1 - 1.62539682539684*G0_1_0_1_0_0_3_1_0 - 1.62539682539684*G0_1_0_1_0_0_3_1_1 + 1.62539682539684*G0_1_0_1_0_0_4_1_0 + 1.62539682539684*G0_1_0_1_0_0_5_1_1 - 1.62539682539684*G0_1_0_2_0_1_0_0_0 - 1.62539682539684*G0_1_0_2_0_1_0_0_1 + 1.62539682539684*G0_1_0_2_0_1_1_0_0 + 1.62539682539684*G0_1_0_2_0_1_2_0_1 - 1.62539682539684*G0_1_0_2_0_1_3_1_0 - 1.62539682539684*G0_1_0_2_0_1_3_1_1 + 1.62539682539684*G0_1_0_2_0_1_4_1_0 + 1.62539682539684*G0_1_0_2_0_1_5_1_1 + 1.62539682539684*G0_1_0_3_1_0_0_0_0 + 1.62539682539684*G0_1_0_3_1_0_0_0_1 - 1.62539682539684*G0_1_0_3_1_0_1_0_0 - 1.62539682539684*G0_1_0_3_1_0_2_0_1 + 1.62539682539684*G0_1_0_3_1_0_3_1_0 + 1.62539682539684*G0_1_0_3_1_0_3_1_1 - 1.62539682539684*G0_1_0_3_1_0_4_1_0 - 1.62539682539684*G0_1_0_3_1_0_5_1_1 + 1.62539682539684*G0_1_0_3_1_1_0_0_0 + 1.62539682539684*G0_1_0_3_1_1_0_0_1 - 1.62539682539684*G0_1_0_3_1_1_1_0_0 - 1.62539682539684*G0_1_0_3_1_1_2_0_1 + 1.62539682539684*G0_1_0_3_1_1_3_1_0 + 1.62539682539684*G0_1_0_3_1_1_3_1_1 - 1.62539682539684*G0_1_0_3_1_1_4_1_0 - 1.62539682539684*G0_1_0_3_1_1_5_1_1 - 1.62539682539684*G0_1_0_4_1_0_0_0_0 - 1.62539682539684*G0_1_0_4_1_0_0_0_1 + 1.62539682539684*G0_1_0_4_1_0_1_0_0 + 1.62539682539684*G0_1_0_4_1_0_2_0_1 - 1.62539682539684*G0_1_0_4_1_0_3_1_0 - 1.62539682539684*G0_1_0_4_1_0_3_1_1 + 1.62539682539684*G0_1_0_4_1_0_4_1_0 + 1.62539682539684*G0_1_0_4_1_0_5_1_1 - 1.62539682539684*G0_1_0_5_1_1_0_0_0 - 1.62539682539684*G0_1_0_5_1_1_0_0_1 + 1.62539682539684*G0_1_0_5_1_1_1_0_0 + 1.62539682539684*G0_1_0_5_1_1_2_0_1 - 1.62539682539684*G0_1_0_5_1_1_3_1_0 - 1.62539682539684*G0_1_0_5_1_1_3_1_1 + 1.62539682539684*G0_1_0_5_1_1_4_1_0 + 1.62539682539684*G0_1_0_5_1_1_5_1_1; + A[367] = A[312] + 0.507936507936511*G0_0_0_0_0_0_0_0_0 + 0.507936507936511*G0_0_0_0_0_0_0_0_1 - 0.507936507936511*G0_0_0_0_0_0_1_0_0 - 0.507936507936511*G0_0_0_0_0_0_2_0_1 + 0.507936507936511*G0_0_0_0_0_0_3_1_0 + 0.507936507936511*G0_0_0_0_0_0_3_1_1 - 0.507936507936511*G0_0_0_0_0_0_4_1_0 - 0.507936507936511*G0_0_0_0_0_0_5_1_1 + 0.507936507936511*G0_0_0_0_0_1_0_0_0 + 0.507936507936511*G0_0_0_0_0_1_0_0_1 - 0.507936507936511*G0_0_0_0_0_1_1_0_0 - 0.507936507936511*G0_0_0_0_0_1_2_0_1 + 0.507936507936511*G0_0_0_0_0_1_3_1_0 + 0.507936507936511*G0_0_0_0_0_1_3_1_1 - 0.507936507936511*G0_0_0_0_0_1_4_1_0 - 0.507936507936511*G0_0_0_0_0_1_5_1_1 - 0.507936507936511*G0_0_0_1_0_0_0_0_0 - 0.507936507936511*G0_0_0_1_0_0_0_0_1 + 0.507936507936511*G0_0_0_1_0_0_1_0_0 + 0.507936507936511*G0_0_0_1_0_0_2_0_1 - 0.507936507936511*G0_0_0_1_0_0_3_1_0 - 0.507936507936511*G0_0_0_1_0_0_3_1_1 + 0.507936507936511*G0_0_0_1_0_0_4_1_0 + 0.507936507936511*G0_0_0_1_0_0_5_1_1 - 0.507936507936511*G0_0_0_2_0_1_0_0_0 - 0.507936507936511*G0_0_0_2_0_1_0_0_1 + 0.507936507936511*G0_0_0_2_0_1_1_0_0 + 0.507936507936511*G0_0_0_2_0_1_2_0_1 - 0.507936507936511*G0_0_0_2_0_1_3_1_0 - 0.507936507936511*G0_0_0_2_0_1_3_1_1 + 0.507936507936511*G0_0_0_2_0_1_4_1_0 + 0.507936507936511*G0_0_0_2_0_1_5_1_1 + 0.507936507936511*G0_0_0_3_1_0_0_0_0 + 0.507936507936511*G0_0_0_3_1_0_0_0_1 - 0.507936507936511*G0_0_0_3_1_0_1_0_0 - 0.507936507936511*G0_0_0_3_1_0_2_0_1 + 0.507936507936511*G0_0_0_3_1_0_3_1_0 + 0.507936507936511*G0_0_0_3_1_0_3_1_1 - 0.507936507936511*G0_0_0_3_1_0_4_1_0 - 0.507936507936511*G0_0_0_3_1_0_5_1_1 + 0.507936507936511*G0_0_0_3_1_1_0_0_0 + 0.507936507936511*G0_0_0_3_1_1_0_0_1 - 0.507936507936511*G0_0_0_3_1_1_1_0_0 - 0.507936507936511*G0_0_0_3_1_1_2_0_1 + 0.507936507936511*G0_0_0_3_1_1_3_1_0 + 0.507936507936511*G0_0_0_3_1_1_3_1_1 - 0.507936507936511*G0_0_0_3_1_1_4_1_0 - 0.507936507936511*G0_0_0_3_1_1_5_1_1 - 0.507936507936511*G0_0_0_4_1_0_0_0_0 - 0.507936507936511*G0_0_0_4_1_0_0_0_1 + 0.507936507936511*G0_0_0_4_1_0_1_0_0 + 0.507936507936511*G0_0_0_4_1_0_2_0_1 - 0.507936507936511*G0_0_0_4_1_0_3_1_0 - 0.507936507936511*G0_0_0_4_1_0_3_1_1 + 0.507936507936511*G0_0_0_4_1_0_4_1_0 + 0.507936507936511*G0_0_0_4_1_0_5_1_1 - 0.507936507936511*G0_0_0_5_1_1_0_0_0 - 0.507936507936511*G0_0_0_5_1_1_0_0_1 + 0.507936507936511*G0_0_0_5_1_1_1_0_0 + 0.507936507936511*G0_0_0_5_1_1_2_0_1 - 0.507936507936511*G0_0_0_5_1_1_3_1_0 - 0.507936507936511*G0_0_0_5_1_1_3_1_1 + 0.507936507936511*G0_0_0_5_1_1_4_1_0 + 0.507936507936511*G0_0_0_5_1_1_5_1_1 - 0.507936507936506*G0_1_1_0_0_0_0_0_0 - 0.507936507936506*G0_1_1_0_0_0_0_0_1 + 0.507936507936506*G0_1_1_0_0_0_1_0_0 + 0.507936507936506*G0_1_1_0_0_0_2_0_1 - 0.507936507936506*G0_1_1_0_0_0_3_1_0 - 0.507936507936506*G0_1_1_0_0_0_3_1_1 + 0.507936507936506*G0_1_1_0_0_0_4_1_0 + 0.507936507936506*G0_1_1_0_0_0_5_1_1 - 0.507936507936506*G0_1_1_0_0_1_0_0_0 - 0.507936507936506*G0_1_1_0_0_1_0_0_1 + 0.507936507936506*G0_1_1_0_0_1_1_0_0 + 0.507936507936506*G0_1_1_0_0_1_2_0_1 - 0.507936507936506*G0_1_1_0_0_1_3_1_0 - 0.507936507936506*G0_1_1_0_0_1_3_1_1 + 0.507936507936506*G0_1_1_0_0_1_4_1_0 + 0.507936507936506*G0_1_1_0_0_1_5_1_1 + 0.507936507936506*G0_1_1_1_0_0_0_0_0 + 0.507936507936506*G0_1_1_1_0_0_0_0_1 - 0.507936507936506*G0_1_1_1_0_0_1_0_0 - 0.507936507936506*G0_1_1_1_0_0_2_0_1 + 0.507936507936506*G0_1_1_1_0_0_3_1_0 + 0.507936507936506*G0_1_1_1_0_0_3_1_1 - 0.507936507936506*G0_1_1_1_0_0_4_1_0 - 0.507936507936506*G0_1_1_1_0_0_5_1_1 + 0.507936507936506*G0_1_1_2_0_1_0_0_0 + 0.507936507936506*G0_1_1_2_0_1_0_0_1 - 0.507936507936506*G0_1_1_2_0_1_1_0_0 - 0.507936507936506*G0_1_1_2_0_1_2_0_1 + 0.507936507936506*G0_1_1_2_0_1_3_1_0 + 0.507936507936506*G0_1_1_2_0_1_3_1_1 - 0.507936507936506*G0_1_1_2_0_1_4_1_0 - 0.507936507936506*G0_1_1_2_0_1_5_1_1 - 0.507936507936506*G0_1_1_3_1_0_0_0_0 - 0.507936507936506*G0_1_1_3_1_0_0_0_1 + 0.507936507936506*G0_1_1_3_1_0_1_0_0 + 0.507936507936506*G0_1_1_3_1_0_2_0_1 - 0.507936507936506*G0_1_1_3_1_0_3_1_0 - 0.507936507936506*G0_1_1_3_1_0_3_1_1 + 0.507936507936506*G0_1_1_3_1_0_4_1_0 + 0.507936507936506*G0_1_1_3_1_0_5_1_1 - 0.507936507936506*G0_1_1_3_1_1_0_0_0 - 0.507936507936506*G0_1_1_3_1_1_0_0_1 + 0.507936507936506*G0_1_1_3_1_1_1_0_0 + 0.507936507936506*G0_1_1_3_1_1_2_0_1 - 0.507936507936506*G0_1_1_3_1_1_3_1_0 - 0.507936507936506*G0_1_1_3_1_1_3_1_1 + 0.507936507936506*G0_1_1_3_1_1_4_1_0 + 0.507936507936506*G0_1_1_3_1_1_5_1_1 + 0.507936507936506*G0_1_1_4_1_0_0_0_0 + 0.507936507936506*G0_1_1_4_1_0_0_0_1 - 0.507936507936506*G0_1_1_4_1_0_1_0_0 - 0.507936507936506*G0_1_1_4_1_0_2_0_1 + 0.507936507936506*G0_1_1_4_1_0_3_1_0 + 0.507936507936506*G0_1_1_4_1_0_3_1_1 - 0.507936507936506*G0_1_1_4_1_0_4_1_0 - 0.507936507936506*G0_1_1_4_1_0_5_1_1 + 0.507936507936506*G0_1_1_5_1_1_0_0_0 + 0.507936507936506*G0_1_1_5_1_1_0_0_1 - 0.507936507936506*G0_1_1_5_1_1_1_0_0 - 0.507936507936506*G0_1_1_5_1_1_2_0_1 + 0.507936507936506*G0_1_1_5_1_1_3_1_0 + 0.507936507936506*G0_1_1_5_1_1_3_1_1 - 0.507936507936506*G0_1_1_5_1_1_4_1_0 - 0.507936507936506*G0_1_1_5_1_1_5_1_1; + A[370] = A[312]; + A[134] = A[314] - 2.74285714285719*G0_0_0_0_0_0_0_0_0 - 2.74285714285719*G0_0_0_0_0_0_0_0_1 + 2.74285714285719*G0_0_0_0_0_0_1_0_0 + 2.74285714285719*G0_0_0_0_0_0_2_0_1 - 2.74285714285719*G0_0_0_0_0_0_3_1_0 - 2.74285714285719*G0_0_0_0_0_0_3_1_1 + 2.74285714285719*G0_0_0_0_0_0_4_1_0 + 2.74285714285719*G0_0_0_0_0_0_5_1_1 - 2.74285714285719*G0_0_0_0_0_1_0_0_0 - 2.74285714285719*G0_0_0_0_0_1_0_0_1 + 2.74285714285719*G0_0_0_0_0_1_1_0_0 + 2.74285714285719*G0_0_0_0_0_1_2_0_1 - 2.74285714285719*G0_0_0_0_0_1_3_1_0 - 2.74285714285719*G0_0_0_0_0_1_3_1_1 + 2.74285714285719*G0_0_0_0_0_1_4_1_0 + 2.74285714285719*G0_0_0_0_0_1_5_1_1 + 2.74285714285719*G0_0_0_1_0_0_0_0_0 + 2.74285714285719*G0_0_0_1_0_0_0_0_1 - 2.74285714285719*G0_0_0_1_0_0_1_0_0 - 2.74285714285719*G0_0_0_1_0_0_2_0_1 + 2.74285714285719*G0_0_0_1_0_0_3_1_0 + 2.74285714285719*G0_0_0_1_0_0_3_1_1 - 2.74285714285719*G0_0_0_1_0_0_4_1_0 - 2.74285714285719*G0_0_0_1_0_0_5_1_1 + 2.74285714285719*G0_0_0_2_0_1_0_0_0 + 2.74285714285719*G0_0_0_2_0_1_0_0_1 - 2.74285714285719*G0_0_0_2_0_1_1_0_0 - 2.74285714285719*G0_0_0_2_0_1_2_0_1 + 2.74285714285719*G0_0_0_2_0_1_3_1_0 + 2.74285714285719*G0_0_0_2_0_1_3_1_1 - 2.74285714285719*G0_0_0_2_0_1_4_1_0 - 2.74285714285719*G0_0_0_2_0_1_5_1_1 - 2.74285714285719*G0_0_0_3_1_0_0_0_0 - 2.74285714285719*G0_0_0_3_1_0_0_0_1 + 2.74285714285719*G0_0_0_3_1_0_1_0_0 + 2.74285714285719*G0_0_0_3_1_0_2_0_1 - 2.74285714285719*G0_0_0_3_1_0_3_1_0 - 2.74285714285719*G0_0_0_3_1_0_3_1_1 + 2.74285714285719*G0_0_0_3_1_0_4_1_0 + 2.74285714285719*G0_0_0_3_1_0_5_1_1 - 2.74285714285719*G0_0_0_3_1_1_0_0_0 - 2.74285714285719*G0_0_0_3_1_1_0_0_1 + 2.74285714285719*G0_0_0_3_1_1_1_0_0 + 2.74285714285719*G0_0_0_3_1_1_2_0_1 - 2.74285714285719*G0_0_0_3_1_1_3_1_0 - 2.74285714285719*G0_0_0_3_1_1_3_1_1 + 2.74285714285719*G0_0_0_3_1_1_4_1_0 + 2.74285714285719*G0_0_0_3_1_1_5_1_1 + 2.74285714285719*G0_0_0_4_1_0_0_0_0 + 2.74285714285719*G0_0_0_4_1_0_0_0_1 - 2.74285714285719*G0_0_0_4_1_0_1_0_0 - 2.74285714285719*G0_0_0_4_1_0_2_0_1 + 2.74285714285719*G0_0_0_4_1_0_3_1_0 + 2.74285714285719*G0_0_0_4_1_0_3_1_1 - 2.74285714285719*G0_0_0_4_1_0_4_1_0 - 2.74285714285719*G0_0_0_4_1_0_5_1_1 + 2.74285714285719*G0_0_0_5_1_1_0_0_0 + 2.74285714285719*G0_0_0_5_1_1_0_0_1 - 2.74285714285719*G0_0_0_5_1_1_1_0_0 - 2.74285714285719*G0_0_0_5_1_1_2_0_1 + 2.74285714285719*G0_0_0_5_1_1_3_1_0 + 2.74285714285719*G0_0_0_5_1_1_3_1_1 - 2.74285714285719*G0_0_0_5_1_1_4_1_0 - 2.74285714285719*G0_0_0_5_1_1_5_1_1 - 1.11746031746035*G0_0_1_0_0_0_0_0_0 - 1.11746031746035*G0_0_1_0_0_0_0_0_1 + 1.11746031746035*G0_0_1_0_0_0_1_0_0 + 1.11746031746035*G0_0_1_0_0_0_2_0_1 - 1.11746031746035*G0_0_1_0_0_0_3_1_0 - 1.11746031746035*G0_0_1_0_0_0_3_1_1 + 1.11746031746035*G0_0_1_0_0_0_4_1_0 + 1.11746031746035*G0_0_1_0_0_0_5_1_1 - 1.11746031746035*G0_0_1_0_0_1_0_0_0 - 1.11746031746035*G0_0_1_0_0_1_0_0_1 + 1.11746031746035*G0_0_1_0_0_1_1_0_0 + 1.11746031746035*G0_0_1_0_0_1_2_0_1 - 1.11746031746035*G0_0_1_0_0_1_3_1_0 - 1.11746031746035*G0_0_1_0_0_1_3_1_1 + 1.11746031746035*G0_0_1_0_0_1_4_1_0 + 1.11746031746035*G0_0_1_0_0_1_5_1_1 + 1.11746031746035*G0_0_1_1_0_0_0_0_0 + 1.11746031746035*G0_0_1_1_0_0_0_0_1 - 1.11746031746035*G0_0_1_1_0_0_1_0_0 - 1.11746031746035*G0_0_1_1_0_0_2_0_1 + 1.11746031746035*G0_0_1_1_0_0_3_1_0 + 1.11746031746035*G0_0_1_1_0_0_3_1_1 - 1.11746031746035*G0_0_1_1_0_0_4_1_0 - 1.11746031746035*G0_0_1_1_0_0_5_1_1 + 1.11746031746035*G0_0_1_2_0_1_0_0_0 + 1.11746031746035*G0_0_1_2_0_1_0_0_1 - 1.11746031746035*G0_0_1_2_0_1_1_0_0 - 1.11746031746035*G0_0_1_2_0_1_2_0_1 + 1.11746031746035*G0_0_1_2_0_1_3_1_0 + 1.11746031746035*G0_0_1_2_0_1_3_1_1 - 1.11746031746035*G0_0_1_2_0_1_4_1_0 - 1.11746031746035*G0_0_1_2_0_1_5_1_1 - 1.11746031746035*G0_0_1_3_1_0_0_0_0 - 1.11746031746035*G0_0_1_3_1_0_0_0_1 + 1.11746031746035*G0_0_1_3_1_0_1_0_0 + 1.11746031746035*G0_0_1_3_1_0_2_0_1 - 1.11746031746035*G0_0_1_3_1_0_3_1_0 - 1.11746031746035*G0_0_1_3_1_0_3_1_1 + 1.11746031746035*G0_0_1_3_1_0_4_1_0 + 1.11746031746035*G0_0_1_3_1_0_5_1_1 - 1.11746031746035*G0_0_1_3_1_1_0_0_0 - 1.11746031746035*G0_0_1_3_1_1_0_0_1 + 1.11746031746035*G0_0_1_3_1_1_1_0_0 + 1.11746031746035*G0_0_1_3_1_1_2_0_1 - 1.11746031746035*G0_0_1_3_1_1_3_1_0 - 1.11746031746035*G0_0_1_3_1_1_3_1_1 + 1.11746031746035*G0_0_1_3_1_1_4_1_0 + 1.11746031746035*G0_0_1_3_1_1_5_1_1 + 1.11746031746035*G0_0_1_4_1_0_0_0_0 + 1.11746031746035*G0_0_1_4_1_0_0_0_1 - 1.11746031746035*G0_0_1_4_1_0_1_0_0 - 1.11746031746035*G0_0_1_4_1_0_2_0_1 + 1.11746031746035*G0_0_1_4_1_0_3_1_0 + 1.11746031746035*G0_0_1_4_1_0_3_1_1 - 1.11746031746035*G0_0_1_4_1_0_4_1_0 - 1.11746031746035*G0_0_1_4_1_0_5_1_1 + 1.11746031746035*G0_0_1_5_1_1_0_0_0 + 1.11746031746035*G0_0_1_5_1_1_0_0_1 - 1.11746031746035*G0_0_1_5_1_1_1_0_0 - 1.11746031746035*G0_0_1_5_1_1_2_0_1 + 1.11746031746035*G0_0_1_5_1_1_3_1_0 + 1.11746031746035*G0_0_1_5_1_1_3_1_1 - 1.11746031746035*G0_0_1_5_1_1_4_1_0 - 1.11746031746035*G0_0_1_5_1_1_5_1_1 - 1.11746031746034*G0_1_0_0_0_0_0_0_0 - 1.11746031746034*G0_1_0_0_0_0_0_0_1 + 1.11746031746034*G0_1_0_0_0_0_1_0_0 + 1.11746031746034*G0_1_0_0_0_0_2_0_1 - 1.11746031746034*G0_1_0_0_0_0_3_1_0 - 1.11746031746034*G0_1_0_0_0_0_3_1_1 + 1.11746031746034*G0_1_0_0_0_0_4_1_0 + 1.11746031746034*G0_1_0_0_0_0_5_1_1 - 1.11746031746034*G0_1_0_0_0_1_0_0_0 - 1.11746031746034*G0_1_0_0_0_1_0_0_1 + 1.11746031746034*G0_1_0_0_0_1_1_0_0 + 1.11746031746034*G0_1_0_0_0_1_2_0_1 - 1.11746031746034*G0_1_0_0_0_1_3_1_0 - 1.11746031746034*G0_1_0_0_0_1_3_1_1 + 1.11746031746034*G0_1_0_0_0_1_4_1_0 + 1.11746031746034*G0_1_0_0_0_1_5_1_1 + 1.11746031746034*G0_1_0_1_0_0_0_0_0 + 1.11746031746034*G0_1_0_1_0_0_0_0_1 - 1.11746031746034*G0_1_0_1_0_0_1_0_0 - 1.11746031746034*G0_1_0_1_0_0_2_0_1 + 1.11746031746034*G0_1_0_1_0_0_3_1_0 + 1.11746031746034*G0_1_0_1_0_0_3_1_1 - 1.11746031746034*G0_1_0_1_0_0_4_1_0 - 1.11746031746034*G0_1_0_1_0_0_5_1_1 + 1.11746031746034*G0_1_0_2_0_1_0_0_0 + 1.11746031746034*G0_1_0_2_0_1_0_0_1 - 1.11746031746034*G0_1_0_2_0_1_1_0_0 - 1.11746031746034*G0_1_0_2_0_1_2_0_1 + 1.11746031746034*G0_1_0_2_0_1_3_1_0 + 1.11746031746034*G0_1_0_2_0_1_3_1_1 - 1.11746031746034*G0_1_0_2_0_1_4_1_0 - 1.11746031746034*G0_1_0_2_0_1_5_1_1 - 1.11746031746034*G0_1_0_3_1_0_0_0_0 - 1.11746031746034*G0_1_0_3_1_0_0_0_1 + 1.11746031746034*G0_1_0_3_1_0_1_0_0 + 1.11746031746034*G0_1_0_3_1_0_2_0_1 - 1.11746031746034*G0_1_0_3_1_0_3_1_0 - 1.11746031746034*G0_1_0_3_1_0_3_1_1 + 1.11746031746034*G0_1_0_3_1_0_4_1_0 + 1.11746031746034*G0_1_0_3_1_0_5_1_1 - 1.11746031746034*G0_1_0_3_1_1_0_0_0 - 1.11746031746034*G0_1_0_3_1_1_0_0_1 + 1.11746031746034*G0_1_0_3_1_1_1_0_0 + 1.11746031746034*G0_1_0_3_1_1_2_0_1 - 1.11746031746034*G0_1_0_3_1_1_3_1_0 - 1.11746031746034*G0_1_0_3_1_1_3_1_1 + 1.11746031746034*G0_1_0_3_1_1_4_1_0 + 1.11746031746034*G0_1_0_3_1_1_5_1_1 + 1.11746031746034*G0_1_0_4_1_0_0_0_0 + 1.11746031746034*G0_1_0_4_1_0_0_0_1 - 1.11746031746034*G0_1_0_4_1_0_1_0_0 - 1.11746031746034*G0_1_0_4_1_0_2_0_1 + 1.11746031746034*G0_1_0_4_1_0_3_1_0 + 1.11746031746034*G0_1_0_4_1_0_3_1_1 - 1.11746031746034*G0_1_0_4_1_0_4_1_0 - 1.11746031746034*G0_1_0_4_1_0_5_1_1 + 1.11746031746034*G0_1_0_5_1_1_0_0_0 + 1.11746031746034*G0_1_0_5_1_1_0_0_1 - 1.11746031746034*G0_1_0_5_1_1_1_0_0 - 1.11746031746034*G0_1_0_5_1_1_2_0_1 + 1.11746031746034*G0_1_0_5_1_1_3_1_0 + 1.11746031746034*G0_1_0_5_1_1_3_1_1 - 1.11746031746034*G0_1_0_5_1_1_4_1_0 - 1.11746031746034*G0_1_0_5_1_1_5_1_1; + A[394] = A[134] + 3.2507936507937*G0_0_0_0_0_0_0_0_0 + 3.2507936507937*G0_0_0_0_0_0_0_0_1 - 3.2507936507937*G0_0_0_0_0_0_1_0_0 - 3.2507936507937*G0_0_0_0_0_0_2_0_1 + 3.2507936507937*G0_0_0_0_0_0_3_1_0 + 3.2507936507937*G0_0_0_0_0_0_3_1_1 - 3.2507936507937*G0_0_0_0_0_0_4_1_0 - 3.2507936507937*G0_0_0_0_0_0_5_1_1 + 3.2507936507937*G0_0_0_0_0_1_0_0_0 + 3.2507936507937*G0_0_0_0_0_1_0_0_1 - 3.2507936507937*G0_0_0_0_0_1_1_0_0 - 3.2507936507937*G0_0_0_0_0_1_2_0_1 + 3.2507936507937*G0_0_0_0_0_1_3_1_0 + 3.2507936507937*G0_0_0_0_0_1_3_1_1 - 3.2507936507937*G0_0_0_0_0_1_4_1_0 - 3.2507936507937*G0_0_0_0_0_1_5_1_1 - 3.2507936507937*G0_0_0_1_0_0_0_0_0 - 3.2507936507937*G0_0_0_1_0_0_0_0_1 + 3.2507936507937*G0_0_0_1_0_0_1_0_0 + 3.2507936507937*G0_0_0_1_0_0_2_0_1 - 3.2507936507937*G0_0_0_1_0_0_3_1_0 - 3.2507936507937*G0_0_0_1_0_0_3_1_1 + 3.2507936507937*G0_0_0_1_0_0_4_1_0 + 3.2507936507937*G0_0_0_1_0_0_5_1_1 - 3.2507936507937*G0_0_0_2_0_1_0_0_0 - 3.2507936507937*G0_0_0_2_0_1_0_0_1 + 3.2507936507937*G0_0_0_2_0_1_1_0_0 + 3.2507936507937*G0_0_0_2_0_1_2_0_1 - 3.2507936507937*G0_0_0_2_0_1_3_1_0 - 3.2507936507937*G0_0_0_2_0_1_3_1_1 + 3.2507936507937*G0_0_0_2_0_1_4_1_0 + 3.2507936507937*G0_0_0_2_0_1_5_1_1 + 3.2507936507937*G0_0_0_3_1_0_0_0_0 + 3.2507936507937*G0_0_0_3_1_0_0_0_1 - 3.2507936507937*G0_0_0_3_1_0_1_0_0 - 3.2507936507937*G0_0_0_3_1_0_2_0_1 + 3.2507936507937*G0_0_0_3_1_0_3_1_0 + 3.2507936507937*G0_0_0_3_1_0_3_1_1 - 3.2507936507937*G0_0_0_3_1_0_4_1_0 - 3.2507936507937*G0_0_0_3_1_0_5_1_1 + 3.2507936507937*G0_0_0_3_1_1_0_0_0 + 3.2507936507937*G0_0_0_3_1_1_0_0_1 - 3.2507936507937*G0_0_0_3_1_1_1_0_0 - 3.2507936507937*G0_0_0_3_1_1_2_0_1 + 3.2507936507937*G0_0_0_3_1_1_3_1_0 + 3.2507936507937*G0_0_0_3_1_1_3_1_1 - 3.2507936507937*G0_0_0_3_1_1_4_1_0 - 3.2507936507937*G0_0_0_3_1_1_5_1_1 - 3.2507936507937*G0_0_0_4_1_0_0_0_0 - 3.2507936507937*G0_0_0_4_1_0_0_0_1 + 3.2507936507937*G0_0_0_4_1_0_1_0_0 + 3.2507936507937*G0_0_0_4_1_0_2_0_1 - 3.2507936507937*G0_0_0_4_1_0_3_1_0 - 3.2507936507937*G0_0_0_4_1_0_3_1_1 + 3.2507936507937*G0_0_0_4_1_0_4_1_0 + 3.2507936507937*G0_0_0_4_1_0_5_1_1 - 3.2507936507937*G0_0_0_5_1_1_0_0_0 - 3.2507936507937*G0_0_0_5_1_1_0_0_1 + 3.2507936507937*G0_0_0_5_1_1_1_0_0 + 3.2507936507937*G0_0_0_5_1_1_2_0_1 - 3.2507936507937*G0_0_0_5_1_1_3_1_0 - 3.2507936507937*G0_0_0_5_1_1_3_1_1 + 3.2507936507937*G0_0_0_5_1_1_4_1_0 + 3.2507936507937*G0_0_0_5_1_1_5_1_1 - 3.25079365079369*G0_1_1_0_0_0_0_0_0 - 3.25079365079369*G0_1_1_0_0_0_0_0_1 + 3.25079365079369*G0_1_1_0_0_0_1_0_0 + 3.25079365079369*G0_1_1_0_0_0_2_0_1 - 3.25079365079369*G0_1_1_0_0_0_3_1_0 - 3.25079365079369*G0_1_1_0_0_0_3_1_1 + 3.25079365079369*G0_1_1_0_0_0_4_1_0 + 3.25079365079369*G0_1_1_0_0_0_5_1_1 - 3.25079365079369*G0_1_1_0_0_1_0_0_0 - 3.25079365079369*G0_1_1_0_0_1_0_0_1 + 3.25079365079369*G0_1_1_0_0_1_1_0_0 + 3.25079365079369*G0_1_1_0_0_1_2_0_1 - 3.25079365079369*G0_1_1_0_0_1_3_1_0 - 3.25079365079369*G0_1_1_0_0_1_3_1_1 + 3.25079365079369*G0_1_1_0_0_1_4_1_0 + 3.25079365079369*G0_1_1_0_0_1_5_1_1 + 3.25079365079369*G0_1_1_1_0_0_0_0_0 + 3.25079365079369*G0_1_1_1_0_0_0_0_1 - 3.25079365079369*G0_1_1_1_0_0_1_0_0 - 3.25079365079369*G0_1_1_1_0_0_2_0_1 + 3.25079365079369*G0_1_1_1_0_0_3_1_0 + 3.25079365079369*G0_1_1_1_0_0_3_1_1 - 3.25079365079369*G0_1_1_1_0_0_4_1_0 - 3.25079365079369*G0_1_1_1_0_0_5_1_1 + 3.25079365079369*G0_1_1_2_0_1_0_0_0 + 3.25079365079369*G0_1_1_2_0_1_0_0_1 - 3.25079365079369*G0_1_1_2_0_1_1_0_0 - 3.25079365079369*G0_1_1_2_0_1_2_0_1 + 3.25079365079369*G0_1_1_2_0_1_3_1_0 + 3.25079365079369*G0_1_1_2_0_1_3_1_1 - 3.25079365079369*G0_1_1_2_0_1_4_1_0 - 3.25079365079369*G0_1_1_2_0_1_5_1_1 - 3.25079365079369*G0_1_1_3_1_0_0_0_0 - 3.25079365079369*G0_1_1_3_1_0_0_0_1 + 3.25079365079369*G0_1_1_3_1_0_1_0_0 + 3.25079365079369*G0_1_1_3_1_0_2_0_1 - 3.25079365079369*G0_1_1_3_1_0_3_1_0 - 3.25079365079369*G0_1_1_3_1_0_3_1_1 + 3.25079365079369*G0_1_1_3_1_0_4_1_0 + 3.25079365079369*G0_1_1_3_1_0_5_1_1 - 3.25079365079369*G0_1_1_3_1_1_0_0_0 - 3.25079365079369*G0_1_1_3_1_1_0_0_1 + 3.25079365079369*G0_1_1_3_1_1_1_0_0 + 3.25079365079369*G0_1_1_3_1_1_2_0_1 - 3.25079365079369*G0_1_1_3_1_1_3_1_0 - 3.25079365079369*G0_1_1_3_1_1_3_1_1 + 3.25079365079369*G0_1_1_3_1_1_4_1_0 + 3.25079365079369*G0_1_1_3_1_1_5_1_1 + 3.25079365079369*G0_1_1_4_1_0_0_0_0 + 3.25079365079369*G0_1_1_4_1_0_0_0_1 - 3.25079365079369*G0_1_1_4_1_0_1_0_0 - 3.25079365079369*G0_1_1_4_1_0_2_0_1 + 3.25079365079369*G0_1_1_4_1_0_3_1_0 + 3.25079365079369*G0_1_1_4_1_0_3_1_1 - 3.25079365079369*G0_1_1_4_1_0_4_1_0 - 3.25079365079369*G0_1_1_4_1_0_5_1_1 + 3.25079365079369*G0_1_1_5_1_1_0_0_0 + 3.25079365079369*G0_1_1_5_1_1_0_0_1 - 3.25079365079369*G0_1_1_5_1_1_1_0_0 - 3.25079365079369*G0_1_1_5_1_1_2_0_1 + 3.25079365079369*G0_1_1_5_1_1_3_1_0 + 3.25079365079369*G0_1_1_5_1_1_3_1_1 - 3.25079365079369*G0_1_1_5_1_1_4_1_0 - 3.25079365079369*G0_1_1_5_1_1_5_1_1; + A[599] = A[134]; + A[688] = A[314] + 0.507936507936539*G0_0_0_0_0_0_0_0_0 + 0.507936507936539*G0_0_0_0_0_0_0_0_1 - 0.507936507936539*G0_0_0_0_0_0_1_0_0 - 0.507936507936539*G0_0_0_0_0_0_2_0_1 + 0.507936507936539*G0_0_0_0_0_0_3_1_0 + 0.507936507936539*G0_0_0_0_0_0_3_1_1 - 0.507936507936539*G0_0_0_0_0_0_4_1_0 - 0.507936507936539*G0_0_0_0_0_0_5_1_1 + 0.507936507936539*G0_0_0_0_0_1_0_0_0 + 0.507936507936539*G0_0_0_0_0_1_0_0_1 - 0.507936507936539*G0_0_0_0_0_1_1_0_0 - 0.507936507936539*G0_0_0_0_0_1_2_0_1 + 0.507936507936539*G0_0_0_0_0_1_3_1_0 + 0.507936507936539*G0_0_0_0_0_1_3_1_1 - 0.507936507936539*G0_0_0_0_0_1_4_1_0 - 0.507936507936539*G0_0_0_0_0_1_5_1_1 - 0.507936507936539*G0_0_0_1_0_0_0_0_0 - 0.507936507936539*G0_0_0_1_0_0_0_0_1 + 0.507936507936539*G0_0_0_1_0_0_1_0_0 + 0.507936507936539*G0_0_0_1_0_0_2_0_1 - 0.507936507936539*G0_0_0_1_0_0_3_1_0 - 0.507936507936539*G0_0_0_1_0_0_3_1_1 + 0.507936507936539*G0_0_0_1_0_0_4_1_0 + 0.507936507936539*G0_0_0_1_0_0_5_1_1 - 0.507936507936539*G0_0_0_2_0_1_0_0_0 - 0.507936507936539*G0_0_0_2_0_1_0_0_1 + 0.507936507936539*G0_0_0_2_0_1_1_0_0 + 0.507936507936539*G0_0_0_2_0_1_2_0_1 - 0.507936507936539*G0_0_0_2_0_1_3_1_0 - 0.507936507936539*G0_0_0_2_0_1_3_1_1 + 0.507936507936539*G0_0_0_2_0_1_4_1_0 + 0.507936507936539*G0_0_0_2_0_1_5_1_1 + 0.507936507936539*G0_0_0_3_1_0_0_0_0 + 0.507936507936539*G0_0_0_3_1_0_0_0_1 - 0.507936507936539*G0_0_0_3_1_0_1_0_0 - 0.507936507936539*G0_0_0_3_1_0_2_0_1 + 0.507936507936539*G0_0_0_3_1_0_3_1_0 + 0.507936507936539*G0_0_0_3_1_0_3_1_1 - 0.507936507936539*G0_0_0_3_1_0_4_1_0 - 0.507936507936539*G0_0_0_3_1_0_5_1_1 + 0.507936507936539*G0_0_0_3_1_1_0_0_0 + 0.507936507936539*G0_0_0_3_1_1_0_0_1 - 0.507936507936539*G0_0_0_3_1_1_1_0_0 - 0.507936507936539*G0_0_0_3_1_1_2_0_1 + 0.507936507936539*G0_0_0_3_1_1_3_1_0 + 0.507936507936539*G0_0_0_3_1_1_3_1_1 - 0.507936507936539*G0_0_0_3_1_1_4_1_0 - 0.507936507936539*G0_0_0_3_1_1_5_1_1 - 0.507936507936539*G0_0_0_4_1_0_0_0_0 - 0.507936507936539*G0_0_0_4_1_0_0_0_1 + 0.507936507936539*G0_0_0_4_1_0_1_0_0 + 0.507936507936539*G0_0_0_4_1_0_2_0_1 - 0.507936507936539*G0_0_0_4_1_0_3_1_0 - 0.507936507936539*G0_0_0_4_1_0_3_1_1 + 0.507936507936539*G0_0_0_4_1_0_4_1_0 + 0.507936507936539*G0_0_0_4_1_0_5_1_1 - 0.507936507936539*G0_0_0_5_1_1_0_0_0 - 0.507936507936539*G0_0_0_5_1_1_0_0_1 + 0.507936507936539*G0_0_0_5_1_1_1_0_0 + 0.507936507936539*G0_0_0_5_1_1_2_0_1 - 0.507936507936539*G0_0_0_5_1_1_3_1_0 - 0.507936507936539*G0_0_0_5_1_1_3_1_1 + 0.507936507936539*G0_0_0_5_1_1_4_1_0 + 0.507936507936539*G0_0_0_5_1_1_5_1_1 - 0.507936507936546*G0_1_1_0_0_0_0_0_0 - 0.507936507936546*G0_1_1_0_0_0_0_0_1 + 0.507936507936546*G0_1_1_0_0_0_1_0_0 + 0.507936507936546*G0_1_1_0_0_0_2_0_1 - 0.507936507936546*G0_1_1_0_0_0_3_1_0 - 0.507936507936546*G0_1_1_0_0_0_3_1_1 + 0.507936507936546*G0_1_1_0_0_0_4_1_0 + 0.507936507936546*G0_1_1_0_0_0_5_1_1 - 0.507936507936546*G0_1_1_0_0_1_0_0_0 - 0.507936507936546*G0_1_1_0_0_1_0_0_1 + 0.507936507936546*G0_1_1_0_0_1_1_0_0 + 0.507936507936546*G0_1_1_0_0_1_2_0_1 - 0.507936507936546*G0_1_1_0_0_1_3_1_0 - 0.507936507936546*G0_1_1_0_0_1_3_1_1 + 0.507936507936546*G0_1_1_0_0_1_4_1_0 + 0.507936507936546*G0_1_1_0_0_1_5_1_1 + 0.507936507936546*G0_1_1_1_0_0_0_0_0 + 0.507936507936546*G0_1_1_1_0_0_0_0_1 - 0.507936507936546*G0_1_1_1_0_0_1_0_0 - 0.507936507936546*G0_1_1_1_0_0_2_0_1 + 0.507936507936546*G0_1_1_1_0_0_3_1_0 + 0.507936507936546*G0_1_1_1_0_0_3_1_1 - 0.507936507936546*G0_1_1_1_0_0_4_1_0 - 0.507936507936546*G0_1_1_1_0_0_5_1_1 + 0.507936507936546*G0_1_1_2_0_1_0_0_0 + 0.507936507936546*G0_1_1_2_0_1_0_0_1 - 0.507936507936546*G0_1_1_2_0_1_1_0_0 - 0.507936507936546*G0_1_1_2_0_1_2_0_1 + 0.507936507936546*G0_1_1_2_0_1_3_1_0 + 0.507936507936546*G0_1_1_2_0_1_3_1_1 - 0.507936507936546*G0_1_1_2_0_1_4_1_0 - 0.507936507936546*G0_1_1_2_0_1_5_1_1 - 0.507936507936546*G0_1_1_3_1_0_0_0_0 - 0.507936507936546*G0_1_1_3_1_0_0_0_1 + 0.507936507936546*G0_1_1_3_1_0_1_0_0 + 0.507936507936546*G0_1_1_3_1_0_2_0_1 - 0.507936507936546*G0_1_1_3_1_0_3_1_0 - 0.507936507936546*G0_1_1_3_1_0_3_1_1 + 0.507936507936546*G0_1_1_3_1_0_4_1_0 + 0.507936507936546*G0_1_1_3_1_0_5_1_1 - 0.507936507936546*G0_1_1_3_1_1_0_0_0 - 0.507936507936546*G0_1_1_3_1_1_0_0_1 + 0.507936507936546*G0_1_1_3_1_1_1_0_0 + 0.507936507936546*G0_1_1_3_1_1_2_0_1 - 0.507936507936546*G0_1_1_3_1_1_3_1_0 - 0.507936507936546*G0_1_1_3_1_1_3_1_1 + 0.507936507936546*G0_1_1_3_1_1_4_1_0 + 0.507936507936546*G0_1_1_3_1_1_5_1_1 + 0.507936507936546*G0_1_1_4_1_0_0_0_0 + 0.507936507936546*G0_1_1_4_1_0_0_0_1 - 0.507936507936546*G0_1_1_4_1_0_1_0_0 - 0.507936507936546*G0_1_1_4_1_0_2_0_1 + 0.507936507936546*G0_1_1_4_1_0_3_1_0 + 0.507936507936546*G0_1_1_4_1_0_3_1_1 - 0.507936507936546*G0_1_1_4_1_0_4_1_0 - 0.507936507936546*G0_1_1_4_1_0_5_1_1 + 0.507936507936546*G0_1_1_5_1_1_0_0_0 + 0.507936507936546*G0_1_1_5_1_1_0_0_1 - 0.507936507936546*G0_1_1_5_1_1_1_0_0 - 0.507936507936546*G0_1_1_5_1_1_2_0_1 + 0.507936507936546*G0_1_1_5_1_1_3_1_0 + 0.507936507936546*G0_1_1_5_1_1_3_1_1 - 0.507936507936546*G0_1_1_5_1_1_4_1_0 - 0.507936507936546*G0_1_1_5_1_1_5_1_1; + A[832] = A[367]; + A[476] = -A[5] - 0.203174603174605*G0_0_0_0_0_0_0_0_0 - 0.203174603174605*G0_0_0_0_0_0_0_0_1 + 0.203174603174605*G0_0_0_0_0_0_1_0_0 + 0.203174603174605*G0_0_0_0_0_0_2_0_1 - 0.203174603174605*G0_0_0_0_0_0_3_1_0 - 0.203174603174605*G0_0_0_0_0_0_3_1_1 + 0.203174603174605*G0_0_0_0_0_0_4_1_0 + 0.203174603174605*G0_0_0_0_0_0_5_1_1 - 0.203174603174605*G0_0_0_0_0_1_0_0_0 - 0.203174603174605*G0_0_0_0_0_1_0_0_1 + 0.203174603174605*G0_0_0_0_0_1_1_0_0 + 0.203174603174605*G0_0_0_0_0_1_2_0_1 - 0.203174603174605*G0_0_0_0_0_1_3_1_0 - 0.203174603174605*G0_0_0_0_0_1_3_1_1 + 0.203174603174605*G0_0_0_0_0_1_4_1_0 + 0.203174603174605*G0_0_0_0_0_1_5_1_1 + 0.203174603174605*G0_0_0_1_0_0_0_0_0 + 0.203174603174605*G0_0_0_1_0_0_0_0_1 - 0.203174603174605*G0_0_0_1_0_0_1_0_0 - 0.203174603174605*G0_0_0_1_0_0_2_0_1 + 0.203174603174605*G0_0_0_1_0_0_3_1_0 + 0.203174603174605*G0_0_0_1_0_0_3_1_1 - 0.203174603174605*G0_0_0_1_0_0_4_1_0 - 0.203174603174605*G0_0_0_1_0_0_5_1_1 + 0.203174603174605*G0_0_0_2_0_1_0_0_0 + 0.203174603174605*G0_0_0_2_0_1_0_0_1 - 0.203174603174605*G0_0_0_2_0_1_1_0_0 - 0.203174603174605*G0_0_0_2_0_1_2_0_1 + 0.203174603174605*G0_0_0_2_0_1_3_1_0 + 0.203174603174605*G0_0_0_2_0_1_3_1_1 - 0.203174603174605*G0_0_0_2_0_1_4_1_0 - 0.203174603174605*G0_0_0_2_0_1_5_1_1 - 0.203174603174605*G0_0_0_3_1_0_0_0_0 - 0.203174603174605*G0_0_0_3_1_0_0_0_1 + 0.203174603174605*G0_0_0_3_1_0_1_0_0 + 0.203174603174605*G0_0_0_3_1_0_2_0_1 - 0.203174603174605*G0_0_0_3_1_0_3_1_0 - 0.203174603174605*G0_0_0_3_1_0_3_1_1 + 0.203174603174605*G0_0_0_3_1_0_4_1_0 + 0.203174603174605*G0_0_0_3_1_0_5_1_1 - 0.203174603174605*G0_0_0_3_1_1_0_0_0 - 0.203174603174605*G0_0_0_3_1_1_0_0_1 + 0.203174603174605*G0_0_0_3_1_1_1_0_0 + 0.203174603174605*G0_0_0_3_1_1_2_0_1 - 0.203174603174605*G0_0_0_3_1_1_3_1_0 - 0.203174603174605*G0_0_0_3_1_1_3_1_1 + 0.203174603174605*G0_0_0_3_1_1_4_1_0 + 0.203174603174605*G0_0_0_3_1_1_5_1_1 + 0.203174603174605*G0_0_0_4_1_0_0_0_0 + 0.203174603174605*G0_0_0_4_1_0_0_0_1 - 0.203174603174605*G0_0_0_4_1_0_1_0_0 - 0.203174603174605*G0_0_0_4_1_0_2_0_1 + 0.203174603174605*G0_0_0_4_1_0_3_1_0 + 0.203174603174605*G0_0_0_4_1_0_3_1_1 - 0.203174603174605*G0_0_0_4_1_0_4_1_0 - 0.203174603174605*G0_0_0_4_1_0_5_1_1 + 0.203174603174605*G0_0_0_5_1_1_0_0_0 + 0.203174603174605*G0_0_0_5_1_1_0_0_1 - 0.203174603174605*G0_0_0_5_1_1_1_0_0 - 0.203174603174605*G0_0_0_5_1_1_2_0_1 + 0.203174603174605*G0_0_0_5_1_1_3_1_0 + 0.203174603174605*G0_0_0_5_1_1_3_1_1 - 0.203174603174605*G0_0_0_5_1_1_4_1_0 - 0.203174603174605*G0_0_0_5_1_1_5_1_1 - 0.203174603174604*G0_1_0_0_0_0_0_0_0 - 0.203174603174604*G0_1_0_0_0_0_0_0_1 + 0.203174603174604*G0_1_0_0_0_0_1_0_0 + 0.203174603174604*G0_1_0_0_0_0_2_0_1 - 0.203174603174604*G0_1_0_0_0_0_3_1_0 - 0.203174603174604*G0_1_0_0_0_0_3_1_1 + 0.203174603174604*G0_1_0_0_0_0_4_1_0 + 0.203174603174604*G0_1_0_0_0_0_5_1_1 - 0.203174603174604*G0_1_0_0_0_1_0_0_0 - 0.203174603174604*G0_1_0_0_0_1_0_0_1 + 0.203174603174604*G0_1_0_0_0_1_1_0_0 + 0.203174603174604*G0_1_0_0_0_1_2_0_1 - 0.203174603174604*G0_1_0_0_0_1_3_1_0 - 0.203174603174604*G0_1_0_0_0_1_3_1_1 + 0.203174603174604*G0_1_0_0_0_1_4_1_0 + 0.203174603174604*G0_1_0_0_0_1_5_1_1 + 0.203174603174604*G0_1_0_1_0_0_0_0_0 + 0.203174603174604*G0_1_0_1_0_0_0_0_1 - 0.203174603174604*G0_1_0_1_0_0_1_0_0 - 0.203174603174604*G0_1_0_1_0_0_2_0_1 + 0.203174603174604*G0_1_0_1_0_0_3_1_0 + 0.203174603174604*G0_1_0_1_0_0_3_1_1 - 0.203174603174604*G0_1_0_1_0_0_4_1_0 - 0.203174603174604*G0_1_0_1_0_0_5_1_1 + 0.203174603174604*G0_1_0_2_0_1_0_0_0 + 0.203174603174604*G0_1_0_2_0_1_0_0_1 - 0.203174603174604*G0_1_0_2_0_1_1_0_0 - 0.203174603174604*G0_1_0_2_0_1_2_0_1 + 0.203174603174604*G0_1_0_2_0_1_3_1_0 + 0.203174603174604*G0_1_0_2_0_1_3_1_1 - 0.203174603174604*G0_1_0_2_0_1_4_1_0 - 0.203174603174604*G0_1_0_2_0_1_5_1_1 - 0.203174603174604*G0_1_0_3_1_0_0_0_0 - 0.203174603174604*G0_1_0_3_1_0_0_0_1 + 0.203174603174604*G0_1_0_3_1_0_1_0_0 + 0.203174603174604*G0_1_0_3_1_0_2_0_1 - 0.203174603174604*G0_1_0_3_1_0_3_1_0 - 0.203174603174604*G0_1_0_3_1_0_3_1_1 + 0.203174603174604*G0_1_0_3_1_0_4_1_0 + 0.203174603174604*G0_1_0_3_1_0_5_1_1 - 0.203174603174604*G0_1_0_3_1_1_0_0_0 - 0.203174603174604*G0_1_0_3_1_1_0_0_1 + 0.203174603174604*G0_1_0_3_1_1_1_0_0 + 0.203174603174604*G0_1_0_3_1_1_2_0_1 - 0.203174603174604*G0_1_0_3_1_1_3_1_0 - 0.203174603174604*G0_1_0_3_1_1_3_1_1 + 0.203174603174604*G0_1_0_3_1_1_4_1_0 + 0.203174603174604*G0_1_0_3_1_1_5_1_1 + 0.203174603174604*G0_1_0_4_1_0_0_0_0 + 0.203174603174604*G0_1_0_4_1_0_0_0_1 - 0.203174603174604*G0_1_0_4_1_0_1_0_0 - 0.203174603174604*G0_1_0_4_1_0_2_0_1 + 0.203174603174604*G0_1_0_4_1_0_3_1_0 + 0.203174603174604*G0_1_0_4_1_0_3_1_1 - 0.203174603174604*G0_1_0_4_1_0_4_1_0 - 0.203174603174604*G0_1_0_4_1_0_5_1_1 + 0.203174603174604*G0_1_0_5_1_1_0_0_0 + 0.203174603174604*G0_1_0_5_1_1_0_0_1 - 0.203174603174604*G0_1_0_5_1_1_1_0_0 - 0.203174603174604*G0_1_0_5_1_1_2_0_1 + 0.203174603174604*G0_1_0_5_1_1_3_1_0 + 0.203174603174604*G0_1_0_5_1_1_3_1_1 - 0.203174603174604*G0_1_0_5_1_1_4_1_0 - 0.203174603174604*G0_1_0_5_1_1_5_1_1; + A[340] = A[805]; + A[21] = 0.0; + A[738] = A[273]; + A[425] = A[890]; + A[373] = A[897] - 3.2507936507937*G0_0_0_0_0_0_0_0_0 - 3.2507936507937*G0_0_0_0_0_0_0_0_1 + 3.2507936507937*G0_0_0_0_0_0_1_0_0 + 3.2507936507937*G0_0_0_0_0_0_2_0_1 - 3.2507936507937*G0_0_0_0_0_0_3_1_0 - 3.2507936507937*G0_0_0_0_0_0_3_1_1 + 3.2507936507937*G0_0_0_0_0_0_4_1_0 + 3.2507936507937*G0_0_0_0_0_0_5_1_1 - 3.2507936507937*G0_0_0_0_0_1_0_0_0 - 3.2507936507937*G0_0_0_0_0_1_0_0_1 + 3.2507936507937*G0_0_0_0_0_1_1_0_0 + 3.2507936507937*G0_0_0_0_0_1_2_0_1 - 3.2507936507937*G0_0_0_0_0_1_3_1_0 - 3.2507936507937*G0_0_0_0_0_1_3_1_1 + 3.2507936507937*G0_0_0_0_0_1_4_1_0 + 3.2507936507937*G0_0_0_0_0_1_5_1_1 + 3.2507936507937*G0_0_0_1_0_0_0_0_0 + 3.2507936507937*G0_0_0_1_0_0_0_0_1 - 3.2507936507937*G0_0_0_1_0_0_1_0_0 - 3.2507936507937*G0_0_0_1_0_0_2_0_1 + 3.2507936507937*G0_0_0_1_0_0_3_1_0 + 3.2507936507937*G0_0_0_1_0_0_3_1_1 - 3.2507936507937*G0_0_0_1_0_0_4_1_0 - 3.2507936507937*G0_0_0_1_0_0_5_1_1 + 3.2507936507937*G0_0_0_2_0_1_0_0_0 + 3.2507936507937*G0_0_0_2_0_1_0_0_1 - 3.2507936507937*G0_0_0_2_0_1_1_0_0 - 3.2507936507937*G0_0_0_2_0_1_2_0_1 + 3.2507936507937*G0_0_0_2_0_1_3_1_0 + 3.2507936507937*G0_0_0_2_0_1_3_1_1 - 3.2507936507937*G0_0_0_2_0_1_4_1_0 - 3.2507936507937*G0_0_0_2_0_1_5_1_1 - 3.2507936507937*G0_0_0_3_1_0_0_0_0 - 3.2507936507937*G0_0_0_3_1_0_0_0_1 + 3.2507936507937*G0_0_0_3_1_0_1_0_0 + 3.2507936507937*G0_0_0_3_1_0_2_0_1 - 3.2507936507937*G0_0_0_3_1_0_3_1_0 - 3.2507936507937*G0_0_0_3_1_0_3_1_1 + 3.2507936507937*G0_0_0_3_1_0_4_1_0 + 3.2507936507937*G0_0_0_3_1_0_5_1_1 - 3.2507936507937*G0_0_0_3_1_1_0_0_0 - 3.2507936507937*G0_0_0_3_1_1_0_0_1 + 3.2507936507937*G0_0_0_3_1_1_1_0_0 + 3.2507936507937*G0_0_0_3_1_1_2_0_1 - 3.2507936507937*G0_0_0_3_1_1_3_1_0 - 3.2507936507937*G0_0_0_3_1_1_3_1_1 + 3.2507936507937*G0_0_0_3_1_1_4_1_0 + 3.2507936507937*G0_0_0_3_1_1_5_1_1 + 3.2507936507937*G0_0_0_4_1_0_0_0_0 + 3.2507936507937*G0_0_0_4_1_0_0_0_1 - 3.2507936507937*G0_0_0_4_1_0_1_0_0 - 3.2507936507937*G0_0_0_4_1_0_2_0_1 + 3.2507936507937*G0_0_0_4_1_0_3_1_0 + 3.2507936507937*G0_0_0_4_1_0_3_1_1 - 3.2507936507937*G0_0_0_4_1_0_4_1_0 - 3.2507936507937*G0_0_0_4_1_0_5_1_1 + 3.2507936507937*G0_0_0_5_1_1_0_0_0 + 3.2507936507937*G0_0_0_5_1_1_0_0_1 - 3.2507936507937*G0_0_0_5_1_1_1_0_0 - 3.2507936507937*G0_0_0_5_1_1_2_0_1 + 3.2507936507937*G0_0_0_5_1_1_3_1_0 + 3.2507936507937*G0_0_0_5_1_1_3_1_1 - 3.2507936507937*G0_0_0_5_1_1_4_1_0 - 3.2507936507937*G0_0_0_5_1_1_5_1_1 + 3.2507936507937*G0_1_1_0_0_0_0_0_0 + 3.2507936507937*G0_1_1_0_0_0_0_0_1 - 3.2507936507937*G0_1_1_0_0_0_1_0_0 - 3.2507936507937*G0_1_1_0_0_0_2_0_1 + 3.2507936507937*G0_1_1_0_0_0_3_1_0 + 3.2507936507937*G0_1_1_0_0_0_3_1_1 - 3.2507936507937*G0_1_1_0_0_0_4_1_0 - 3.2507936507937*G0_1_1_0_0_0_5_1_1 + 3.2507936507937*G0_1_1_0_0_1_0_0_0 + 3.2507936507937*G0_1_1_0_0_1_0_0_1 - 3.2507936507937*G0_1_1_0_0_1_1_0_0 - 3.2507936507937*G0_1_1_0_0_1_2_0_1 + 3.2507936507937*G0_1_1_0_0_1_3_1_0 + 3.2507936507937*G0_1_1_0_0_1_3_1_1 - 3.2507936507937*G0_1_1_0_0_1_4_1_0 - 3.2507936507937*G0_1_1_0_0_1_5_1_1 - 3.2507936507937*G0_1_1_1_0_0_0_0_0 - 3.2507936507937*G0_1_1_1_0_0_0_0_1 + 3.2507936507937*G0_1_1_1_0_0_1_0_0 + 3.2507936507937*G0_1_1_1_0_0_2_0_1 - 3.2507936507937*G0_1_1_1_0_0_3_1_0 - 3.2507936507937*G0_1_1_1_0_0_3_1_1 + 3.2507936507937*G0_1_1_1_0_0_4_1_0 + 3.2507936507937*G0_1_1_1_0_0_5_1_1 - 3.2507936507937*G0_1_1_2_0_1_0_0_0 - 3.2507936507937*G0_1_1_2_0_1_0_0_1 + 3.2507936507937*G0_1_1_2_0_1_1_0_0 + 3.2507936507937*G0_1_1_2_0_1_2_0_1 - 3.2507936507937*G0_1_1_2_0_1_3_1_0 - 3.2507936507937*G0_1_1_2_0_1_3_1_1 + 3.2507936507937*G0_1_1_2_0_1_4_1_0 + 3.2507936507937*G0_1_1_2_0_1_5_1_1 + 3.2507936507937*G0_1_1_3_1_0_0_0_0 + 3.2507936507937*G0_1_1_3_1_0_0_0_1 - 3.2507936507937*G0_1_1_3_1_0_1_0_0 - 3.2507936507937*G0_1_1_3_1_0_2_0_1 + 3.2507936507937*G0_1_1_3_1_0_3_1_0 + 3.2507936507937*G0_1_1_3_1_0_3_1_1 - 3.2507936507937*G0_1_1_3_1_0_4_1_0 - 3.2507936507937*G0_1_1_3_1_0_5_1_1 + 3.2507936507937*G0_1_1_3_1_1_0_0_0 + 3.2507936507937*G0_1_1_3_1_1_0_0_1 - 3.2507936507937*G0_1_1_3_1_1_1_0_0 - 3.2507936507937*G0_1_1_3_1_1_2_0_1 + 3.2507936507937*G0_1_1_3_1_1_3_1_0 + 3.2507936507937*G0_1_1_3_1_1_3_1_1 - 3.2507936507937*G0_1_1_3_1_1_4_1_0 - 3.2507936507937*G0_1_1_3_1_1_5_1_1 - 3.2507936507937*G0_1_1_4_1_0_0_0_0 - 3.2507936507937*G0_1_1_4_1_0_0_0_1 + 3.2507936507937*G0_1_1_4_1_0_1_0_0 + 3.2507936507937*G0_1_1_4_1_0_2_0_1 - 3.2507936507937*G0_1_1_4_1_0_3_1_0 - 3.2507936507937*G0_1_1_4_1_0_3_1_1 + 3.2507936507937*G0_1_1_4_1_0_4_1_0 + 3.2507936507937*G0_1_1_4_1_0_5_1_1 - 3.2507936507937*G0_1_1_5_1_1_0_0_0 - 3.2507936507937*G0_1_1_5_1_1_0_0_1 + 3.2507936507937*G0_1_1_5_1_1_1_0_0 + 3.2507936507937*G0_1_1_5_1_1_2_0_1 - 3.2507936507937*G0_1_1_5_1_1_3_1_0 - 3.2507936507937*G0_1_1_5_1_1_3_1_1 + 3.2507936507937*G0_1_1_5_1_1_4_1_0 + 3.2507936507937*G0_1_1_5_1_1_5_1_1; + A[46] = 0.0; + A[769] = A[679] - 0.342857142857162*G0_0_0_0_0_0_0_0_0 - 0.342857142857162*G0_0_0_0_0_0_0_0_1 + 0.342857142857162*G0_0_0_0_0_0_1_0_0 + 0.342857142857162*G0_0_0_0_0_0_2_0_1 - 0.342857142857162*G0_0_0_0_0_0_3_1_0 - 0.342857142857162*G0_0_0_0_0_0_3_1_1 + 0.342857142857162*G0_0_0_0_0_0_4_1_0 + 0.342857142857162*G0_0_0_0_0_0_5_1_1 - 0.342857142857162*G0_0_0_0_0_1_0_0_0 - 0.342857142857162*G0_0_0_0_0_1_0_0_1 + 0.342857142857162*G0_0_0_0_0_1_1_0_0 + 0.342857142857162*G0_0_0_0_0_1_2_0_1 - 0.342857142857162*G0_0_0_0_0_1_3_1_0 - 0.342857142857162*G0_0_0_0_0_1_3_1_1 + 0.342857142857162*G0_0_0_0_0_1_4_1_0 + 0.342857142857162*G0_0_0_0_0_1_5_1_1 + 0.342857142857162*G0_0_0_1_0_0_0_0_0 + 0.342857142857162*G0_0_0_1_0_0_0_0_1 - 0.342857142857162*G0_0_0_1_0_0_1_0_0 - 0.342857142857162*G0_0_0_1_0_0_2_0_1 + 0.342857142857162*G0_0_0_1_0_0_3_1_0 + 0.342857142857162*G0_0_0_1_0_0_3_1_1 - 0.342857142857162*G0_0_0_1_0_0_4_1_0 - 0.342857142857162*G0_0_0_1_0_0_5_1_1 + 0.342857142857162*G0_0_0_2_0_1_0_0_0 + 0.342857142857162*G0_0_0_2_0_1_0_0_1 - 0.342857142857162*G0_0_0_2_0_1_1_0_0 - 0.342857142857162*G0_0_0_2_0_1_2_0_1 + 0.342857142857162*G0_0_0_2_0_1_3_1_0 + 0.342857142857162*G0_0_0_2_0_1_3_1_1 - 0.342857142857162*G0_0_0_2_0_1_4_1_0 - 0.342857142857162*G0_0_0_2_0_1_5_1_1 - 0.342857142857162*G0_0_0_3_1_0_0_0_0 - 0.342857142857162*G0_0_0_3_1_0_0_0_1 + 0.342857142857162*G0_0_0_3_1_0_1_0_0 + 0.342857142857162*G0_0_0_3_1_0_2_0_1 - 0.342857142857162*G0_0_0_3_1_0_3_1_0 - 0.342857142857162*G0_0_0_3_1_0_3_1_1 + 0.342857142857162*G0_0_0_3_1_0_4_1_0 + 0.342857142857162*G0_0_0_3_1_0_5_1_1 - 0.342857142857162*G0_0_0_3_1_1_0_0_0 - 0.342857142857162*G0_0_0_3_1_1_0_0_1 + 0.342857142857162*G0_0_0_3_1_1_1_0_0 + 0.342857142857162*G0_0_0_3_1_1_2_0_1 - 0.342857142857162*G0_0_0_3_1_1_3_1_0 - 0.342857142857162*G0_0_0_3_1_1_3_1_1 + 0.342857142857162*G0_0_0_3_1_1_4_1_0 + 0.342857142857162*G0_0_0_3_1_1_5_1_1 + 0.342857142857162*G0_0_0_4_1_0_0_0_0 + 0.342857142857162*G0_0_0_4_1_0_0_0_1 - 0.342857142857162*G0_0_0_4_1_0_1_0_0 - 0.342857142857162*G0_0_0_4_1_0_2_0_1 + 0.342857142857162*G0_0_0_4_1_0_3_1_0 + 0.342857142857162*G0_0_0_4_1_0_3_1_1 - 0.342857142857162*G0_0_0_4_1_0_4_1_0 - 0.342857142857162*G0_0_0_4_1_0_5_1_1 + 0.342857142857162*G0_0_0_5_1_1_0_0_0 + 0.342857142857162*G0_0_0_5_1_1_0_0_1 - 0.342857142857162*G0_0_0_5_1_1_1_0_0 - 0.342857142857162*G0_0_0_5_1_1_2_0_1 + 0.342857142857162*G0_0_0_5_1_1_3_1_0 + 0.342857142857162*G0_0_0_5_1_1_3_1_1 - 0.342857142857162*G0_0_0_5_1_1_4_1_0 - 0.342857142857162*G0_0_0_5_1_1_5_1_1 + 0.342857142857158*G0_1_1_0_0_0_0_0_0 + 0.342857142857158*G0_1_1_0_0_0_0_0_1 - 0.342857142857158*G0_1_1_0_0_0_1_0_0 - 0.342857142857158*G0_1_1_0_0_0_2_0_1 + 0.342857142857158*G0_1_1_0_0_0_3_1_0 + 0.342857142857158*G0_1_1_0_0_0_3_1_1 - 0.342857142857158*G0_1_1_0_0_0_4_1_0 - 0.342857142857158*G0_1_1_0_0_0_5_1_1 + 0.342857142857158*G0_1_1_0_0_1_0_0_0 + 0.342857142857158*G0_1_1_0_0_1_0_0_1 - 0.342857142857158*G0_1_1_0_0_1_1_0_0 - 0.342857142857158*G0_1_1_0_0_1_2_0_1 + 0.342857142857158*G0_1_1_0_0_1_3_1_0 + 0.342857142857158*G0_1_1_0_0_1_3_1_1 - 0.342857142857158*G0_1_1_0_0_1_4_1_0 - 0.342857142857158*G0_1_1_0_0_1_5_1_1 - 0.342857142857158*G0_1_1_1_0_0_0_0_0 - 0.342857142857158*G0_1_1_1_0_0_0_0_1 + 0.342857142857158*G0_1_1_1_0_0_1_0_0 + 0.342857142857158*G0_1_1_1_0_0_2_0_1 - 0.342857142857158*G0_1_1_1_0_0_3_1_0 - 0.342857142857158*G0_1_1_1_0_0_3_1_1 + 0.342857142857158*G0_1_1_1_0_0_4_1_0 + 0.342857142857158*G0_1_1_1_0_0_5_1_1 - 0.342857142857158*G0_1_1_2_0_1_0_0_0 - 0.342857142857158*G0_1_1_2_0_1_0_0_1 + 0.342857142857158*G0_1_1_2_0_1_1_0_0 + 0.342857142857158*G0_1_1_2_0_1_2_0_1 - 0.342857142857158*G0_1_1_2_0_1_3_1_0 - 0.342857142857158*G0_1_1_2_0_1_3_1_1 + 0.342857142857158*G0_1_1_2_0_1_4_1_0 + 0.342857142857158*G0_1_1_2_0_1_5_1_1 + 0.342857142857158*G0_1_1_3_1_0_0_0_0 + 0.342857142857158*G0_1_1_3_1_0_0_0_1 - 0.342857142857158*G0_1_1_3_1_0_1_0_0 - 0.342857142857158*G0_1_1_3_1_0_2_0_1 + 0.342857142857158*G0_1_1_3_1_0_3_1_0 + 0.342857142857158*G0_1_1_3_1_0_3_1_1 - 0.342857142857158*G0_1_1_3_1_0_4_1_0 - 0.342857142857158*G0_1_1_3_1_0_5_1_1 + 0.342857142857158*G0_1_1_3_1_1_0_0_0 + 0.342857142857158*G0_1_1_3_1_1_0_0_1 - 0.342857142857158*G0_1_1_3_1_1_1_0_0 - 0.342857142857158*G0_1_1_3_1_1_2_0_1 + 0.342857142857158*G0_1_1_3_1_1_3_1_0 + 0.342857142857158*G0_1_1_3_1_1_3_1_1 - 0.342857142857158*G0_1_1_3_1_1_4_1_0 - 0.342857142857158*G0_1_1_3_1_1_5_1_1 - 0.342857142857158*G0_1_1_4_1_0_0_0_0 - 0.342857142857158*G0_1_1_4_1_0_0_0_1 + 0.342857142857158*G0_1_1_4_1_0_1_0_0 + 0.342857142857158*G0_1_1_4_1_0_2_0_1 - 0.342857142857158*G0_1_1_4_1_0_3_1_0 - 0.342857142857158*G0_1_1_4_1_0_3_1_1 + 0.342857142857158*G0_1_1_4_1_0_4_1_0 + 0.342857142857158*G0_1_1_4_1_0_5_1_1 - 0.342857142857158*G0_1_1_5_1_1_0_0_0 - 0.342857142857158*G0_1_1_5_1_1_0_0_1 + 0.342857142857158*G0_1_1_5_1_1_1_0_0 + 0.342857142857158*G0_1_1_5_1_1_2_0_1 - 0.342857142857158*G0_1_1_5_1_1_3_1_0 - 0.342857142857158*G0_1_1_5_1_1_3_1_1 + 0.342857142857158*G0_1_1_5_1_1_4_1_0 + 0.342857142857158*G0_1_1_5_1_1_5_1_1; + A[450] = 0.0; + A[406] = 0.0; + A[83] = 0.0; + A[788] = 0.0; + A[11] = A[476]; + A[96] = -A[716] - 0.203174603174611*G0_0_0_0_0_0_0_0_0 - 0.203174603174611*G0_0_0_0_0_0_0_0_1 + 0.203174603174611*G0_0_0_0_0_0_1_0_0 + 0.203174603174611*G0_0_0_0_0_0_2_0_1 - 0.203174603174611*G0_0_0_0_0_0_3_1_0 - 0.203174603174611*G0_0_0_0_0_0_3_1_1 + 0.203174603174611*G0_0_0_0_0_0_4_1_0 + 0.203174603174611*G0_0_0_0_0_0_5_1_1 - 0.203174603174611*G0_0_0_0_0_1_0_0_0 - 0.203174603174611*G0_0_0_0_0_1_0_0_1 + 0.203174603174611*G0_0_0_0_0_1_1_0_0 + 0.203174603174611*G0_0_0_0_0_1_2_0_1 - 0.203174603174611*G0_0_0_0_0_1_3_1_0 - 0.203174603174611*G0_0_0_0_0_1_3_1_1 + 0.203174603174611*G0_0_0_0_0_1_4_1_0 + 0.203174603174611*G0_0_0_0_0_1_5_1_1 + 0.203174603174611*G0_0_0_1_0_0_0_0_0 + 0.203174603174611*G0_0_0_1_0_0_0_0_1 - 0.203174603174611*G0_0_0_1_0_0_1_0_0 - 0.203174603174611*G0_0_0_1_0_0_2_0_1 + 0.203174603174611*G0_0_0_1_0_0_3_1_0 + 0.203174603174611*G0_0_0_1_0_0_3_1_1 - 0.203174603174611*G0_0_0_1_0_0_4_1_0 - 0.203174603174611*G0_0_0_1_0_0_5_1_1 + 0.203174603174611*G0_0_0_2_0_1_0_0_0 + 0.203174603174611*G0_0_0_2_0_1_0_0_1 - 0.203174603174611*G0_0_0_2_0_1_1_0_0 - 0.203174603174611*G0_0_0_2_0_1_2_0_1 + 0.203174603174611*G0_0_0_2_0_1_3_1_0 + 0.203174603174611*G0_0_0_2_0_1_3_1_1 - 0.203174603174611*G0_0_0_2_0_1_4_1_0 - 0.203174603174611*G0_0_0_2_0_1_5_1_1 - 0.203174603174611*G0_0_0_3_1_0_0_0_0 - 0.203174603174611*G0_0_0_3_1_0_0_0_1 + 0.203174603174611*G0_0_0_3_1_0_1_0_0 + 0.203174603174611*G0_0_0_3_1_0_2_0_1 - 0.203174603174611*G0_0_0_3_1_0_3_1_0 - 0.203174603174611*G0_0_0_3_1_0_3_1_1 + 0.203174603174611*G0_0_0_3_1_0_4_1_0 + 0.203174603174611*G0_0_0_3_1_0_5_1_1 - 0.203174603174611*G0_0_0_3_1_1_0_0_0 - 0.203174603174611*G0_0_0_3_1_1_0_0_1 + 0.203174603174611*G0_0_0_3_1_1_1_0_0 + 0.203174603174611*G0_0_0_3_1_1_2_0_1 - 0.203174603174611*G0_0_0_3_1_1_3_1_0 - 0.203174603174611*G0_0_0_3_1_1_3_1_1 + 0.203174603174611*G0_0_0_3_1_1_4_1_0 + 0.203174603174611*G0_0_0_3_1_1_5_1_1 + 0.203174603174611*G0_0_0_4_1_0_0_0_0 + 0.203174603174611*G0_0_0_4_1_0_0_0_1 - 0.203174603174611*G0_0_0_4_1_0_1_0_0 - 0.203174603174611*G0_0_0_4_1_0_2_0_1 + 0.203174603174611*G0_0_0_4_1_0_3_1_0 + 0.203174603174611*G0_0_0_4_1_0_3_1_1 - 0.203174603174611*G0_0_0_4_1_0_4_1_0 - 0.203174603174611*G0_0_0_4_1_0_5_1_1 + 0.203174603174611*G0_0_0_5_1_1_0_0_0 + 0.203174603174611*G0_0_0_5_1_1_0_0_1 - 0.203174603174611*G0_0_0_5_1_1_1_0_0 - 0.203174603174611*G0_0_0_5_1_1_2_0_1 + 0.203174603174611*G0_0_0_5_1_1_3_1_0 + 0.203174603174611*G0_0_0_5_1_1_3_1_1 - 0.203174603174611*G0_0_0_5_1_1_4_1_0 - 0.203174603174611*G0_0_0_5_1_1_5_1_1; + A[815] = 0.0; + A[121] = A[181] - 0.425396825396831*G0_1_0_0_0_0_0_0_0 - 0.425396825396831*G0_1_0_0_0_0_0_0_1 + 0.425396825396831*G0_1_0_0_0_0_1_0_0 + 0.425396825396831*G0_1_0_0_0_0_2_0_1 - 0.425396825396831*G0_1_0_0_0_0_3_1_0 - 0.425396825396831*G0_1_0_0_0_0_3_1_1 + 0.425396825396831*G0_1_0_0_0_0_4_1_0 + 0.425396825396831*G0_1_0_0_0_0_5_1_1 - 0.425396825396831*G0_1_0_0_0_1_0_0_0 - 0.425396825396831*G0_1_0_0_0_1_0_0_1 + 0.425396825396831*G0_1_0_0_0_1_1_0_0 + 0.425396825396831*G0_1_0_0_0_1_2_0_1 - 0.425396825396831*G0_1_0_0_0_1_3_1_0 - 0.425396825396831*G0_1_0_0_0_1_3_1_1 + 0.425396825396831*G0_1_0_0_0_1_4_1_0 + 0.425396825396831*G0_1_0_0_0_1_5_1_1 + 0.425396825396831*G0_1_0_1_0_0_0_0_0 + 0.425396825396831*G0_1_0_1_0_0_0_0_1 - 0.425396825396831*G0_1_0_1_0_0_1_0_0 - 0.425396825396831*G0_1_0_1_0_0_2_0_1 + 0.425396825396831*G0_1_0_1_0_0_3_1_0 + 0.425396825396831*G0_1_0_1_0_0_3_1_1 - 0.425396825396831*G0_1_0_1_0_0_4_1_0 - 0.425396825396831*G0_1_0_1_0_0_5_1_1 + 0.425396825396831*G0_1_0_2_0_1_0_0_0 + 0.425396825396831*G0_1_0_2_0_1_0_0_1 - 0.425396825396831*G0_1_0_2_0_1_1_0_0 - 0.425396825396831*G0_1_0_2_0_1_2_0_1 + 0.425396825396831*G0_1_0_2_0_1_3_1_0 + 0.425396825396831*G0_1_0_2_0_1_3_1_1 - 0.425396825396831*G0_1_0_2_0_1_4_1_0 - 0.425396825396831*G0_1_0_2_0_1_5_1_1 - 0.425396825396831*G0_1_0_3_1_0_0_0_0 - 0.425396825396831*G0_1_0_3_1_0_0_0_1 + 0.425396825396831*G0_1_0_3_1_0_1_0_0 + 0.425396825396831*G0_1_0_3_1_0_2_0_1 - 0.425396825396831*G0_1_0_3_1_0_3_1_0 - 0.425396825396831*G0_1_0_3_1_0_3_1_1 + 0.425396825396831*G0_1_0_3_1_0_4_1_0 + 0.425396825396831*G0_1_0_3_1_0_5_1_1 - 0.425396825396831*G0_1_0_3_1_1_0_0_0 - 0.425396825396831*G0_1_0_3_1_1_0_0_1 + 0.425396825396831*G0_1_0_3_1_1_1_0_0 + 0.425396825396831*G0_1_0_3_1_1_2_0_1 - 0.425396825396831*G0_1_0_3_1_1_3_1_0 - 0.425396825396831*G0_1_0_3_1_1_3_1_1 + 0.425396825396831*G0_1_0_3_1_1_4_1_0 + 0.425396825396831*G0_1_0_3_1_1_5_1_1 + 0.425396825396831*G0_1_0_4_1_0_0_0_0 + 0.425396825396831*G0_1_0_4_1_0_0_0_1 - 0.425396825396831*G0_1_0_4_1_0_1_0_0 - 0.425396825396831*G0_1_0_4_1_0_2_0_1 + 0.425396825396831*G0_1_0_4_1_0_3_1_0 + 0.425396825396831*G0_1_0_4_1_0_3_1_1 - 0.425396825396831*G0_1_0_4_1_0_4_1_0 - 0.425396825396831*G0_1_0_4_1_0_5_1_1 + 0.425396825396831*G0_1_0_5_1_1_0_0_0 + 0.425396825396831*G0_1_0_5_1_1_0_0_1 - 0.425396825396831*G0_1_0_5_1_1_1_0_0 - 0.425396825396831*G0_1_0_5_1_1_2_0_1 + 0.425396825396831*G0_1_0_5_1_1_3_1_0 + 0.425396825396831*G0_1_0_5_1_1_3_1_1 - 0.425396825396831*G0_1_0_5_1_1_4_1_0 - 0.425396825396831*G0_1_0_5_1_1_5_1_1; + A[766] = -A[121] + 0.510052910052917*G0_0_0_0_0_0_0_0_0 + 0.510052910052917*G0_0_0_0_0_0_0_0_1 - 0.510052910052917*G0_0_0_0_0_0_1_0_0 - 0.510052910052917*G0_0_0_0_0_0_2_0_1 + 0.510052910052917*G0_0_0_0_0_0_3_1_0 + 0.510052910052917*G0_0_0_0_0_0_3_1_1 - 0.510052910052917*G0_0_0_0_0_0_4_1_0 - 0.510052910052917*G0_0_0_0_0_0_5_1_1 + 0.510052910052917*G0_0_0_0_0_1_0_0_0 + 0.510052910052917*G0_0_0_0_0_1_0_0_1 - 0.510052910052917*G0_0_0_0_0_1_1_0_0 - 0.510052910052917*G0_0_0_0_0_1_2_0_1 + 0.510052910052917*G0_0_0_0_0_1_3_1_0 + 0.510052910052917*G0_0_0_0_0_1_3_1_1 - 0.510052910052917*G0_0_0_0_0_1_4_1_0 - 0.510052910052917*G0_0_0_0_0_1_5_1_1 - 0.510052910052917*G0_0_0_1_0_0_0_0_0 - 0.510052910052917*G0_0_0_1_0_0_0_0_1 + 0.510052910052917*G0_0_0_1_0_0_1_0_0 + 0.510052910052917*G0_0_0_1_0_0_2_0_1 - 0.510052910052917*G0_0_0_1_0_0_3_1_0 - 0.510052910052917*G0_0_0_1_0_0_3_1_1 + 0.510052910052917*G0_0_0_1_0_0_4_1_0 + 0.510052910052917*G0_0_0_1_0_0_5_1_1 - 0.510052910052917*G0_0_0_2_0_1_0_0_0 - 0.510052910052917*G0_0_0_2_0_1_0_0_1 + 0.510052910052917*G0_0_0_2_0_1_1_0_0 + 0.510052910052917*G0_0_0_2_0_1_2_0_1 - 0.510052910052917*G0_0_0_2_0_1_3_1_0 - 0.510052910052917*G0_0_0_2_0_1_3_1_1 + 0.510052910052917*G0_0_0_2_0_1_4_1_0 + 0.510052910052917*G0_0_0_2_0_1_5_1_1 + 0.510052910052917*G0_0_0_3_1_0_0_0_0 + 0.510052910052917*G0_0_0_3_1_0_0_0_1 - 0.510052910052917*G0_0_0_3_1_0_1_0_0 - 0.510052910052917*G0_0_0_3_1_0_2_0_1 + 0.510052910052917*G0_0_0_3_1_0_3_1_0 + 0.510052910052917*G0_0_0_3_1_0_3_1_1 - 0.510052910052917*G0_0_0_3_1_0_4_1_0 - 0.510052910052917*G0_0_0_3_1_0_5_1_1 + 0.510052910052917*G0_0_0_3_1_1_0_0_0 + 0.510052910052917*G0_0_0_3_1_1_0_0_1 - 0.510052910052917*G0_0_0_3_1_1_1_0_0 - 0.510052910052917*G0_0_0_3_1_1_2_0_1 + 0.510052910052917*G0_0_0_3_1_1_3_1_0 + 0.510052910052917*G0_0_0_3_1_1_3_1_1 - 0.510052910052917*G0_0_0_3_1_1_4_1_0 - 0.510052910052917*G0_0_0_3_1_1_5_1_1 - 0.510052910052917*G0_0_0_4_1_0_0_0_0 - 0.510052910052917*G0_0_0_4_1_0_0_0_1 + 0.510052910052917*G0_0_0_4_1_0_1_0_0 + 0.510052910052917*G0_0_0_4_1_0_2_0_1 - 0.510052910052917*G0_0_0_4_1_0_3_1_0 - 0.510052910052917*G0_0_0_4_1_0_3_1_1 + 0.510052910052917*G0_0_0_4_1_0_4_1_0 + 0.510052910052917*G0_0_0_4_1_0_5_1_1 - 0.510052910052917*G0_0_0_5_1_1_0_0_0 - 0.510052910052917*G0_0_0_5_1_1_0_0_1 + 0.510052910052917*G0_0_0_5_1_1_1_0_0 + 0.510052910052917*G0_0_0_5_1_1_2_0_1 - 0.510052910052917*G0_0_0_5_1_1_3_1_0 - 0.510052910052917*G0_0_0_5_1_1_3_1_1 + 0.510052910052917*G0_0_0_5_1_1_4_1_0 + 0.510052910052917*G0_0_0_5_1_1_5_1_1; + A[846] = 0.0; + A[154] = -A[709] + 1.11746031746032*G0_1_0_0_0_0_0_0_0 + 1.11746031746032*G0_1_0_0_0_0_0_0_1 - 1.11746031746032*G0_1_0_0_0_0_1_0_0 - 1.11746031746032*G0_1_0_0_0_0_2_0_1 + 1.11746031746032*G0_1_0_0_0_0_3_1_0 + 1.11746031746032*G0_1_0_0_0_0_3_1_1 - 1.11746031746032*G0_1_0_0_0_0_4_1_0 - 1.11746031746032*G0_1_0_0_0_0_5_1_1 + 1.11746031746032*G0_1_0_0_0_1_0_0_0 + 1.11746031746032*G0_1_0_0_0_1_0_0_1 - 1.11746031746032*G0_1_0_0_0_1_1_0_0 - 1.11746031746032*G0_1_0_0_0_1_2_0_1 + 1.11746031746032*G0_1_0_0_0_1_3_1_0 + 1.11746031746032*G0_1_0_0_0_1_3_1_1 - 1.11746031746032*G0_1_0_0_0_1_4_1_0 - 1.11746031746032*G0_1_0_0_0_1_5_1_1 - 1.11746031746032*G0_1_0_1_0_0_0_0_0 - 1.11746031746032*G0_1_0_1_0_0_0_0_1 + 1.11746031746032*G0_1_0_1_0_0_1_0_0 + 1.11746031746032*G0_1_0_1_0_0_2_0_1 - 1.11746031746032*G0_1_0_1_0_0_3_1_0 - 1.11746031746032*G0_1_0_1_0_0_3_1_1 + 1.11746031746032*G0_1_0_1_0_0_4_1_0 + 1.11746031746032*G0_1_0_1_0_0_5_1_1 - 1.11746031746032*G0_1_0_2_0_1_0_0_0 - 1.11746031746032*G0_1_0_2_0_1_0_0_1 + 1.11746031746032*G0_1_0_2_0_1_1_0_0 + 1.11746031746032*G0_1_0_2_0_1_2_0_1 - 1.11746031746032*G0_1_0_2_0_1_3_1_0 - 1.11746031746032*G0_1_0_2_0_1_3_1_1 + 1.11746031746032*G0_1_0_2_0_1_4_1_0 + 1.11746031746032*G0_1_0_2_0_1_5_1_1 + 1.11746031746032*G0_1_0_3_1_0_0_0_0 + 1.11746031746032*G0_1_0_3_1_0_0_0_1 - 1.11746031746032*G0_1_0_3_1_0_1_0_0 - 1.11746031746032*G0_1_0_3_1_0_2_0_1 + 1.11746031746032*G0_1_0_3_1_0_3_1_0 + 1.11746031746032*G0_1_0_3_1_0_3_1_1 - 1.11746031746032*G0_1_0_3_1_0_4_1_0 - 1.11746031746032*G0_1_0_3_1_0_5_1_1 + 1.11746031746032*G0_1_0_3_1_1_0_0_0 + 1.11746031746032*G0_1_0_3_1_1_0_0_1 - 1.11746031746032*G0_1_0_3_1_1_1_0_0 - 1.11746031746032*G0_1_0_3_1_1_2_0_1 + 1.11746031746032*G0_1_0_3_1_1_3_1_0 + 1.11746031746032*G0_1_0_3_1_1_3_1_1 - 1.11746031746032*G0_1_0_3_1_1_4_1_0 - 1.11746031746032*G0_1_0_3_1_1_5_1_1 - 1.11746031746032*G0_1_0_4_1_0_0_0_0 - 1.11746031746032*G0_1_0_4_1_0_0_0_1 + 1.11746031746032*G0_1_0_4_1_0_1_0_0 + 1.11746031746032*G0_1_0_4_1_0_2_0_1 - 1.11746031746032*G0_1_0_4_1_0_3_1_0 - 1.11746031746032*G0_1_0_4_1_0_3_1_1 + 1.11746031746032*G0_1_0_4_1_0_4_1_0 + 1.11746031746032*G0_1_0_4_1_0_5_1_1 - 1.11746031746032*G0_1_0_5_1_1_0_0_0 - 1.11746031746032*G0_1_0_5_1_1_0_0_1 + 1.11746031746032*G0_1_0_5_1_1_1_0_0 + 1.11746031746032*G0_1_0_5_1_1_2_0_1 - 1.11746031746032*G0_1_0_5_1_1_3_1_0 - 1.11746031746032*G0_1_0_5_1_1_3_1_1 + 1.11746031746032*G0_1_0_5_1_1_4_1_0 + 1.11746031746032*G0_1_0_5_1_1_5_1_1 - 0.728042328042336*G0_1_1_0_0_0_0_0_0 - 0.728042328042336*G0_1_1_0_0_0_0_0_1 + 0.728042328042336*G0_1_1_0_0_0_1_0_0 + 0.728042328042336*G0_1_1_0_0_0_2_0_1 - 0.728042328042336*G0_1_1_0_0_0_3_1_0 - 0.728042328042336*G0_1_1_0_0_0_3_1_1 + 0.728042328042336*G0_1_1_0_0_0_4_1_0 + 0.728042328042336*G0_1_1_0_0_0_5_1_1 - 0.728042328042336*G0_1_1_0_0_1_0_0_0 - 0.728042328042336*G0_1_1_0_0_1_0_0_1 + 0.728042328042336*G0_1_1_0_0_1_1_0_0 + 0.728042328042336*G0_1_1_0_0_1_2_0_1 - 0.728042328042336*G0_1_1_0_0_1_3_1_0 - 0.728042328042336*G0_1_1_0_0_1_3_1_1 + 0.728042328042336*G0_1_1_0_0_1_4_1_0 + 0.728042328042336*G0_1_1_0_0_1_5_1_1 + 0.728042328042336*G0_1_1_1_0_0_0_0_0 + 0.728042328042336*G0_1_1_1_0_0_0_0_1 - 0.728042328042336*G0_1_1_1_0_0_1_0_0 - 0.728042328042336*G0_1_1_1_0_0_2_0_1 + 0.728042328042336*G0_1_1_1_0_0_3_1_0 + 0.728042328042336*G0_1_1_1_0_0_3_1_1 - 0.728042328042336*G0_1_1_1_0_0_4_1_0 - 0.728042328042336*G0_1_1_1_0_0_5_1_1 + 0.728042328042336*G0_1_1_2_0_1_0_0_0 + 0.728042328042336*G0_1_1_2_0_1_0_0_1 - 0.728042328042336*G0_1_1_2_0_1_1_0_0 - 0.728042328042336*G0_1_1_2_0_1_2_0_1 + 0.728042328042336*G0_1_1_2_0_1_3_1_0 + 0.728042328042336*G0_1_1_2_0_1_3_1_1 - 0.728042328042336*G0_1_1_2_0_1_4_1_0 - 0.728042328042336*G0_1_1_2_0_1_5_1_1 - 0.728042328042336*G0_1_1_3_1_0_0_0_0 - 0.728042328042336*G0_1_1_3_1_0_0_0_1 + 0.728042328042336*G0_1_1_3_1_0_1_0_0 + 0.728042328042336*G0_1_1_3_1_0_2_0_1 - 0.728042328042336*G0_1_1_3_1_0_3_1_0 - 0.728042328042336*G0_1_1_3_1_0_3_1_1 + 0.728042328042336*G0_1_1_3_1_0_4_1_0 + 0.728042328042336*G0_1_1_3_1_0_5_1_1 - 0.728042328042336*G0_1_1_3_1_1_0_0_0 - 0.728042328042336*G0_1_1_3_1_1_0_0_1 + 0.728042328042336*G0_1_1_3_1_1_1_0_0 + 0.728042328042336*G0_1_1_3_1_1_2_0_1 - 0.728042328042336*G0_1_1_3_1_1_3_1_0 - 0.728042328042336*G0_1_1_3_1_1_3_1_1 + 0.728042328042336*G0_1_1_3_1_1_4_1_0 + 0.728042328042336*G0_1_1_3_1_1_5_1_1 + 0.728042328042336*G0_1_1_4_1_0_0_0_0 + 0.728042328042336*G0_1_1_4_1_0_0_0_1 - 0.728042328042336*G0_1_1_4_1_0_1_0_0 - 0.728042328042336*G0_1_1_4_1_0_2_0_1 + 0.728042328042336*G0_1_1_4_1_0_3_1_0 + 0.728042328042336*G0_1_1_4_1_0_3_1_1 - 0.728042328042336*G0_1_1_4_1_0_4_1_0 - 0.728042328042336*G0_1_1_4_1_0_5_1_1 + 0.728042328042336*G0_1_1_5_1_1_0_0_0 + 0.728042328042336*G0_1_1_5_1_1_0_0_1 - 0.728042328042336*G0_1_1_5_1_1_1_0_0 - 0.728042328042336*G0_1_1_5_1_1_2_0_1 + 0.728042328042336*G0_1_1_5_1_1_3_1_0 + 0.728042328042336*G0_1_1_5_1_1_3_1_1 - 0.728042328042336*G0_1_1_5_1_1_4_1_0 - 0.728042328042336*G0_1_1_5_1_1_5_1_1; + A[877] = 0.0; + A[484] = 0.0; + A[191] = A[656]; + A[587] = A[534] - 0.425396825396829*G0_0_1_0_0_0_0_0_0 - 0.425396825396829*G0_0_1_0_0_0_0_0_1 + 0.425396825396829*G0_0_1_0_0_0_1_0_0 + 0.425396825396829*G0_0_1_0_0_0_2_0_1 - 0.425396825396829*G0_0_1_0_0_0_3_1_0 - 0.425396825396829*G0_0_1_0_0_0_3_1_1 + 0.425396825396829*G0_0_1_0_0_0_4_1_0 + 0.425396825396829*G0_0_1_0_0_0_5_1_1 - 0.425396825396829*G0_0_1_0_0_1_0_0_0 - 0.425396825396829*G0_0_1_0_0_1_0_0_1 + 0.425396825396829*G0_0_1_0_0_1_1_0_0 + 0.425396825396829*G0_0_1_0_0_1_2_0_1 - 0.425396825396829*G0_0_1_0_0_1_3_1_0 - 0.425396825396829*G0_0_1_0_0_1_3_1_1 + 0.425396825396829*G0_0_1_0_0_1_4_1_0 + 0.425396825396829*G0_0_1_0_0_1_5_1_1 + 0.425396825396829*G0_0_1_1_0_0_0_0_0 + 0.425396825396829*G0_0_1_1_0_0_0_0_1 - 0.425396825396829*G0_0_1_1_0_0_1_0_0 - 0.425396825396829*G0_0_1_1_0_0_2_0_1 + 0.425396825396829*G0_0_1_1_0_0_3_1_0 + 0.425396825396829*G0_0_1_1_0_0_3_1_1 - 0.425396825396829*G0_0_1_1_0_0_4_1_0 - 0.425396825396829*G0_0_1_1_0_0_5_1_1 + 0.425396825396829*G0_0_1_2_0_1_0_0_0 + 0.425396825396829*G0_0_1_2_0_1_0_0_1 - 0.425396825396829*G0_0_1_2_0_1_1_0_0 - 0.425396825396829*G0_0_1_2_0_1_2_0_1 + 0.425396825396829*G0_0_1_2_0_1_3_1_0 + 0.425396825396829*G0_0_1_2_0_1_3_1_1 - 0.425396825396829*G0_0_1_2_0_1_4_1_0 - 0.425396825396829*G0_0_1_2_0_1_5_1_1 - 0.425396825396829*G0_0_1_3_1_0_0_0_0 - 0.425396825396829*G0_0_1_3_1_0_0_0_1 + 0.425396825396829*G0_0_1_3_1_0_1_0_0 + 0.425396825396829*G0_0_1_3_1_0_2_0_1 - 0.425396825396829*G0_0_1_3_1_0_3_1_0 - 0.425396825396829*G0_0_1_3_1_0_3_1_1 + 0.425396825396829*G0_0_1_3_1_0_4_1_0 + 0.425396825396829*G0_0_1_3_1_0_5_1_1 - 0.425396825396829*G0_0_1_3_1_1_0_0_0 - 0.425396825396829*G0_0_1_3_1_1_0_0_1 + 0.425396825396829*G0_0_1_3_1_1_1_0_0 + 0.425396825396829*G0_0_1_3_1_1_2_0_1 - 0.425396825396829*G0_0_1_3_1_1_3_1_0 - 0.425396825396829*G0_0_1_3_1_1_3_1_1 + 0.425396825396829*G0_0_1_3_1_1_4_1_0 + 0.425396825396829*G0_0_1_3_1_1_5_1_1 + 0.425396825396829*G0_0_1_4_1_0_0_0_0 + 0.425396825396829*G0_0_1_4_1_0_0_0_1 - 0.425396825396829*G0_0_1_4_1_0_1_0_0 - 0.425396825396829*G0_0_1_4_1_0_2_0_1 + 0.425396825396829*G0_0_1_4_1_0_3_1_0 + 0.425396825396829*G0_0_1_4_1_0_3_1_1 - 0.425396825396829*G0_0_1_4_1_0_4_1_0 - 0.425396825396829*G0_0_1_4_1_0_5_1_1 + 0.425396825396829*G0_0_1_5_1_1_0_0_0 + 0.425396825396829*G0_0_1_5_1_1_0_0_1 - 0.425396825396829*G0_0_1_5_1_1_1_0_0 - 0.425396825396829*G0_0_1_5_1_1_2_0_1 + 0.425396825396829*G0_0_1_5_1_1_3_1_0 + 0.425396825396829*G0_0_1_5_1_1_3_1_1 - 0.425396825396829*G0_0_1_5_1_1_4_1_0 - 0.425396825396829*G0_0_1_5_1_1_5_1_1; + A[677] = -A[587] + 0.510052910052918*G0_1_1_0_0_0_0_0_0 + 0.510052910052918*G0_1_1_0_0_0_0_0_1 - 0.510052910052918*G0_1_1_0_0_0_1_0_0 - 0.510052910052918*G0_1_1_0_0_0_2_0_1 + 0.510052910052918*G0_1_1_0_0_0_3_1_0 + 0.510052910052918*G0_1_1_0_0_0_3_1_1 - 0.510052910052918*G0_1_1_0_0_0_4_1_0 - 0.510052910052918*G0_1_1_0_0_0_5_1_1 + 0.510052910052918*G0_1_1_0_0_1_0_0_0 + 0.510052910052918*G0_1_1_0_0_1_0_0_1 - 0.510052910052918*G0_1_1_0_0_1_1_0_0 - 0.510052910052918*G0_1_1_0_0_1_2_0_1 + 0.510052910052918*G0_1_1_0_0_1_3_1_0 + 0.510052910052918*G0_1_1_0_0_1_3_1_1 - 0.510052910052918*G0_1_1_0_0_1_4_1_0 - 0.510052910052918*G0_1_1_0_0_1_5_1_1 - 0.510052910052918*G0_1_1_1_0_0_0_0_0 - 0.510052910052918*G0_1_1_1_0_0_0_0_1 + 0.510052910052918*G0_1_1_1_0_0_1_0_0 + 0.510052910052918*G0_1_1_1_0_0_2_0_1 - 0.510052910052918*G0_1_1_1_0_0_3_1_0 - 0.510052910052918*G0_1_1_1_0_0_3_1_1 + 0.510052910052918*G0_1_1_1_0_0_4_1_0 + 0.510052910052918*G0_1_1_1_0_0_5_1_1 - 0.510052910052918*G0_1_1_2_0_1_0_0_0 - 0.510052910052918*G0_1_1_2_0_1_0_0_1 + 0.510052910052918*G0_1_1_2_0_1_1_0_0 + 0.510052910052918*G0_1_1_2_0_1_2_0_1 - 0.510052910052918*G0_1_1_2_0_1_3_1_0 - 0.510052910052918*G0_1_1_2_0_1_3_1_1 + 0.510052910052918*G0_1_1_2_0_1_4_1_0 + 0.510052910052918*G0_1_1_2_0_1_5_1_1 + 0.510052910052918*G0_1_1_3_1_0_0_0_0 + 0.510052910052918*G0_1_1_3_1_0_0_0_1 - 0.510052910052918*G0_1_1_3_1_0_1_0_0 - 0.510052910052918*G0_1_1_3_1_0_2_0_1 + 0.510052910052918*G0_1_1_3_1_0_3_1_0 + 0.510052910052918*G0_1_1_3_1_0_3_1_1 - 0.510052910052918*G0_1_1_3_1_0_4_1_0 - 0.510052910052918*G0_1_1_3_1_0_5_1_1 + 0.510052910052918*G0_1_1_3_1_1_0_0_0 + 0.510052910052918*G0_1_1_3_1_1_0_0_1 - 0.510052910052918*G0_1_1_3_1_1_1_0_0 - 0.510052910052918*G0_1_1_3_1_1_2_0_1 + 0.510052910052918*G0_1_1_3_1_1_3_1_0 + 0.510052910052918*G0_1_1_3_1_1_3_1_1 - 0.510052910052918*G0_1_1_3_1_1_4_1_0 - 0.510052910052918*G0_1_1_3_1_1_5_1_1 - 0.510052910052918*G0_1_1_4_1_0_0_0_0 - 0.510052910052918*G0_1_1_4_1_0_0_0_1 + 0.510052910052918*G0_1_1_4_1_0_1_0_0 + 0.510052910052918*G0_1_1_4_1_0_2_0_1 - 0.510052910052918*G0_1_1_4_1_0_3_1_0 - 0.510052910052918*G0_1_1_4_1_0_3_1_1 + 0.510052910052918*G0_1_1_4_1_0_4_1_0 + 0.510052910052918*G0_1_1_4_1_0_5_1_1 - 0.510052910052918*G0_1_1_5_1_1_0_0_0 - 0.510052910052918*G0_1_1_5_1_1_0_0_1 + 0.510052910052918*G0_1_1_5_1_1_1_0_0 + 0.510052910052918*G0_1_1_5_1_1_2_0_1 - 0.510052910052918*G0_1_1_5_1_1_3_1_0 - 0.510052910052918*G0_1_1_5_1_1_3_1_1 + 0.510052910052918*G0_1_1_5_1_1_4_1_0 + 0.510052910052918*G0_1_1_5_1_1_5_1_1; + A[511] = 0.0; + A[228] = 0.0; + A[610] = 0.0; + A[546] = 0.0; + A[506] = -0.651851851851859*G0_0_0_0_0_0_0_0_0 - 0.651851851851859*G0_0_0_0_0_0_0_0_1 + 0.651851851851859*G0_0_0_0_0_0_1_0_0 + 0.651851851851859*G0_0_0_0_0_0_2_0_1 - 0.651851851851859*G0_0_0_0_0_0_3_1_0 - 0.651851851851859*G0_0_0_0_0_0_3_1_1 + 0.651851851851859*G0_0_0_0_0_0_4_1_0 + 0.651851851851859*G0_0_0_0_0_0_5_1_1 - 0.651851851851859*G0_0_0_0_0_1_0_0_0 - 0.651851851851859*G0_0_0_0_0_1_0_0_1 + 0.651851851851859*G0_0_0_0_0_1_1_0_0 + 0.651851851851859*G0_0_0_0_0_1_2_0_1 - 0.651851851851859*G0_0_0_0_0_1_3_1_0 - 0.651851851851859*G0_0_0_0_0_1_3_1_1 + 0.651851851851859*G0_0_0_0_0_1_4_1_0 + 0.651851851851859*G0_0_0_0_0_1_5_1_1 + 0.651851851851859*G0_0_0_1_0_0_0_0_0 + 0.651851851851859*G0_0_0_1_0_0_0_0_1 - 0.651851851851859*G0_0_0_1_0_0_1_0_0 - 0.651851851851859*G0_0_0_1_0_0_2_0_1 + 0.651851851851859*G0_0_0_1_0_0_3_1_0 + 0.651851851851859*G0_0_0_1_0_0_3_1_1 - 0.651851851851859*G0_0_0_1_0_0_4_1_0 - 0.651851851851859*G0_0_0_1_0_0_5_1_1 + 0.651851851851859*G0_0_0_2_0_1_0_0_0 + 0.651851851851859*G0_0_0_2_0_1_0_0_1 - 0.651851851851859*G0_0_0_2_0_1_1_0_0 - 0.651851851851859*G0_0_0_2_0_1_2_0_1 + 0.651851851851859*G0_0_0_2_0_1_3_1_0 + 0.651851851851859*G0_0_0_2_0_1_3_1_1 - 0.651851851851859*G0_0_0_2_0_1_4_1_0 - 0.651851851851859*G0_0_0_2_0_1_5_1_1 - 0.651851851851859*G0_0_0_3_1_0_0_0_0 - 0.651851851851859*G0_0_0_3_1_0_0_0_1 + 0.651851851851859*G0_0_0_3_1_0_1_0_0 + 0.651851851851859*G0_0_0_3_1_0_2_0_1 - 0.651851851851859*G0_0_0_3_1_0_3_1_0 - 0.651851851851859*G0_0_0_3_1_0_3_1_1 + 0.651851851851859*G0_0_0_3_1_0_4_1_0 + 0.651851851851859*G0_0_0_3_1_0_5_1_1 - 0.651851851851859*G0_0_0_3_1_1_0_0_0 - 0.651851851851859*G0_0_0_3_1_1_0_0_1 + 0.651851851851859*G0_0_0_3_1_1_1_0_0 + 0.651851851851859*G0_0_0_3_1_1_2_0_1 - 0.651851851851859*G0_0_0_3_1_1_3_1_0 - 0.651851851851859*G0_0_0_3_1_1_3_1_1 + 0.651851851851859*G0_0_0_3_1_1_4_1_0 + 0.651851851851859*G0_0_0_3_1_1_5_1_1 + 0.651851851851859*G0_0_0_4_1_0_0_0_0 + 0.651851851851859*G0_0_0_4_1_0_0_0_1 - 0.651851851851859*G0_0_0_4_1_0_1_0_0 - 0.651851851851859*G0_0_0_4_1_0_2_0_1 + 0.651851851851859*G0_0_0_4_1_0_3_1_0 + 0.651851851851859*G0_0_0_4_1_0_3_1_1 - 0.651851851851859*G0_0_0_4_1_0_4_1_0 - 0.651851851851859*G0_0_0_4_1_0_5_1_1 + 0.651851851851859*G0_0_0_5_1_1_0_0_0 + 0.651851851851859*G0_0_0_5_1_1_0_0_1 - 0.651851851851859*G0_0_0_5_1_1_1_0_0 - 0.651851851851859*G0_0_0_5_1_1_2_0_1 + 0.651851851851859*G0_0_0_5_1_1_3_1_0 + 0.651851851851859*G0_0_0_5_1_1_3_1_1 - 0.651851851851859*G0_0_0_5_1_1_4_1_0 - 0.651851851851859*G0_0_0_5_1_1_5_1_1 - 0.778835978835987*G0_0_1_0_0_0_0_0_0 - 0.778835978835987*G0_0_1_0_0_0_0_0_1 + 0.778835978835987*G0_0_1_0_0_0_1_0_0 + 0.778835978835987*G0_0_1_0_0_0_2_0_1 - 0.778835978835987*G0_0_1_0_0_0_3_1_0 - 0.778835978835987*G0_0_1_0_0_0_3_1_1 + 0.778835978835987*G0_0_1_0_0_0_4_1_0 + 0.778835978835987*G0_0_1_0_0_0_5_1_1 - 0.778835978835987*G0_0_1_0_0_1_0_0_0 - 0.778835978835987*G0_0_1_0_0_1_0_0_1 + 0.778835978835987*G0_0_1_0_0_1_1_0_0 + 0.778835978835987*G0_0_1_0_0_1_2_0_1 - 0.778835978835987*G0_0_1_0_0_1_3_1_0 - 0.778835978835987*G0_0_1_0_0_1_3_1_1 + 0.778835978835987*G0_0_1_0_0_1_4_1_0 + 0.778835978835987*G0_0_1_0_0_1_5_1_1 + 0.778835978835987*G0_0_1_1_0_0_0_0_0 + 0.778835978835987*G0_0_1_1_0_0_0_0_1 - 0.778835978835987*G0_0_1_1_0_0_1_0_0 - 0.778835978835987*G0_0_1_1_0_0_2_0_1 + 0.778835978835987*G0_0_1_1_0_0_3_1_0 + 0.778835978835987*G0_0_1_1_0_0_3_1_1 - 0.778835978835987*G0_0_1_1_0_0_4_1_0 - 0.778835978835987*G0_0_1_1_0_0_5_1_1 + 0.778835978835987*G0_0_1_2_0_1_0_0_0 + 0.778835978835987*G0_0_1_2_0_1_0_0_1 - 0.778835978835987*G0_0_1_2_0_1_1_0_0 - 0.778835978835987*G0_0_1_2_0_1_2_0_1 + 0.778835978835987*G0_0_1_2_0_1_3_1_0 + 0.778835978835987*G0_0_1_2_0_1_3_1_1 - 0.778835978835987*G0_0_1_2_0_1_4_1_0 - 0.778835978835987*G0_0_1_2_0_1_5_1_1 - 0.778835978835987*G0_0_1_3_1_0_0_0_0 - 0.778835978835987*G0_0_1_3_1_0_0_0_1 + 0.778835978835987*G0_0_1_3_1_0_1_0_0 + 0.778835978835987*G0_0_1_3_1_0_2_0_1 - 0.778835978835987*G0_0_1_3_1_0_3_1_0 - 0.778835978835987*G0_0_1_3_1_0_3_1_1 + 0.778835978835987*G0_0_1_3_1_0_4_1_0 + 0.778835978835987*G0_0_1_3_1_0_5_1_1 - 0.778835978835987*G0_0_1_3_1_1_0_0_0 - 0.778835978835987*G0_0_1_3_1_1_0_0_1 + 0.778835978835987*G0_0_1_3_1_1_1_0_0 + 0.778835978835987*G0_0_1_3_1_1_2_0_1 - 0.778835978835987*G0_0_1_3_1_1_3_1_0 - 0.778835978835987*G0_0_1_3_1_1_3_1_1 + 0.778835978835987*G0_0_1_3_1_1_4_1_0 + 0.778835978835987*G0_0_1_3_1_1_5_1_1 + 0.778835978835987*G0_0_1_4_1_0_0_0_0 + 0.778835978835987*G0_0_1_4_1_0_0_0_1 - 0.778835978835987*G0_0_1_4_1_0_1_0_0 - 0.778835978835987*G0_0_1_4_1_0_2_0_1 + 0.778835978835987*G0_0_1_4_1_0_3_1_0 + 0.778835978835987*G0_0_1_4_1_0_3_1_1 - 0.778835978835987*G0_0_1_4_1_0_4_1_0 - 0.778835978835987*G0_0_1_4_1_0_5_1_1 + 0.778835978835987*G0_0_1_5_1_1_0_0_0 + 0.778835978835987*G0_0_1_5_1_1_0_0_1 - 0.778835978835987*G0_0_1_5_1_1_1_0_0 - 0.778835978835987*G0_0_1_5_1_1_2_0_1 + 0.778835978835987*G0_0_1_5_1_1_3_1_0 + 0.778835978835987*G0_0_1_5_1_1_3_1_1 - 0.778835978835987*G0_0_1_5_1_1_4_1_0 - 0.778835978835987*G0_0_1_5_1_1_5_1_1; + A[641] = 0.0; + A[537] = A[887]; + A[660] = 0.0; + A[283] = A[748]; + A[695] = 0.0; + A[310] = A[775]; + A[262] = 0.0; + A[333] = A[101]; + A[293] = 0.0; + A[745] = A[309] + 1.11746031746033*G0_0_1_0_0_0_0_0_0 + 1.11746031746033*G0_0_1_0_0_0_0_0_1 - 1.11746031746033*G0_0_1_0_0_0_1_0_0 - 1.11746031746033*G0_0_1_0_0_0_2_0_1 + 1.11746031746033*G0_0_1_0_0_0_3_1_0 + 1.11746031746033*G0_0_1_0_0_0_3_1_1 - 1.11746031746033*G0_0_1_0_0_0_4_1_0 - 1.11746031746033*G0_0_1_0_0_0_5_1_1 + 1.11746031746033*G0_0_1_0_0_1_0_0_0 + 1.11746031746033*G0_0_1_0_0_1_0_0_1 - 1.11746031746033*G0_0_1_0_0_1_1_0_0 - 1.11746031746033*G0_0_1_0_0_1_2_0_1 + 1.11746031746033*G0_0_1_0_0_1_3_1_0 + 1.11746031746033*G0_0_1_0_0_1_3_1_1 - 1.11746031746033*G0_0_1_0_0_1_4_1_0 - 1.11746031746033*G0_0_1_0_0_1_5_1_1 - 1.11746031746033*G0_0_1_1_0_0_0_0_0 - 1.11746031746033*G0_0_1_1_0_0_0_0_1 + 1.11746031746033*G0_0_1_1_0_0_1_0_0 + 1.11746031746033*G0_0_1_1_0_0_2_0_1 - 1.11746031746033*G0_0_1_1_0_0_3_1_0 - 1.11746031746033*G0_0_1_1_0_0_3_1_1 + 1.11746031746033*G0_0_1_1_0_0_4_1_0 + 1.11746031746033*G0_0_1_1_0_0_5_1_1 - 1.11746031746033*G0_0_1_2_0_1_0_0_0 - 1.11746031746033*G0_0_1_2_0_1_0_0_1 + 1.11746031746033*G0_0_1_2_0_1_1_0_0 + 1.11746031746033*G0_0_1_2_0_1_2_0_1 - 1.11746031746033*G0_0_1_2_0_1_3_1_0 - 1.11746031746033*G0_0_1_2_0_1_3_1_1 + 1.11746031746033*G0_0_1_2_0_1_4_1_0 + 1.11746031746033*G0_0_1_2_0_1_5_1_1 + 1.11746031746033*G0_0_1_3_1_0_0_0_0 + 1.11746031746033*G0_0_1_3_1_0_0_0_1 - 1.11746031746033*G0_0_1_3_1_0_1_0_0 - 1.11746031746033*G0_0_1_3_1_0_2_0_1 + 1.11746031746033*G0_0_1_3_1_0_3_1_0 + 1.11746031746033*G0_0_1_3_1_0_3_1_1 - 1.11746031746033*G0_0_1_3_1_0_4_1_0 - 1.11746031746033*G0_0_1_3_1_0_5_1_1 + 1.11746031746033*G0_0_1_3_1_1_0_0_0 + 1.11746031746033*G0_0_1_3_1_1_0_0_1 - 1.11746031746033*G0_0_1_3_1_1_1_0_0 - 1.11746031746033*G0_0_1_3_1_1_2_0_1 + 1.11746031746033*G0_0_1_3_1_1_3_1_0 + 1.11746031746033*G0_0_1_3_1_1_3_1_1 - 1.11746031746033*G0_0_1_3_1_1_4_1_0 - 1.11746031746033*G0_0_1_3_1_1_5_1_1 - 1.11746031746033*G0_0_1_4_1_0_0_0_0 - 1.11746031746033*G0_0_1_4_1_0_0_0_1 + 1.11746031746033*G0_0_1_4_1_0_1_0_0 + 1.11746031746033*G0_0_1_4_1_0_2_0_1 - 1.11746031746033*G0_0_1_4_1_0_3_1_0 - 1.11746031746033*G0_0_1_4_1_0_3_1_1 + 1.11746031746033*G0_0_1_4_1_0_4_1_0 + 1.11746031746033*G0_0_1_4_1_0_5_1_1 - 1.11746031746033*G0_0_1_5_1_1_0_0_0 - 1.11746031746033*G0_0_1_5_1_1_0_0_1 + 1.11746031746033*G0_0_1_5_1_1_1_0_0 + 1.11746031746033*G0_0_1_5_1_1_2_0_1 - 1.11746031746033*G0_0_1_5_1_1_3_1_0 - 1.11746031746033*G0_0_1_5_1_1_3_1_1 + 1.11746031746033*G0_0_1_5_1_1_4_1_0 + 1.11746031746033*G0_0_1_5_1_1_5_1_1 - 1.11746031746033*G0_1_0_0_0_0_0_0_0 - 1.11746031746033*G0_1_0_0_0_0_0_0_1 + 1.11746031746033*G0_1_0_0_0_0_1_0_0 + 1.11746031746033*G0_1_0_0_0_0_2_0_1 - 1.11746031746033*G0_1_0_0_0_0_3_1_0 - 1.11746031746033*G0_1_0_0_0_0_3_1_1 + 1.11746031746033*G0_1_0_0_0_0_4_1_0 + 1.11746031746033*G0_1_0_0_0_0_5_1_1 - 1.11746031746033*G0_1_0_0_0_1_0_0_0 - 1.11746031746033*G0_1_0_0_0_1_0_0_1 + 1.11746031746033*G0_1_0_0_0_1_1_0_0 + 1.11746031746033*G0_1_0_0_0_1_2_0_1 - 1.11746031746033*G0_1_0_0_0_1_3_1_0 - 1.11746031746033*G0_1_0_0_0_1_3_1_1 + 1.11746031746033*G0_1_0_0_0_1_4_1_0 + 1.11746031746033*G0_1_0_0_0_1_5_1_1 + 1.11746031746033*G0_1_0_1_0_0_0_0_0 + 1.11746031746033*G0_1_0_1_0_0_0_0_1 - 1.11746031746033*G0_1_0_1_0_0_1_0_0 - 1.11746031746033*G0_1_0_1_0_0_2_0_1 + 1.11746031746033*G0_1_0_1_0_0_3_1_0 + 1.11746031746033*G0_1_0_1_0_0_3_1_1 - 1.11746031746033*G0_1_0_1_0_0_4_1_0 - 1.11746031746033*G0_1_0_1_0_0_5_1_1 + 1.11746031746033*G0_1_0_2_0_1_0_0_0 + 1.11746031746033*G0_1_0_2_0_1_0_0_1 - 1.11746031746033*G0_1_0_2_0_1_1_0_0 - 1.11746031746033*G0_1_0_2_0_1_2_0_1 + 1.11746031746033*G0_1_0_2_0_1_3_1_0 + 1.11746031746033*G0_1_0_2_0_1_3_1_1 - 1.11746031746033*G0_1_0_2_0_1_4_1_0 - 1.11746031746033*G0_1_0_2_0_1_5_1_1 - 1.11746031746033*G0_1_0_3_1_0_0_0_0 - 1.11746031746033*G0_1_0_3_1_0_0_0_1 + 1.11746031746033*G0_1_0_3_1_0_1_0_0 + 1.11746031746033*G0_1_0_3_1_0_2_0_1 - 1.11746031746033*G0_1_0_3_1_0_3_1_0 - 1.11746031746033*G0_1_0_3_1_0_3_1_1 + 1.11746031746033*G0_1_0_3_1_0_4_1_0 + 1.11746031746033*G0_1_0_3_1_0_5_1_1 - 1.11746031746033*G0_1_0_3_1_1_0_0_0 - 1.11746031746033*G0_1_0_3_1_1_0_0_1 + 1.11746031746033*G0_1_0_3_1_1_1_0_0 + 1.11746031746033*G0_1_0_3_1_1_2_0_1 - 1.11746031746033*G0_1_0_3_1_1_3_1_0 - 1.11746031746033*G0_1_0_3_1_1_3_1_1 + 1.11746031746033*G0_1_0_3_1_1_4_1_0 + 1.11746031746033*G0_1_0_3_1_1_5_1_1 + 1.11746031746033*G0_1_0_4_1_0_0_0_0 + 1.11746031746033*G0_1_0_4_1_0_0_0_1 - 1.11746031746033*G0_1_0_4_1_0_1_0_0 - 1.11746031746033*G0_1_0_4_1_0_2_0_1 + 1.11746031746033*G0_1_0_4_1_0_3_1_0 + 1.11746031746033*G0_1_0_4_1_0_3_1_1 - 1.11746031746033*G0_1_0_4_1_0_4_1_0 - 1.11746031746033*G0_1_0_4_1_0_5_1_1 + 1.11746031746033*G0_1_0_5_1_1_0_0_0 + 1.11746031746033*G0_1_0_5_1_1_0_0_1 - 1.11746031746033*G0_1_0_5_1_1_1_0_0 - 1.11746031746033*G0_1_0_5_1_1_2_0_1 + 1.11746031746033*G0_1_0_5_1_1_3_1_0 + 1.11746031746033*G0_1_0_5_1_1_3_1_1 - 1.11746031746033*G0_1_0_5_1_1_4_1_0 - 1.11746031746033*G0_1_0_5_1_1_5_1_1; + A[432] = A[897]; + A[364] = A[132]; + A[320] = 0.0; + A[770] = A[625]; + A[459] = 0.0; + A[399] = A[748]; + A[355] = 0.0; + A[799] = A[334]; + A[105] = 0.0; + A[836] = -A[569] + 0.948148148148171*G0_0_0_0_0_0_0_0_0 + 0.948148148148171*G0_0_0_0_0_0_0_0_1 - 0.948148148148171*G0_0_0_0_0_0_1_0_0 - 0.948148148148171*G0_0_0_0_0_0_2_0_1 + 0.948148148148171*G0_0_0_0_0_0_3_1_0 + 0.948148148148171*G0_0_0_0_0_0_3_1_1 - 0.948148148148171*G0_0_0_0_0_0_4_1_0 - 0.948148148148171*G0_0_0_0_0_0_5_1_1 + 0.948148148148171*G0_0_0_0_0_1_0_0_0 + 0.948148148148171*G0_0_0_0_0_1_0_0_1 - 0.948148148148171*G0_0_0_0_0_1_1_0_0 - 0.948148148148171*G0_0_0_0_0_1_2_0_1 + 0.948148148148171*G0_0_0_0_0_1_3_1_0 + 0.948148148148171*G0_0_0_0_0_1_3_1_1 - 0.948148148148171*G0_0_0_0_0_1_4_1_0 - 0.948148148148171*G0_0_0_0_0_1_5_1_1 - 0.948148148148171*G0_0_0_1_0_0_0_0_0 - 0.948148148148171*G0_0_0_1_0_0_0_0_1 + 0.948148148148171*G0_0_0_1_0_0_1_0_0 + 0.948148148148171*G0_0_0_1_0_0_2_0_1 - 0.948148148148171*G0_0_0_1_0_0_3_1_0 - 0.948148148148171*G0_0_0_1_0_0_3_1_1 + 0.948148148148171*G0_0_0_1_0_0_4_1_0 + 0.948148148148171*G0_0_0_1_0_0_5_1_1 - 0.948148148148171*G0_0_0_2_0_1_0_0_0 - 0.948148148148171*G0_0_0_2_0_1_0_0_1 + 0.948148148148171*G0_0_0_2_0_1_1_0_0 + 0.948148148148171*G0_0_0_2_0_1_2_0_1 - 0.948148148148171*G0_0_0_2_0_1_3_1_0 - 0.948148148148171*G0_0_0_2_0_1_3_1_1 + 0.948148148148171*G0_0_0_2_0_1_4_1_0 + 0.948148148148171*G0_0_0_2_0_1_5_1_1 + 0.948148148148171*G0_0_0_3_1_0_0_0_0 + 0.948148148148171*G0_0_0_3_1_0_0_0_1 - 0.948148148148171*G0_0_0_3_1_0_1_0_0 - 0.948148148148171*G0_0_0_3_1_0_2_0_1 + 0.948148148148171*G0_0_0_3_1_0_3_1_0 + 0.948148148148171*G0_0_0_3_1_0_3_1_1 - 0.948148148148171*G0_0_0_3_1_0_4_1_0 - 0.948148148148171*G0_0_0_3_1_0_5_1_1 + 0.948148148148171*G0_0_0_3_1_1_0_0_0 + 0.948148148148171*G0_0_0_3_1_1_0_0_1 - 0.948148148148171*G0_0_0_3_1_1_1_0_0 - 0.948148148148171*G0_0_0_3_1_1_2_0_1 + 0.948148148148171*G0_0_0_3_1_1_3_1_0 + 0.948148148148171*G0_0_0_3_1_1_3_1_1 - 0.948148148148171*G0_0_0_3_1_1_4_1_0 - 0.948148148148171*G0_0_0_3_1_1_5_1_1 - 0.948148148148171*G0_0_0_4_1_0_0_0_0 - 0.948148148148171*G0_0_0_4_1_0_0_0_1 + 0.948148148148171*G0_0_0_4_1_0_1_0_0 + 0.948148148148171*G0_0_0_4_1_0_2_0_1 - 0.948148148148171*G0_0_0_4_1_0_3_1_0 - 0.948148148148171*G0_0_0_4_1_0_3_1_1 + 0.948148148148171*G0_0_0_4_1_0_4_1_0 + 0.948148148148171*G0_0_0_4_1_0_5_1_1 - 0.948148148148171*G0_0_0_5_1_1_0_0_0 - 0.948148148148171*G0_0_0_5_1_1_0_0_1 + 0.948148148148171*G0_0_0_5_1_1_1_0_0 + 0.948148148148171*G0_0_0_5_1_1_2_0_1 - 0.948148148148171*G0_0_0_5_1_1_3_1_0 - 0.948148148148171*G0_0_0_5_1_1_3_1_1 + 0.948148148148171*G0_0_0_5_1_1_4_1_0 + 0.948148148148171*G0_0_0_5_1_1_5_1_1; + A[33] = -A[506] - 0.524867724867733*G0_0_0_0_0_0_0_0_0 - 0.524867724867733*G0_0_0_0_0_0_0_0_1 + 0.524867724867733*G0_0_0_0_0_0_1_0_0 + 0.524867724867733*G0_0_0_0_0_0_2_0_1 - 0.524867724867733*G0_0_0_0_0_0_3_1_0 - 0.524867724867733*G0_0_0_0_0_0_3_1_1 + 0.524867724867733*G0_0_0_0_0_0_4_1_0 + 0.524867724867733*G0_0_0_0_0_0_5_1_1 - 0.524867724867733*G0_0_0_0_0_1_0_0_0 - 0.524867724867733*G0_0_0_0_0_1_0_0_1 + 0.524867724867733*G0_0_0_0_0_1_1_0_0 + 0.524867724867733*G0_0_0_0_0_1_2_0_1 - 0.524867724867733*G0_0_0_0_0_1_3_1_0 - 0.524867724867733*G0_0_0_0_0_1_3_1_1 + 0.524867724867733*G0_0_0_0_0_1_4_1_0 + 0.524867724867733*G0_0_0_0_0_1_5_1_1 + 0.524867724867733*G0_0_0_1_0_0_0_0_0 + 0.524867724867733*G0_0_0_1_0_0_0_0_1 - 0.524867724867733*G0_0_0_1_0_0_1_0_0 - 0.524867724867733*G0_0_0_1_0_0_2_0_1 + 0.524867724867733*G0_0_0_1_0_0_3_1_0 + 0.524867724867733*G0_0_0_1_0_0_3_1_1 - 0.524867724867733*G0_0_0_1_0_0_4_1_0 - 0.524867724867733*G0_0_0_1_0_0_5_1_1 + 0.524867724867733*G0_0_0_2_0_1_0_0_0 + 0.524867724867733*G0_0_0_2_0_1_0_0_1 - 0.524867724867733*G0_0_0_2_0_1_1_0_0 - 0.524867724867733*G0_0_0_2_0_1_2_0_1 + 0.524867724867733*G0_0_0_2_0_1_3_1_0 + 0.524867724867733*G0_0_0_2_0_1_3_1_1 - 0.524867724867733*G0_0_0_2_0_1_4_1_0 - 0.524867724867733*G0_0_0_2_0_1_5_1_1 - 0.524867724867733*G0_0_0_3_1_0_0_0_0 - 0.524867724867733*G0_0_0_3_1_0_0_0_1 + 0.524867724867733*G0_0_0_3_1_0_1_0_0 + 0.524867724867733*G0_0_0_3_1_0_2_0_1 - 0.524867724867733*G0_0_0_3_1_0_3_1_0 - 0.524867724867733*G0_0_0_3_1_0_3_1_1 + 0.524867724867733*G0_0_0_3_1_0_4_1_0 + 0.524867724867733*G0_0_0_3_1_0_5_1_1 - 0.524867724867733*G0_0_0_3_1_1_0_0_0 - 0.524867724867733*G0_0_0_3_1_1_0_0_1 + 0.524867724867733*G0_0_0_3_1_1_1_0_0 + 0.524867724867733*G0_0_0_3_1_1_2_0_1 - 0.524867724867733*G0_0_0_3_1_1_3_1_0 - 0.524867724867733*G0_0_0_3_1_1_3_1_1 + 0.524867724867733*G0_0_0_3_1_1_4_1_0 + 0.524867724867733*G0_0_0_3_1_1_5_1_1 + 0.524867724867733*G0_0_0_4_1_0_0_0_0 + 0.524867724867733*G0_0_0_4_1_0_0_0_1 - 0.524867724867733*G0_0_0_4_1_0_1_0_0 - 0.524867724867733*G0_0_0_4_1_0_2_0_1 + 0.524867724867733*G0_0_0_4_1_0_3_1_0 + 0.524867724867733*G0_0_0_4_1_0_3_1_1 - 0.524867724867733*G0_0_0_4_1_0_4_1_0 - 0.524867724867733*G0_0_0_4_1_0_5_1_1 + 0.524867724867733*G0_0_0_5_1_1_0_0_0 + 0.524867724867733*G0_0_0_5_1_1_0_0_1 - 0.524867724867733*G0_0_0_5_1_1_1_0_0 - 0.524867724867733*G0_0_0_5_1_1_2_0_1 + 0.524867724867733*G0_0_0_5_1_1_3_1_0 + 0.524867724867733*G0_0_0_5_1_1_3_1_1 - 0.524867724867733*G0_0_0_5_1_1_4_1_0 - 0.524867724867733*G0_0_0_5_1_1_5_1_1; + A[128] = A[709]; + A[869] = -A[628] - 0.812698412698434*G0_0_0_0_0_0_0_0_0 - 0.812698412698434*G0_0_0_0_0_0_0_0_1 + 0.812698412698434*G0_0_0_0_0_0_1_0_0 + 0.812698412698434*G0_0_0_0_0_0_2_0_1 - 0.812698412698434*G0_0_0_0_0_0_3_1_0 - 0.812698412698434*G0_0_0_0_0_0_3_1_1 + 0.812698412698434*G0_0_0_0_0_0_4_1_0 + 0.812698412698434*G0_0_0_0_0_0_5_1_1 - 0.812698412698434*G0_0_0_0_0_1_0_0_0 - 0.812698412698434*G0_0_0_0_0_1_0_0_1 + 0.812698412698434*G0_0_0_0_0_1_1_0_0 + 0.812698412698434*G0_0_0_0_0_1_2_0_1 - 0.812698412698434*G0_0_0_0_0_1_3_1_0 - 0.812698412698434*G0_0_0_0_0_1_3_1_1 + 0.812698412698434*G0_0_0_0_0_1_4_1_0 + 0.812698412698434*G0_0_0_0_0_1_5_1_1 + 0.812698412698434*G0_0_0_1_0_0_0_0_0 + 0.812698412698434*G0_0_0_1_0_0_0_0_1 - 0.812698412698434*G0_0_0_1_0_0_1_0_0 - 0.812698412698434*G0_0_0_1_0_0_2_0_1 + 0.812698412698434*G0_0_0_1_0_0_3_1_0 + 0.812698412698434*G0_0_0_1_0_0_3_1_1 - 0.812698412698434*G0_0_0_1_0_0_4_1_0 - 0.812698412698434*G0_0_0_1_0_0_5_1_1 + 0.812698412698434*G0_0_0_2_0_1_0_0_0 + 0.812698412698434*G0_0_0_2_0_1_0_0_1 - 0.812698412698434*G0_0_0_2_0_1_1_0_0 - 0.812698412698434*G0_0_0_2_0_1_2_0_1 + 0.812698412698434*G0_0_0_2_0_1_3_1_0 + 0.812698412698434*G0_0_0_2_0_1_3_1_1 - 0.812698412698434*G0_0_0_2_0_1_4_1_0 - 0.812698412698434*G0_0_0_2_0_1_5_1_1 - 0.812698412698434*G0_0_0_3_1_0_0_0_0 - 0.812698412698434*G0_0_0_3_1_0_0_0_1 + 0.812698412698434*G0_0_0_3_1_0_1_0_0 + 0.812698412698434*G0_0_0_3_1_0_2_0_1 - 0.812698412698434*G0_0_0_3_1_0_3_1_0 - 0.812698412698434*G0_0_0_3_1_0_3_1_1 + 0.812698412698434*G0_0_0_3_1_0_4_1_0 + 0.812698412698434*G0_0_0_3_1_0_5_1_1 - 0.812698412698434*G0_0_0_3_1_1_0_0_0 - 0.812698412698434*G0_0_0_3_1_1_0_0_1 + 0.812698412698434*G0_0_0_3_1_1_1_0_0 + 0.812698412698434*G0_0_0_3_1_1_2_0_1 - 0.812698412698434*G0_0_0_3_1_1_3_1_0 - 0.812698412698434*G0_0_0_3_1_1_3_1_1 + 0.812698412698434*G0_0_0_3_1_1_4_1_0 + 0.812698412698434*G0_0_0_3_1_1_5_1_1 + 0.812698412698434*G0_0_0_4_1_0_0_0_0 + 0.812698412698434*G0_0_0_4_1_0_0_0_1 - 0.812698412698434*G0_0_0_4_1_0_1_0_0 - 0.812698412698434*G0_0_0_4_1_0_2_0_1 + 0.812698412698434*G0_0_0_4_1_0_3_1_0 + 0.812698412698434*G0_0_0_4_1_0_3_1_1 - 0.812698412698434*G0_0_0_4_1_0_4_1_0 - 0.812698412698434*G0_0_0_4_1_0_5_1_1 + 0.812698412698434*G0_0_0_5_1_1_0_0_0 + 0.812698412698434*G0_0_0_5_1_1_0_0_1 - 0.812698412698434*G0_0_0_5_1_1_1_0_0 - 0.812698412698434*G0_0_0_5_1_1_2_0_1 + 0.812698412698434*G0_0_0_5_1_1_3_1_0 + 0.812698412698434*G0_0_0_5_1_1_3_1_1 - 0.812698412698434*G0_0_0_5_1_1_4_1_0 - 0.812698412698434*G0_0_0_5_1_1_5_1_1 + 1.55767195767197*G0_0_1_0_0_0_0_0_0 + 1.55767195767197*G0_0_1_0_0_0_0_0_1 - 1.55767195767197*G0_0_1_0_0_0_1_0_0 - 1.55767195767197*G0_0_1_0_0_0_2_0_1 + 1.55767195767197*G0_0_1_0_0_0_3_1_0 + 1.55767195767197*G0_0_1_0_0_0_3_1_1 - 1.55767195767197*G0_0_1_0_0_0_4_1_0 - 1.55767195767197*G0_0_1_0_0_0_5_1_1 + 1.55767195767197*G0_0_1_0_0_1_0_0_0 + 1.55767195767197*G0_0_1_0_0_1_0_0_1 - 1.55767195767197*G0_0_1_0_0_1_1_0_0 - 1.55767195767197*G0_0_1_0_0_1_2_0_1 + 1.55767195767197*G0_0_1_0_0_1_3_1_0 + 1.55767195767197*G0_0_1_0_0_1_3_1_1 - 1.55767195767197*G0_0_1_0_0_1_4_1_0 - 1.55767195767197*G0_0_1_0_0_1_5_1_1 - 1.55767195767197*G0_0_1_1_0_0_0_0_0 - 1.55767195767197*G0_0_1_1_0_0_0_0_1 + 1.55767195767197*G0_0_1_1_0_0_1_0_0 + 1.55767195767197*G0_0_1_1_0_0_2_0_1 - 1.55767195767197*G0_0_1_1_0_0_3_1_0 - 1.55767195767197*G0_0_1_1_0_0_3_1_1 + 1.55767195767197*G0_0_1_1_0_0_4_1_0 + 1.55767195767197*G0_0_1_1_0_0_5_1_1 - 1.55767195767197*G0_0_1_2_0_1_0_0_0 - 1.55767195767197*G0_0_1_2_0_1_0_0_1 + 1.55767195767197*G0_0_1_2_0_1_1_0_0 + 1.55767195767197*G0_0_1_2_0_1_2_0_1 - 1.55767195767197*G0_0_1_2_0_1_3_1_0 - 1.55767195767197*G0_0_1_2_0_1_3_1_1 + 1.55767195767197*G0_0_1_2_0_1_4_1_0 + 1.55767195767197*G0_0_1_2_0_1_5_1_1 + 1.55767195767197*G0_0_1_3_1_0_0_0_0 + 1.55767195767197*G0_0_1_3_1_0_0_0_1 - 1.55767195767197*G0_0_1_3_1_0_1_0_0 - 1.55767195767197*G0_0_1_3_1_0_2_0_1 + 1.55767195767197*G0_0_1_3_1_0_3_1_0 + 1.55767195767197*G0_0_1_3_1_0_3_1_1 - 1.55767195767197*G0_0_1_3_1_0_4_1_0 - 1.55767195767197*G0_0_1_3_1_0_5_1_1 + 1.55767195767197*G0_0_1_3_1_1_0_0_0 + 1.55767195767197*G0_0_1_3_1_1_0_0_1 - 1.55767195767197*G0_0_1_3_1_1_1_0_0 - 1.55767195767197*G0_0_1_3_1_1_2_0_1 + 1.55767195767197*G0_0_1_3_1_1_3_1_0 + 1.55767195767197*G0_0_1_3_1_1_3_1_1 - 1.55767195767197*G0_0_1_3_1_1_4_1_0 - 1.55767195767197*G0_0_1_3_1_1_5_1_1 - 1.55767195767197*G0_0_1_4_1_0_0_0_0 - 1.55767195767197*G0_0_1_4_1_0_0_0_1 + 1.55767195767197*G0_0_1_4_1_0_1_0_0 + 1.55767195767197*G0_0_1_4_1_0_2_0_1 - 1.55767195767197*G0_0_1_4_1_0_3_1_0 - 1.55767195767197*G0_0_1_4_1_0_3_1_1 + 1.55767195767197*G0_0_1_4_1_0_4_1_0 + 1.55767195767197*G0_0_1_4_1_0_5_1_1 - 1.55767195767197*G0_0_1_5_1_1_0_0_0 - 1.55767195767197*G0_0_1_5_1_1_0_0_1 + 1.55767195767197*G0_0_1_5_1_1_1_0_0 + 1.55767195767197*G0_0_1_5_1_1_2_0_1 - 1.55767195767197*G0_0_1_5_1_1_3_1_0 - 1.55767195767197*G0_0_1_5_1_1_3_1_1 + 1.55767195767197*G0_0_1_5_1_1_4_1_0 + 1.55767195767197*G0_0_1_5_1_1_5_1_1 + 1.55767195767197*G0_1_0_0_0_0_0_0_0 + 1.55767195767197*G0_1_0_0_0_0_0_0_1 - 1.55767195767197*G0_1_0_0_0_0_1_0_0 - 1.55767195767197*G0_1_0_0_0_0_2_0_1 + 1.55767195767197*G0_1_0_0_0_0_3_1_0 + 1.55767195767197*G0_1_0_0_0_0_3_1_1 - 1.55767195767197*G0_1_0_0_0_0_4_1_0 - 1.55767195767197*G0_1_0_0_0_0_5_1_1 + 1.55767195767197*G0_1_0_0_0_1_0_0_0 + 1.55767195767197*G0_1_0_0_0_1_0_0_1 - 1.55767195767197*G0_1_0_0_0_1_1_0_0 - 1.55767195767197*G0_1_0_0_0_1_2_0_1 + 1.55767195767197*G0_1_0_0_0_1_3_1_0 + 1.55767195767197*G0_1_0_0_0_1_3_1_1 - 1.55767195767197*G0_1_0_0_0_1_4_1_0 - 1.55767195767197*G0_1_0_0_0_1_5_1_1 - 1.55767195767197*G0_1_0_1_0_0_0_0_0 - 1.55767195767197*G0_1_0_1_0_0_0_0_1 + 1.55767195767197*G0_1_0_1_0_0_1_0_0 + 1.55767195767197*G0_1_0_1_0_0_2_0_1 - 1.55767195767197*G0_1_0_1_0_0_3_1_0 - 1.55767195767197*G0_1_0_1_0_0_3_1_1 + 1.55767195767197*G0_1_0_1_0_0_4_1_0 + 1.55767195767197*G0_1_0_1_0_0_5_1_1 - 1.55767195767197*G0_1_0_2_0_1_0_0_0 - 1.55767195767197*G0_1_0_2_0_1_0_0_1 + 1.55767195767197*G0_1_0_2_0_1_1_0_0 + 1.55767195767197*G0_1_0_2_0_1_2_0_1 - 1.55767195767197*G0_1_0_2_0_1_3_1_0 - 1.55767195767197*G0_1_0_2_0_1_3_1_1 + 1.55767195767197*G0_1_0_2_0_1_4_1_0 + 1.55767195767197*G0_1_0_2_0_1_5_1_1 + 1.55767195767197*G0_1_0_3_1_0_0_0_0 + 1.55767195767197*G0_1_0_3_1_0_0_0_1 - 1.55767195767197*G0_1_0_3_1_0_1_0_0 - 1.55767195767197*G0_1_0_3_1_0_2_0_1 + 1.55767195767197*G0_1_0_3_1_0_3_1_0 + 1.55767195767197*G0_1_0_3_1_0_3_1_1 - 1.55767195767197*G0_1_0_3_1_0_4_1_0 - 1.55767195767197*G0_1_0_3_1_0_5_1_1 + 1.55767195767197*G0_1_0_3_1_1_0_0_0 + 1.55767195767197*G0_1_0_3_1_1_0_0_1 - 1.55767195767197*G0_1_0_3_1_1_1_0_0 - 1.55767195767197*G0_1_0_3_1_1_2_0_1 + 1.55767195767197*G0_1_0_3_1_1_3_1_0 + 1.55767195767197*G0_1_0_3_1_1_3_1_1 - 1.55767195767197*G0_1_0_3_1_1_4_1_0 - 1.55767195767197*G0_1_0_3_1_1_5_1_1 - 1.55767195767197*G0_1_0_4_1_0_0_0_0 - 1.55767195767197*G0_1_0_4_1_0_0_0_1 + 1.55767195767197*G0_1_0_4_1_0_1_0_0 + 1.55767195767197*G0_1_0_4_1_0_2_0_1 - 1.55767195767197*G0_1_0_4_1_0_3_1_0 - 1.55767195767197*G0_1_0_4_1_0_3_1_1 + 1.55767195767197*G0_1_0_4_1_0_4_1_0 + 1.55767195767197*G0_1_0_4_1_0_5_1_1 - 1.55767195767197*G0_1_0_5_1_1_0_0_0 - 1.55767195767197*G0_1_0_5_1_1_0_0_1 + 1.55767195767197*G0_1_0_5_1_1_1_0_0 + 1.55767195767197*G0_1_0_5_1_1_2_0_1 - 1.55767195767197*G0_1_0_5_1_1_3_1_0 - 1.55767195767197*G0_1_0_5_1_1_3_1_1 + 1.55767195767197*G0_1_0_5_1_1_4_1_0 + 1.55767195767197*G0_1_0_5_1_1_5_1_1; + A[68] = A[533]; + A[163] = A[628]; + A[870] = 0.0; + A[111] = 0.0; + A[182] = A[647]; + A[142] = 0.0; + A[592] = A[679]; + A[221] = -A[213] - 0.220105820105836*G0_0_0_0_0_0_0_0_0 - 0.220105820105836*G0_0_0_0_0_0_0_0_1 + 0.220105820105836*G0_0_0_0_0_0_1_0_0 + 0.220105820105836*G0_0_0_0_0_0_2_0_1 - 0.220105820105836*G0_0_0_0_0_0_3_1_0 - 0.220105820105836*G0_0_0_0_0_0_3_1_1 + 0.220105820105836*G0_0_0_0_0_0_4_1_0 + 0.220105820105836*G0_0_0_0_0_0_5_1_1 - 0.220105820105836*G0_0_0_0_0_1_0_0_0 - 0.220105820105836*G0_0_0_0_0_1_0_0_1 + 0.220105820105836*G0_0_0_0_0_1_1_0_0 + 0.220105820105836*G0_0_0_0_0_1_2_0_1 - 0.220105820105836*G0_0_0_0_0_1_3_1_0 - 0.220105820105836*G0_0_0_0_0_1_3_1_1 + 0.220105820105836*G0_0_0_0_0_1_4_1_0 + 0.220105820105836*G0_0_0_0_0_1_5_1_1 + 0.220105820105836*G0_0_0_1_0_0_0_0_0 + 0.220105820105836*G0_0_0_1_0_0_0_0_1 - 0.220105820105836*G0_0_0_1_0_0_1_0_0 - 0.220105820105836*G0_0_0_1_0_0_2_0_1 + 0.220105820105836*G0_0_0_1_0_0_3_1_0 + 0.220105820105836*G0_0_0_1_0_0_3_1_1 - 0.220105820105836*G0_0_0_1_0_0_4_1_0 - 0.220105820105836*G0_0_0_1_0_0_5_1_1 + 0.220105820105836*G0_0_0_2_0_1_0_0_0 + 0.220105820105836*G0_0_0_2_0_1_0_0_1 - 0.220105820105836*G0_0_0_2_0_1_1_0_0 - 0.220105820105836*G0_0_0_2_0_1_2_0_1 + 0.220105820105836*G0_0_0_2_0_1_3_1_0 + 0.220105820105836*G0_0_0_2_0_1_3_1_1 - 0.220105820105836*G0_0_0_2_0_1_4_1_0 - 0.220105820105836*G0_0_0_2_0_1_5_1_1 - 0.220105820105836*G0_0_0_3_1_0_0_0_0 - 0.220105820105836*G0_0_0_3_1_0_0_0_1 + 0.220105820105836*G0_0_0_3_1_0_1_0_0 + 0.220105820105836*G0_0_0_3_1_0_2_0_1 - 0.220105820105836*G0_0_0_3_1_0_3_1_0 - 0.220105820105836*G0_0_0_3_1_0_3_1_1 + 0.220105820105836*G0_0_0_3_1_0_4_1_0 + 0.220105820105836*G0_0_0_3_1_0_5_1_1 - 0.220105820105836*G0_0_0_3_1_1_0_0_0 - 0.220105820105836*G0_0_0_3_1_1_0_0_1 + 0.220105820105836*G0_0_0_3_1_1_1_0_0 + 0.220105820105836*G0_0_0_3_1_1_2_0_1 - 0.220105820105836*G0_0_0_3_1_1_3_1_0 - 0.220105820105836*G0_0_0_3_1_1_3_1_1 + 0.220105820105836*G0_0_0_3_1_1_4_1_0 + 0.220105820105836*G0_0_0_3_1_1_5_1_1 + 0.220105820105836*G0_0_0_4_1_0_0_0_0 + 0.220105820105836*G0_0_0_4_1_0_0_0_1 - 0.220105820105836*G0_0_0_4_1_0_1_0_0 - 0.220105820105836*G0_0_0_4_1_0_2_0_1 + 0.220105820105836*G0_0_0_4_1_0_3_1_0 + 0.220105820105836*G0_0_0_4_1_0_3_1_1 - 0.220105820105836*G0_0_0_4_1_0_4_1_0 - 0.220105820105836*G0_0_0_4_1_0_5_1_1 + 0.220105820105836*G0_0_0_5_1_1_0_0_0 + 0.220105820105836*G0_0_0_5_1_1_0_0_1 - 0.220105820105836*G0_0_0_5_1_1_1_0_0 - 0.220105820105836*G0_0_0_5_1_1_2_0_1 + 0.220105820105836*G0_0_0_5_1_1_3_1_0 + 0.220105820105836*G0_0_0_5_1_1_3_1_1 - 0.220105820105836*G0_0_0_5_1_1_4_1_0 - 0.220105820105836*G0_0_0_5_1_1_5_1_1; + A[219] = A[221] - 0.406349206349211*G0_0_1_0_0_0_0_0_0 - 0.406349206349211*G0_0_1_0_0_0_0_0_1 + 0.406349206349211*G0_0_1_0_0_0_1_0_0 + 0.406349206349211*G0_0_1_0_0_0_2_0_1 - 0.406349206349211*G0_0_1_0_0_0_3_1_0 - 0.406349206349211*G0_0_1_0_0_0_3_1_1 + 0.406349206349211*G0_0_1_0_0_0_4_1_0 + 0.406349206349211*G0_0_1_0_0_0_5_1_1 - 0.406349206349211*G0_0_1_0_0_1_0_0_0 - 0.406349206349211*G0_0_1_0_0_1_0_0_1 + 0.406349206349211*G0_0_1_0_0_1_1_0_0 + 0.406349206349211*G0_0_1_0_0_1_2_0_1 - 0.406349206349211*G0_0_1_0_0_1_3_1_0 - 0.406349206349211*G0_0_1_0_0_1_3_1_1 + 0.406349206349211*G0_0_1_0_0_1_4_1_0 + 0.406349206349211*G0_0_1_0_0_1_5_1_1 + 0.406349206349211*G0_0_1_1_0_0_0_0_0 + 0.406349206349211*G0_0_1_1_0_0_0_0_1 - 0.406349206349211*G0_0_1_1_0_0_1_0_0 - 0.406349206349211*G0_0_1_1_0_0_2_0_1 + 0.406349206349211*G0_0_1_1_0_0_3_1_0 + 0.406349206349211*G0_0_1_1_0_0_3_1_1 - 0.406349206349211*G0_0_1_1_0_0_4_1_0 - 0.406349206349211*G0_0_1_1_0_0_5_1_1 + 0.406349206349211*G0_0_1_2_0_1_0_0_0 + 0.406349206349211*G0_0_1_2_0_1_0_0_1 - 0.406349206349211*G0_0_1_2_0_1_1_0_0 - 0.406349206349211*G0_0_1_2_0_1_2_0_1 + 0.406349206349211*G0_0_1_2_0_1_3_1_0 + 0.406349206349211*G0_0_1_2_0_1_3_1_1 - 0.406349206349211*G0_0_1_2_0_1_4_1_0 - 0.406349206349211*G0_0_1_2_0_1_5_1_1 - 0.406349206349211*G0_0_1_3_1_0_0_0_0 - 0.406349206349211*G0_0_1_3_1_0_0_0_1 + 0.406349206349211*G0_0_1_3_1_0_1_0_0 + 0.406349206349211*G0_0_1_3_1_0_2_0_1 - 0.406349206349211*G0_0_1_3_1_0_3_1_0 - 0.406349206349211*G0_0_1_3_1_0_3_1_1 + 0.406349206349211*G0_0_1_3_1_0_4_1_0 + 0.406349206349211*G0_0_1_3_1_0_5_1_1 - 0.406349206349211*G0_0_1_3_1_1_0_0_0 - 0.406349206349211*G0_0_1_3_1_1_0_0_1 + 0.406349206349211*G0_0_1_3_1_1_1_0_0 + 0.406349206349211*G0_0_1_3_1_1_2_0_1 - 0.406349206349211*G0_0_1_3_1_1_3_1_0 - 0.406349206349211*G0_0_1_3_1_1_3_1_1 + 0.406349206349211*G0_0_1_3_1_1_4_1_0 + 0.406349206349211*G0_0_1_3_1_1_5_1_1 + 0.406349206349211*G0_0_1_4_1_0_0_0_0 + 0.406349206349211*G0_0_1_4_1_0_0_0_1 - 0.406349206349211*G0_0_1_4_1_0_1_0_0 - 0.406349206349211*G0_0_1_4_1_0_2_0_1 + 0.406349206349211*G0_0_1_4_1_0_3_1_0 + 0.406349206349211*G0_0_1_4_1_0_3_1_1 - 0.406349206349211*G0_0_1_4_1_0_4_1_0 - 0.406349206349211*G0_0_1_4_1_0_5_1_1 + 0.406349206349211*G0_0_1_5_1_1_0_0_0 + 0.406349206349211*G0_0_1_5_1_1_0_0_1 - 0.406349206349211*G0_0_1_5_1_1_1_0_0 - 0.406349206349211*G0_0_1_5_1_1_2_0_1 + 0.406349206349211*G0_0_1_5_1_1_3_1_0 + 0.406349206349211*G0_0_1_5_1_1_3_1_1 - 0.406349206349211*G0_0_1_5_1_1_4_1_0 - 0.406349206349211*G0_0_1_5_1_1_5_1_1 - 0.406349206349205*G0_1_0_0_0_0_0_0_0 - 0.406349206349205*G0_1_0_0_0_0_0_0_1 + 0.406349206349205*G0_1_0_0_0_0_1_0_0 + 0.406349206349205*G0_1_0_0_0_0_2_0_1 - 0.406349206349205*G0_1_0_0_0_0_3_1_0 - 0.406349206349205*G0_1_0_0_0_0_3_1_1 + 0.406349206349205*G0_1_0_0_0_0_4_1_0 + 0.406349206349205*G0_1_0_0_0_0_5_1_1 - 0.406349206349205*G0_1_0_0_0_1_0_0_0 - 0.406349206349205*G0_1_0_0_0_1_0_0_1 + 0.406349206349205*G0_1_0_0_0_1_1_0_0 + 0.406349206349205*G0_1_0_0_0_1_2_0_1 - 0.406349206349205*G0_1_0_0_0_1_3_1_0 - 0.406349206349205*G0_1_0_0_0_1_3_1_1 + 0.406349206349205*G0_1_0_0_0_1_4_1_0 + 0.406349206349205*G0_1_0_0_0_1_5_1_1 + 0.406349206349205*G0_1_0_1_0_0_0_0_0 + 0.406349206349205*G0_1_0_1_0_0_0_0_1 - 0.406349206349205*G0_1_0_1_0_0_1_0_0 - 0.406349206349205*G0_1_0_1_0_0_2_0_1 + 0.406349206349205*G0_1_0_1_0_0_3_1_0 + 0.406349206349205*G0_1_0_1_0_0_3_1_1 - 0.406349206349205*G0_1_0_1_0_0_4_1_0 - 0.406349206349205*G0_1_0_1_0_0_5_1_1 + 0.406349206349205*G0_1_0_2_0_1_0_0_0 + 0.406349206349205*G0_1_0_2_0_1_0_0_1 - 0.406349206349205*G0_1_0_2_0_1_1_0_0 - 0.406349206349205*G0_1_0_2_0_1_2_0_1 + 0.406349206349205*G0_1_0_2_0_1_3_1_0 + 0.406349206349205*G0_1_0_2_0_1_3_1_1 - 0.406349206349205*G0_1_0_2_0_1_4_1_0 - 0.406349206349205*G0_1_0_2_0_1_5_1_1 - 0.406349206349205*G0_1_0_3_1_0_0_0_0 - 0.406349206349205*G0_1_0_3_1_0_0_0_1 + 0.406349206349205*G0_1_0_3_1_0_1_0_0 + 0.406349206349205*G0_1_0_3_1_0_2_0_1 - 0.406349206349205*G0_1_0_3_1_0_3_1_0 - 0.406349206349205*G0_1_0_3_1_0_3_1_1 + 0.406349206349205*G0_1_0_3_1_0_4_1_0 + 0.406349206349205*G0_1_0_3_1_0_5_1_1 - 0.406349206349205*G0_1_0_3_1_1_0_0_0 - 0.406349206349205*G0_1_0_3_1_1_0_0_1 + 0.406349206349205*G0_1_0_3_1_1_1_0_0 + 0.406349206349205*G0_1_0_3_1_1_2_0_1 - 0.406349206349205*G0_1_0_3_1_1_3_1_0 - 0.406349206349205*G0_1_0_3_1_1_3_1_1 + 0.406349206349205*G0_1_0_3_1_1_4_1_0 + 0.406349206349205*G0_1_0_3_1_1_5_1_1 + 0.406349206349205*G0_1_0_4_1_0_0_0_0 + 0.406349206349205*G0_1_0_4_1_0_0_0_1 - 0.406349206349205*G0_1_0_4_1_0_1_0_0 - 0.406349206349205*G0_1_0_4_1_0_2_0_1 + 0.406349206349205*G0_1_0_4_1_0_3_1_0 + 0.406349206349205*G0_1_0_4_1_0_3_1_1 - 0.406349206349205*G0_1_0_4_1_0_4_1_0 - 0.406349206349205*G0_1_0_4_1_0_5_1_1 + 0.406349206349205*G0_1_0_5_1_1_0_0_0 + 0.406349206349205*G0_1_0_5_1_1_0_0_1 - 0.406349206349205*G0_1_0_5_1_1_1_0_0 - 0.406349206349205*G0_1_0_5_1_1_2_0_1 + 0.406349206349205*G0_1_0_5_1_1_3_1_0 + 0.406349206349205*G0_1_0_5_1_1_3_1_1 - 0.406349206349205*G0_1_0_5_1_1_4_1_0 - 0.406349206349205*G0_1_0_5_1_1_5_1_1 + 0.101587301587311*G0_1_1_0_0_0_0_0_0 + 0.101587301587311*G0_1_1_0_0_0_0_0_1 - 0.101587301587311*G0_1_1_0_0_0_1_0_0 - 0.101587301587311*G0_1_1_0_0_0_2_0_1 + 0.101587301587311*G0_1_1_0_0_0_3_1_0 + 0.101587301587311*G0_1_1_0_0_0_3_1_1 - 0.101587301587311*G0_1_1_0_0_0_4_1_0 - 0.101587301587311*G0_1_1_0_0_0_5_1_1 + 0.101587301587311*G0_1_1_0_0_1_0_0_0 + 0.101587301587311*G0_1_1_0_0_1_0_0_1 - 0.101587301587311*G0_1_1_0_0_1_1_0_0 - 0.101587301587311*G0_1_1_0_0_1_2_0_1 + 0.101587301587311*G0_1_1_0_0_1_3_1_0 + 0.101587301587311*G0_1_1_0_0_1_3_1_1 - 0.101587301587311*G0_1_1_0_0_1_4_1_0 - 0.101587301587311*G0_1_1_0_0_1_5_1_1 - 0.101587301587311*G0_1_1_1_0_0_0_0_0 - 0.101587301587311*G0_1_1_1_0_0_0_0_1 + 0.101587301587311*G0_1_1_1_0_0_1_0_0 + 0.101587301587311*G0_1_1_1_0_0_2_0_1 - 0.101587301587311*G0_1_1_1_0_0_3_1_0 - 0.101587301587311*G0_1_1_1_0_0_3_1_1 + 0.101587301587311*G0_1_1_1_0_0_4_1_0 + 0.101587301587311*G0_1_1_1_0_0_5_1_1 - 0.101587301587311*G0_1_1_2_0_1_0_0_0 - 0.101587301587311*G0_1_1_2_0_1_0_0_1 + 0.101587301587311*G0_1_1_2_0_1_1_0_0 + 0.101587301587311*G0_1_1_2_0_1_2_0_1 - 0.101587301587311*G0_1_1_2_0_1_3_1_0 - 0.101587301587311*G0_1_1_2_0_1_3_1_1 + 0.101587301587311*G0_1_1_2_0_1_4_1_0 + 0.101587301587311*G0_1_1_2_0_1_5_1_1 + 0.101587301587311*G0_1_1_3_1_0_0_0_0 + 0.101587301587311*G0_1_1_3_1_0_0_0_1 - 0.101587301587311*G0_1_1_3_1_0_1_0_0 - 0.101587301587311*G0_1_1_3_1_0_2_0_1 + 0.101587301587311*G0_1_1_3_1_0_3_1_0 + 0.101587301587311*G0_1_1_3_1_0_3_1_1 - 0.101587301587311*G0_1_1_3_1_0_4_1_0 - 0.101587301587311*G0_1_1_3_1_0_5_1_1 + 0.101587301587311*G0_1_1_3_1_1_0_0_0 + 0.101587301587311*G0_1_1_3_1_1_0_0_1 - 0.101587301587311*G0_1_1_3_1_1_1_0_0 - 0.101587301587311*G0_1_1_3_1_1_2_0_1 + 0.101587301587311*G0_1_1_3_1_1_3_1_0 + 0.101587301587311*G0_1_1_3_1_1_3_1_1 - 0.101587301587311*G0_1_1_3_1_1_4_1_0 - 0.101587301587311*G0_1_1_3_1_1_5_1_1 - 0.101587301587311*G0_1_1_4_1_0_0_0_0 - 0.101587301587311*G0_1_1_4_1_0_0_0_1 + 0.101587301587311*G0_1_1_4_1_0_1_0_0 + 0.101587301587311*G0_1_1_4_1_0_2_0_1 - 0.101587301587311*G0_1_1_4_1_0_3_1_0 - 0.101587301587311*G0_1_1_4_1_0_3_1_1 + 0.101587301587311*G0_1_1_4_1_0_4_1_0 + 0.101587301587311*G0_1_1_4_1_0_5_1_1 - 0.101587301587311*G0_1_1_5_1_1_0_0_0 - 0.101587301587311*G0_1_1_5_1_1_0_0_1 + 0.101587301587311*G0_1_1_5_1_1_1_0_0 + 0.101587301587311*G0_1_1_5_1_1_2_0_1 - 0.101587301587311*G0_1_1_5_1_1_3_1_0 - 0.101587301587311*G0_1_1_5_1_1_3_1_1 + 0.101587301587311*G0_1_1_5_1_1_4_1_0 + 0.101587301587311*G0_1_1_5_1_1_5_1_1; + A[274] = A[221] - 0.152380952380964*G0_0_1_0_0_0_0_0_0 - 0.152380952380964*G0_0_1_0_0_0_0_0_1 + 0.152380952380964*G0_0_1_0_0_0_1_0_0 + 0.152380952380964*G0_0_1_0_0_0_2_0_1 - 0.152380952380964*G0_0_1_0_0_0_3_1_0 - 0.152380952380964*G0_0_1_0_0_0_3_1_1 + 0.152380952380964*G0_0_1_0_0_0_4_1_0 + 0.152380952380964*G0_0_1_0_0_0_5_1_1 - 0.152380952380964*G0_0_1_0_0_1_0_0_0 - 0.152380952380964*G0_0_1_0_0_1_0_0_1 + 0.152380952380964*G0_0_1_0_0_1_1_0_0 + 0.152380952380964*G0_0_1_0_0_1_2_0_1 - 0.152380952380964*G0_0_1_0_0_1_3_1_0 - 0.152380952380964*G0_0_1_0_0_1_3_1_1 + 0.152380952380964*G0_0_1_0_0_1_4_1_0 + 0.152380952380964*G0_0_1_0_0_1_5_1_1 + 0.152380952380964*G0_0_1_1_0_0_0_0_0 + 0.152380952380964*G0_0_1_1_0_0_0_0_1 - 0.152380952380964*G0_0_1_1_0_0_1_0_0 - 0.152380952380964*G0_0_1_1_0_0_2_0_1 + 0.152380952380964*G0_0_1_1_0_0_3_1_0 + 0.152380952380964*G0_0_1_1_0_0_3_1_1 - 0.152380952380964*G0_0_1_1_0_0_4_1_0 - 0.152380952380964*G0_0_1_1_0_0_5_1_1 + 0.152380952380964*G0_0_1_2_0_1_0_0_0 + 0.152380952380964*G0_0_1_2_0_1_0_0_1 - 0.152380952380964*G0_0_1_2_0_1_1_0_0 - 0.152380952380964*G0_0_1_2_0_1_2_0_1 + 0.152380952380964*G0_0_1_2_0_1_3_1_0 + 0.152380952380964*G0_0_1_2_0_1_3_1_1 - 0.152380952380964*G0_0_1_2_0_1_4_1_0 - 0.152380952380964*G0_0_1_2_0_1_5_1_1 - 0.152380952380964*G0_0_1_3_1_0_0_0_0 - 0.152380952380964*G0_0_1_3_1_0_0_0_1 + 0.152380952380964*G0_0_1_3_1_0_1_0_0 + 0.152380952380964*G0_0_1_3_1_0_2_0_1 - 0.152380952380964*G0_0_1_3_1_0_3_1_0 - 0.152380952380964*G0_0_1_3_1_0_3_1_1 + 0.152380952380964*G0_0_1_3_1_0_4_1_0 + 0.152380952380964*G0_0_1_3_1_0_5_1_1 - 0.152380952380964*G0_0_1_3_1_1_0_0_0 - 0.152380952380964*G0_0_1_3_1_1_0_0_1 + 0.152380952380964*G0_0_1_3_1_1_1_0_0 + 0.152380952380964*G0_0_1_3_1_1_2_0_1 - 0.152380952380964*G0_0_1_3_1_1_3_1_0 - 0.152380952380964*G0_0_1_3_1_1_3_1_1 + 0.152380952380964*G0_0_1_3_1_1_4_1_0 + 0.152380952380964*G0_0_1_3_1_1_5_1_1 + 0.152380952380964*G0_0_1_4_1_0_0_0_0 + 0.152380952380964*G0_0_1_4_1_0_0_0_1 - 0.152380952380964*G0_0_1_4_1_0_1_0_0 - 0.152380952380964*G0_0_1_4_1_0_2_0_1 + 0.152380952380964*G0_0_1_4_1_0_3_1_0 + 0.152380952380964*G0_0_1_4_1_0_3_1_1 - 0.152380952380964*G0_0_1_4_1_0_4_1_0 - 0.152380952380964*G0_0_1_4_1_0_5_1_1 + 0.152380952380964*G0_0_1_5_1_1_0_0_0 + 0.152380952380964*G0_0_1_5_1_1_0_0_1 - 0.152380952380964*G0_0_1_5_1_1_1_0_0 - 0.152380952380964*G0_0_1_5_1_1_2_0_1 + 0.152380952380964*G0_0_1_5_1_1_3_1_0 + 0.152380952380964*G0_0_1_5_1_1_3_1_1 - 0.152380952380964*G0_0_1_5_1_1_4_1_0 - 0.152380952380964*G0_0_1_5_1_1_5_1_1 - 0.152380952380965*G0_1_0_0_0_0_0_0_0 - 0.152380952380965*G0_1_0_0_0_0_0_0_1 + 0.152380952380965*G0_1_0_0_0_0_1_0_0 + 0.152380952380965*G0_1_0_0_0_0_2_0_1 - 0.152380952380965*G0_1_0_0_0_0_3_1_0 - 0.152380952380965*G0_1_0_0_0_0_3_1_1 + 0.152380952380965*G0_1_0_0_0_0_4_1_0 + 0.152380952380965*G0_1_0_0_0_0_5_1_1 - 0.152380952380965*G0_1_0_0_0_1_0_0_0 - 0.152380952380965*G0_1_0_0_0_1_0_0_1 + 0.152380952380965*G0_1_0_0_0_1_1_0_0 + 0.152380952380965*G0_1_0_0_0_1_2_0_1 - 0.152380952380965*G0_1_0_0_0_1_3_1_0 - 0.152380952380965*G0_1_0_0_0_1_3_1_1 + 0.152380952380965*G0_1_0_0_0_1_4_1_0 + 0.152380952380965*G0_1_0_0_0_1_5_1_1 + 0.152380952380965*G0_1_0_1_0_0_0_0_0 + 0.152380952380965*G0_1_0_1_0_0_0_0_1 - 0.152380952380965*G0_1_0_1_0_0_1_0_0 - 0.152380952380965*G0_1_0_1_0_0_2_0_1 + 0.152380952380965*G0_1_0_1_0_0_3_1_0 + 0.152380952380965*G0_1_0_1_0_0_3_1_1 - 0.152380952380965*G0_1_0_1_0_0_4_1_0 - 0.152380952380965*G0_1_0_1_0_0_5_1_1 + 0.152380952380965*G0_1_0_2_0_1_0_0_0 + 0.152380952380965*G0_1_0_2_0_1_0_0_1 - 0.152380952380965*G0_1_0_2_0_1_1_0_0 - 0.152380952380965*G0_1_0_2_0_1_2_0_1 + 0.152380952380965*G0_1_0_2_0_1_3_1_0 + 0.152380952380965*G0_1_0_2_0_1_3_1_1 - 0.152380952380965*G0_1_0_2_0_1_4_1_0 - 0.152380952380965*G0_1_0_2_0_1_5_1_1 - 0.152380952380965*G0_1_0_3_1_0_0_0_0 - 0.152380952380965*G0_1_0_3_1_0_0_0_1 + 0.152380952380965*G0_1_0_3_1_0_1_0_0 + 0.152380952380965*G0_1_0_3_1_0_2_0_1 - 0.152380952380965*G0_1_0_3_1_0_3_1_0 - 0.152380952380965*G0_1_0_3_1_0_3_1_1 + 0.152380952380965*G0_1_0_3_1_0_4_1_0 + 0.152380952380965*G0_1_0_3_1_0_5_1_1 - 0.152380952380965*G0_1_0_3_1_1_0_0_0 - 0.152380952380965*G0_1_0_3_1_1_0_0_1 + 0.152380952380965*G0_1_0_3_1_1_1_0_0 + 0.152380952380965*G0_1_0_3_1_1_2_0_1 - 0.152380952380965*G0_1_0_3_1_1_3_1_0 - 0.152380952380965*G0_1_0_3_1_1_3_1_1 + 0.152380952380965*G0_1_0_3_1_1_4_1_0 + 0.152380952380965*G0_1_0_3_1_1_5_1_1 + 0.152380952380965*G0_1_0_4_1_0_0_0_0 + 0.152380952380965*G0_1_0_4_1_0_0_0_1 - 0.152380952380965*G0_1_0_4_1_0_1_0_0 - 0.152380952380965*G0_1_0_4_1_0_2_0_1 + 0.152380952380965*G0_1_0_4_1_0_3_1_0 + 0.152380952380965*G0_1_0_4_1_0_3_1_1 - 0.152380952380965*G0_1_0_4_1_0_4_1_0 - 0.152380952380965*G0_1_0_4_1_0_5_1_1 + 0.152380952380965*G0_1_0_5_1_1_0_0_0 + 0.152380952380965*G0_1_0_5_1_1_0_0_1 - 0.152380952380965*G0_1_0_5_1_1_1_0_0 - 0.152380952380965*G0_1_0_5_1_1_2_0_1 + 0.152380952380965*G0_1_0_5_1_1_3_1_0 + 0.152380952380965*G0_1_0_5_1_1_3_1_1 - 0.152380952380965*G0_1_0_5_1_1_4_1_0 - 0.152380952380965*G0_1_0_5_1_1_5_1_1 - 0.152380952380967*G0_1_1_0_0_0_0_0_0 - 0.152380952380967*G0_1_1_0_0_0_0_0_1 + 0.152380952380967*G0_1_1_0_0_0_1_0_0 + 0.152380952380967*G0_1_1_0_0_0_2_0_1 - 0.152380952380967*G0_1_1_0_0_0_3_1_0 - 0.152380952380967*G0_1_1_0_0_0_3_1_1 + 0.152380952380967*G0_1_1_0_0_0_4_1_0 + 0.152380952380967*G0_1_1_0_0_0_5_1_1 - 0.152380952380967*G0_1_1_0_0_1_0_0_0 - 0.152380952380967*G0_1_1_0_0_1_0_0_1 + 0.152380952380967*G0_1_1_0_0_1_1_0_0 + 0.152380952380967*G0_1_1_0_0_1_2_0_1 - 0.152380952380967*G0_1_1_0_0_1_3_1_0 - 0.152380952380967*G0_1_1_0_0_1_3_1_1 + 0.152380952380967*G0_1_1_0_0_1_4_1_0 + 0.152380952380967*G0_1_1_0_0_1_5_1_1 + 0.152380952380967*G0_1_1_1_0_0_0_0_0 + 0.152380952380967*G0_1_1_1_0_0_0_0_1 - 0.152380952380967*G0_1_1_1_0_0_1_0_0 - 0.152380952380967*G0_1_1_1_0_0_2_0_1 + 0.152380952380967*G0_1_1_1_0_0_3_1_0 + 0.152380952380967*G0_1_1_1_0_0_3_1_1 - 0.152380952380967*G0_1_1_1_0_0_4_1_0 - 0.152380952380967*G0_1_1_1_0_0_5_1_1 + 0.152380952380967*G0_1_1_2_0_1_0_0_0 + 0.152380952380967*G0_1_1_2_0_1_0_0_1 - 0.152380952380967*G0_1_1_2_0_1_1_0_0 - 0.152380952380967*G0_1_1_2_0_1_2_0_1 + 0.152380952380967*G0_1_1_2_0_1_3_1_0 + 0.152380952380967*G0_1_1_2_0_1_3_1_1 - 0.152380952380967*G0_1_1_2_0_1_4_1_0 - 0.152380952380967*G0_1_1_2_0_1_5_1_1 - 0.152380952380967*G0_1_1_3_1_0_0_0_0 - 0.152380952380967*G0_1_1_3_1_0_0_0_1 + 0.152380952380967*G0_1_1_3_1_0_1_0_0 + 0.152380952380967*G0_1_1_3_1_0_2_0_1 - 0.152380952380967*G0_1_1_3_1_0_3_1_0 - 0.152380952380967*G0_1_1_3_1_0_3_1_1 + 0.152380952380967*G0_1_1_3_1_0_4_1_0 + 0.152380952380967*G0_1_1_3_1_0_5_1_1 - 0.152380952380967*G0_1_1_3_1_1_0_0_0 - 0.152380952380967*G0_1_1_3_1_1_0_0_1 + 0.152380952380967*G0_1_1_3_1_1_1_0_0 + 0.152380952380967*G0_1_1_3_1_1_2_0_1 - 0.152380952380967*G0_1_1_3_1_1_3_1_0 - 0.152380952380967*G0_1_1_3_1_1_3_1_1 + 0.152380952380967*G0_1_1_3_1_1_4_1_0 + 0.152380952380967*G0_1_1_3_1_1_5_1_1 + 0.152380952380967*G0_1_1_4_1_0_0_0_0 + 0.152380952380967*G0_1_1_4_1_0_0_0_1 - 0.152380952380967*G0_1_1_4_1_0_1_0_0 - 0.152380952380967*G0_1_1_4_1_0_2_0_1 + 0.152380952380967*G0_1_1_4_1_0_3_1_0 + 0.152380952380967*G0_1_1_4_1_0_3_1_1 - 0.152380952380967*G0_1_1_4_1_0_4_1_0 - 0.152380952380967*G0_1_1_4_1_0_5_1_1 + 0.152380952380967*G0_1_1_5_1_1_0_0_0 + 0.152380952380967*G0_1_1_5_1_1_0_0_1 - 0.152380952380967*G0_1_1_5_1_1_1_0_0 - 0.152380952380967*G0_1_1_5_1_1_2_0_1 + 0.152380952380967*G0_1_1_5_1_1_3_1_0 + 0.152380952380967*G0_1_1_5_1_1_3_1_1 - 0.152380952380967*G0_1_1_5_1_1_4_1_0 - 0.152380952380967*G0_1_1_5_1_1_5_1_1; + A[173] = 0.0; + A[617] = -A[242] - 0.524867724867732*G0_1_1_0_0_0_0_0_0 - 0.524867724867732*G0_1_1_0_0_0_0_0_1 + 0.524867724867732*G0_1_1_0_0_0_1_0_0 + 0.524867724867732*G0_1_1_0_0_0_2_0_1 - 0.524867724867732*G0_1_1_0_0_0_3_1_0 - 0.524867724867732*G0_1_1_0_0_0_3_1_1 + 0.524867724867732*G0_1_1_0_0_0_4_1_0 + 0.524867724867732*G0_1_1_0_0_0_5_1_1 - 0.524867724867732*G0_1_1_0_0_1_0_0_0 - 0.524867724867732*G0_1_1_0_0_1_0_0_1 + 0.524867724867732*G0_1_1_0_0_1_1_0_0 + 0.524867724867732*G0_1_1_0_0_1_2_0_1 - 0.524867724867732*G0_1_1_0_0_1_3_1_0 - 0.524867724867732*G0_1_1_0_0_1_3_1_1 + 0.524867724867732*G0_1_1_0_0_1_4_1_0 + 0.524867724867732*G0_1_1_0_0_1_5_1_1 + 0.524867724867732*G0_1_1_1_0_0_0_0_0 + 0.524867724867732*G0_1_1_1_0_0_0_0_1 - 0.524867724867732*G0_1_1_1_0_0_1_0_0 - 0.524867724867732*G0_1_1_1_0_0_2_0_1 + 0.524867724867732*G0_1_1_1_0_0_3_1_0 + 0.524867724867732*G0_1_1_1_0_0_3_1_1 - 0.524867724867732*G0_1_1_1_0_0_4_1_0 - 0.524867724867732*G0_1_1_1_0_0_5_1_1 + 0.524867724867732*G0_1_1_2_0_1_0_0_0 + 0.524867724867732*G0_1_1_2_0_1_0_0_1 - 0.524867724867732*G0_1_1_2_0_1_1_0_0 - 0.524867724867732*G0_1_1_2_0_1_2_0_1 + 0.524867724867732*G0_1_1_2_0_1_3_1_0 + 0.524867724867732*G0_1_1_2_0_1_3_1_1 - 0.524867724867732*G0_1_1_2_0_1_4_1_0 - 0.524867724867732*G0_1_1_2_0_1_5_1_1 - 0.524867724867732*G0_1_1_3_1_0_0_0_0 - 0.524867724867732*G0_1_1_3_1_0_0_0_1 + 0.524867724867732*G0_1_1_3_1_0_1_0_0 + 0.524867724867732*G0_1_1_3_1_0_2_0_1 - 0.524867724867732*G0_1_1_3_1_0_3_1_0 - 0.524867724867732*G0_1_1_3_1_0_3_1_1 + 0.524867724867732*G0_1_1_3_1_0_4_1_0 + 0.524867724867732*G0_1_1_3_1_0_5_1_1 - 0.524867724867732*G0_1_1_3_1_1_0_0_0 - 0.524867724867732*G0_1_1_3_1_1_0_0_1 + 0.524867724867732*G0_1_1_3_1_1_1_0_0 + 0.524867724867732*G0_1_1_3_1_1_2_0_1 - 0.524867724867732*G0_1_1_3_1_1_3_1_0 - 0.524867724867732*G0_1_1_3_1_1_3_1_1 + 0.524867724867732*G0_1_1_3_1_1_4_1_0 + 0.524867724867732*G0_1_1_3_1_1_5_1_1 + 0.524867724867732*G0_1_1_4_1_0_0_0_0 + 0.524867724867732*G0_1_1_4_1_0_0_0_1 - 0.524867724867732*G0_1_1_4_1_0_1_0_0 - 0.524867724867732*G0_1_1_4_1_0_2_0_1 + 0.524867724867732*G0_1_1_4_1_0_3_1_0 + 0.524867724867732*G0_1_1_4_1_0_3_1_1 - 0.524867724867732*G0_1_1_4_1_0_4_1_0 - 0.524867724867732*G0_1_1_4_1_0_5_1_1 + 0.524867724867732*G0_1_1_5_1_1_0_0_0 + 0.524867724867732*G0_1_1_5_1_1_0_0_1 - 0.524867724867732*G0_1_1_5_1_1_1_0_0 - 0.524867724867732*G0_1_1_5_1_1_2_0_1 + 0.524867724867732*G0_1_1_5_1_1_3_1_0 + 0.524867724867732*G0_1_1_5_1_1_3_1_1 - 0.524867724867732*G0_1_1_5_1_1_4_1_0 - 0.524867724867732*G0_1_1_5_1_1_5_1_1; + A[541] = 0.0; + A[497] = -0.0566137566137575*G0_0_1_0_0_0_0_0_0 - 0.0566137566137575*G0_0_1_0_0_0_0_0_1 + 0.0566137566137575*G0_0_1_0_0_0_1_0_0 + 0.0566137566137575*G0_0_1_0_0_0_2_0_1 - 0.0566137566137575*G0_0_1_0_0_0_3_1_0 - 0.0566137566137575*G0_0_1_0_0_0_3_1_1 + 0.0566137566137575*G0_0_1_0_0_0_4_1_0 + 0.0566137566137575*G0_0_1_0_0_0_5_1_1 - 0.0566137566137575*G0_0_1_0_0_1_0_0_0 - 0.0566137566137575*G0_0_1_0_0_1_0_0_1 + 0.0566137566137575*G0_0_1_0_0_1_1_0_0 + 0.0566137566137575*G0_0_1_0_0_1_2_0_1 - 0.0566137566137575*G0_0_1_0_0_1_3_1_0 - 0.0566137566137575*G0_0_1_0_0_1_3_1_1 + 0.0566137566137575*G0_0_1_0_0_1_4_1_0 + 0.0566137566137575*G0_0_1_0_0_1_5_1_1 + 0.0566137566137575*G0_0_1_1_0_0_0_0_0 + 0.0566137566137575*G0_0_1_1_0_0_0_0_1 - 0.0566137566137575*G0_0_1_1_0_0_1_0_0 - 0.0566137566137575*G0_0_1_1_0_0_2_0_1 + 0.0566137566137575*G0_0_1_1_0_0_3_1_0 + 0.0566137566137575*G0_0_1_1_0_0_3_1_1 - 0.0566137566137575*G0_0_1_1_0_0_4_1_0 - 0.0566137566137575*G0_0_1_1_0_0_5_1_1 + 0.0566137566137575*G0_0_1_2_0_1_0_0_0 + 0.0566137566137575*G0_0_1_2_0_1_0_0_1 - 0.0566137566137575*G0_0_1_2_0_1_1_0_0 - 0.0566137566137575*G0_0_1_2_0_1_2_0_1 + 0.0566137566137575*G0_0_1_2_0_1_3_1_0 + 0.0566137566137575*G0_0_1_2_0_1_3_1_1 - 0.0566137566137575*G0_0_1_2_0_1_4_1_0 - 0.0566137566137575*G0_0_1_2_0_1_5_1_1 - 0.0566137566137575*G0_0_1_3_1_0_0_0_0 - 0.0566137566137575*G0_0_1_3_1_0_0_0_1 + 0.0566137566137575*G0_0_1_3_1_0_1_0_0 + 0.0566137566137575*G0_0_1_3_1_0_2_0_1 - 0.0566137566137575*G0_0_1_3_1_0_3_1_0 - 0.0566137566137575*G0_0_1_3_1_0_3_1_1 + 0.0566137566137575*G0_0_1_3_1_0_4_1_0 + 0.0566137566137575*G0_0_1_3_1_0_5_1_1 - 0.0566137566137575*G0_0_1_3_1_1_0_0_0 - 0.0566137566137575*G0_0_1_3_1_1_0_0_1 + 0.0566137566137575*G0_0_1_3_1_1_1_0_0 + 0.0566137566137575*G0_0_1_3_1_1_2_0_1 - 0.0566137566137575*G0_0_1_3_1_1_3_1_0 - 0.0566137566137575*G0_0_1_3_1_1_3_1_1 + 0.0566137566137575*G0_0_1_3_1_1_4_1_0 + 0.0566137566137575*G0_0_1_3_1_1_5_1_1 + 0.0566137566137575*G0_0_1_4_1_0_0_0_0 + 0.0566137566137575*G0_0_1_4_1_0_0_0_1 - 0.0566137566137575*G0_0_1_4_1_0_1_0_0 - 0.0566137566137575*G0_0_1_4_1_0_2_0_1 + 0.0566137566137575*G0_0_1_4_1_0_3_1_0 + 0.0566137566137575*G0_0_1_4_1_0_3_1_1 - 0.0566137566137575*G0_0_1_4_1_0_4_1_0 - 0.0566137566137575*G0_0_1_4_1_0_5_1_1 + 0.0566137566137575*G0_0_1_5_1_1_0_0_0 + 0.0566137566137575*G0_0_1_5_1_1_0_0_1 - 0.0566137566137575*G0_0_1_5_1_1_1_0_0 - 0.0566137566137575*G0_0_1_5_1_1_2_0_1 + 0.0566137566137575*G0_0_1_5_1_1_3_1_0 + 0.0566137566137575*G0_0_1_5_1_1_3_1_1 - 0.0566137566137575*G0_0_1_5_1_1_4_1_0 - 0.0566137566137575*G0_0_1_5_1_1_5_1_1; + A[30] = -A[497] + 0.0566137566137574*G0_0_0_0_0_0_0_0_0 + 0.0566137566137574*G0_0_0_0_0_0_0_0_1 - 0.0566137566137574*G0_0_0_0_0_0_1_0_0 - 0.0566137566137574*G0_0_0_0_0_0_2_0_1 + 0.0566137566137574*G0_0_0_0_0_0_3_1_0 + 0.0566137566137574*G0_0_0_0_0_0_3_1_1 - 0.0566137566137574*G0_0_0_0_0_0_4_1_0 - 0.0566137566137574*G0_0_0_0_0_0_5_1_1 + 0.0566137566137574*G0_0_0_0_0_1_0_0_0 + 0.0566137566137574*G0_0_0_0_0_1_0_0_1 - 0.0566137566137574*G0_0_0_0_0_1_1_0_0 - 0.0566137566137574*G0_0_0_0_0_1_2_0_1 + 0.0566137566137574*G0_0_0_0_0_1_3_1_0 + 0.0566137566137574*G0_0_0_0_0_1_3_1_1 - 0.0566137566137574*G0_0_0_0_0_1_4_1_0 - 0.0566137566137574*G0_0_0_0_0_1_5_1_1 - 0.0566137566137574*G0_0_0_1_0_0_0_0_0 - 0.0566137566137574*G0_0_0_1_0_0_0_0_1 + 0.0566137566137574*G0_0_0_1_0_0_1_0_0 + 0.0566137566137574*G0_0_0_1_0_0_2_0_1 - 0.0566137566137574*G0_0_0_1_0_0_3_1_0 - 0.0566137566137574*G0_0_0_1_0_0_3_1_1 + 0.0566137566137574*G0_0_0_1_0_0_4_1_0 + 0.0566137566137574*G0_0_0_1_0_0_5_1_1 - 0.0566137566137574*G0_0_0_2_0_1_0_0_0 - 0.0566137566137574*G0_0_0_2_0_1_0_0_1 + 0.0566137566137574*G0_0_0_2_0_1_1_0_0 + 0.0566137566137574*G0_0_0_2_0_1_2_0_1 - 0.0566137566137574*G0_0_0_2_0_1_3_1_0 - 0.0566137566137574*G0_0_0_2_0_1_3_1_1 + 0.0566137566137574*G0_0_0_2_0_1_4_1_0 + 0.0566137566137574*G0_0_0_2_0_1_5_1_1 + 0.0566137566137574*G0_0_0_3_1_0_0_0_0 + 0.0566137566137574*G0_0_0_3_1_0_0_0_1 - 0.0566137566137574*G0_0_0_3_1_0_1_0_0 - 0.0566137566137574*G0_0_0_3_1_0_2_0_1 + 0.0566137566137574*G0_0_0_3_1_0_3_1_0 + 0.0566137566137574*G0_0_0_3_1_0_3_1_1 - 0.0566137566137574*G0_0_0_3_1_0_4_1_0 - 0.0566137566137574*G0_0_0_3_1_0_5_1_1 + 0.0566137566137574*G0_0_0_3_1_1_0_0_0 + 0.0566137566137574*G0_0_0_3_1_1_0_0_1 - 0.0566137566137574*G0_0_0_3_1_1_1_0_0 - 0.0566137566137574*G0_0_0_3_1_1_2_0_1 + 0.0566137566137574*G0_0_0_3_1_1_3_1_0 + 0.0566137566137574*G0_0_0_3_1_1_3_1_1 - 0.0566137566137574*G0_0_0_3_1_1_4_1_0 - 0.0566137566137574*G0_0_0_3_1_1_5_1_1 - 0.0566137566137574*G0_0_0_4_1_0_0_0_0 - 0.0566137566137574*G0_0_0_4_1_0_0_0_1 + 0.0566137566137574*G0_0_0_4_1_0_1_0_0 + 0.0566137566137574*G0_0_0_4_1_0_2_0_1 - 0.0566137566137574*G0_0_0_4_1_0_3_1_0 - 0.0566137566137574*G0_0_0_4_1_0_3_1_1 + 0.0566137566137574*G0_0_0_4_1_0_4_1_0 + 0.0566137566137574*G0_0_0_4_1_0_5_1_1 - 0.0566137566137574*G0_0_0_5_1_1_0_0_0 - 0.0566137566137574*G0_0_0_5_1_1_0_0_1 + 0.0566137566137574*G0_0_0_5_1_1_1_0_0 + 0.0566137566137574*G0_0_0_5_1_1_2_0_1 - 0.0566137566137574*G0_0_0_5_1_1_3_1_0 - 0.0566137566137574*G0_0_0_5_1_1_3_1_1 + 0.0566137566137574*G0_0_0_5_1_1_4_1_0 + 0.0566137566137574*G0_0_0_5_1_1_5_1_1; + A[2] = -A[497] + 0.0566137566137576*G0_1_1_0_0_0_0_0_0 + 0.0566137566137576*G0_1_1_0_0_0_0_0_1 - 0.0566137566137576*G0_1_1_0_0_0_1_0_0 - 0.0566137566137576*G0_1_1_0_0_0_2_0_1 + 0.0566137566137576*G0_1_1_0_0_0_3_1_0 + 0.0566137566137576*G0_1_1_0_0_0_3_1_1 - 0.0566137566137576*G0_1_1_0_0_0_4_1_0 - 0.0566137566137576*G0_1_1_0_0_0_5_1_1 + 0.0566137566137576*G0_1_1_0_0_1_0_0_0 + 0.0566137566137576*G0_1_1_0_0_1_0_0_1 - 0.0566137566137576*G0_1_1_0_0_1_1_0_0 - 0.0566137566137576*G0_1_1_0_0_1_2_0_1 + 0.0566137566137576*G0_1_1_0_0_1_3_1_0 + 0.0566137566137576*G0_1_1_0_0_1_3_1_1 - 0.0566137566137576*G0_1_1_0_0_1_4_1_0 - 0.0566137566137576*G0_1_1_0_0_1_5_1_1 - 0.0566137566137576*G0_1_1_1_0_0_0_0_0 - 0.0566137566137576*G0_1_1_1_0_0_0_0_1 + 0.0566137566137576*G0_1_1_1_0_0_1_0_0 + 0.0566137566137576*G0_1_1_1_0_0_2_0_1 - 0.0566137566137576*G0_1_1_1_0_0_3_1_0 - 0.0566137566137576*G0_1_1_1_0_0_3_1_1 + 0.0566137566137576*G0_1_1_1_0_0_4_1_0 + 0.0566137566137576*G0_1_1_1_0_0_5_1_1 - 0.0566137566137576*G0_1_1_2_0_1_0_0_0 - 0.0566137566137576*G0_1_1_2_0_1_0_0_1 + 0.0566137566137576*G0_1_1_2_0_1_1_0_0 + 0.0566137566137576*G0_1_1_2_0_1_2_0_1 - 0.0566137566137576*G0_1_1_2_0_1_3_1_0 - 0.0566137566137576*G0_1_1_2_0_1_3_1_1 + 0.0566137566137576*G0_1_1_2_0_1_4_1_0 + 0.0566137566137576*G0_1_1_2_0_1_5_1_1 + 0.0566137566137576*G0_1_1_3_1_0_0_0_0 + 0.0566137566137576*G0_1_1_3_1_0_0_0_1 - 0.0566137566137576*G0_1_1_3_1_0_1_0_0 - 0.0566137566137576*G0_1_1_3_1_0_2_0_1 + 0.0566137566137576*G0_1_1_3_1_0_3_1_0 + 0.0566137566137576*G0_1_1_3_1_0_3_1_1 - 0.0566137566137576*G0_1_1_3_1_0_4_1_0 - 0.0566137566137576*G0_1_1_3_1_0_5_1_1 + 0.0566137566137576*G0_1_1_3_1_1_0_0_0 + 0.0566137566137576*G0_1_1_3_1_1_0_0_1 - 0.0566137566137576*G0_1_1_3_1_1_1_0_0 - 0.0566137566137576*G0_1_1_3_1_1_2_0_1 + 0.0566137566137576*G0_1_1_3_1_1_3_1_0 + 0.0566137566137576*G0_1_1_3_1_1_3_1_1 - 0.0566137566137576*G0_1_1_3_1_1_4_1_0 - 0.0566137566137576*G0_1_1_3_1_1_5_1_1 - 0.0566137566137576*G0_1_1_4_1_0_0_0_0 - 0.0566137566137576*G0_1_1_4_1_0_0_0_1 + 0.0566137566137576*G0_1_1_4_1_0_1_0_0 + 0.0566137566137576*G0_1_1_4_1_0_2_0_1 - 0.0566137566137576*G0_1_1_4_1_0_3_1_0 - 0.0566137566137576*G0_1_1_4_1_0_3_1_1 + 0.0566137566137576*G0_1_1_4_1_0_4_1_0 + 0.0566137566137576*G0_1_1_4_1_0_5_1_1 - 0.0566137566137576*G0_1_1_5_1_1_0_0_0 - 0.0566137566137576*G0_1_1_5_1_1_0_0_1 + 0.0566137566137576*G0_1_1_5_1_1_1_0_0 + 0.0566137566137576*G0_1_1_5_1_1_2_0_1 - 0.0566137566137576*G0_1_1_5_1_1_3_1_0 - 0.0566137566137576*G0_1_1_5_1_1_3_1_1 + 0.0566137566137576*G0_1_1_5_1_1_4_1_0 + 0.0566137566137576*G0_1_1_5_1_1_5_1_1; + A[650] = A[621]; + A[538] = A[887]; + A[687] = A[367]; + A[567] = A[569]; + A[692] = 0.0; + A[269] = 0.0; + A[294] = 0.0; + A[443] = 0.0; + A[363] = A[569]; + A[779] = A[314]; + A[472] = A[7]; + A[392] = A[887]; + A[806] = -A[101] + 1.69312169312171*G0_0_0_0_0_0_0_0_0 + 1.69312169312171*G0_0_0_0_0_0_0_0_1 - 1.69312169312171*G0_0_0_0_0_0_1_0_0 - 1.69312169312171*G0_0_0_0_0_0_2_0_1 + 1.69312169312171*G0_0_0_0_0_0_3_1_0 + 1.69312169312171*G0_0_0_0_0_0_3_1_1 - 1.69312169312171*G0_0_0_0_0_0_4_1_0 - 1.69312169312171*G0_0_0_0_0_0_5_1_1 + 1.69312169312171*G0_0_0_0_0_1_0_0_0 + 1.69312169312171*G0_0_0_0_0_1_0_0_1 - 1.69312169312171*G0_0_0_0_0_1_1_0_0 - 1.69312169312171*G0_0_0_0_0_1_2_0_1 + 1.69312169312171*G0_0_0_0_0_1_3_1_0 + 1.69312169312171*G0_0_0_0_0_1_3_1_1 - 1.69312169312171*G0_0_0_0_0_1_4_1_0 - 1.69312169312171*G0_0_0_0_0_1_5_1_1 - 1.69312169312171*G0_0_0_1_0_0_0_0_0 - 1.69312169312171*G0_0_0_1_0_0_0_0_1 + 1.69312169312171*G0_0_0_1_0_0_1_0_0 + 1.69312169312171*G0_0_0_1_0_0_2_0_1 - 1.69312169312171*G0_0_0_1_0_0_3_1_0 - 1.69312169312171*G0_0_0_1_0_0_3_1_1 + 1.69312169312171*G0_0_0_1_0_0_4_1_0 + 1.69312169312171*G0_0_0_1_0_0_5_1_1 - 1.69312169312171*G0_0_0_2_0_1_0_0_0 - 1.69312169312171*G0_0_0_2_0_1_0_0_1 + 1.69312169312171*G0_0_0_2_0_1_1_0_0 + 1.69312169312171*G0_0_0_2_0_1_2_0_1 - 1.69312169312171*G0_0_0_2_0_1_3_1_0 - 1.69312169312171*G0_0_0_2_0_1_3_1_1 + 1.69312169312171*G0_0_0_2_0_1_4_1_0 + 1.69312169312171*G0_0_0_2_0_1_5_1_1 + 1.69312169312171*G0_0_0_3_1_0_0_0_0 + 1.69312169312171*G0_0_0_3_1_0_0_0_1 - 1.69312169312171*G0_0_0_3_1_0_1_0_0 - 1.69312169312171*G0_0_0_3_1_0_2_0_1 + 1.69312169312171*G0_0_0_3_1_0_3_1_0 + 1.69312169312171*G0_0_0_3_1_0_3_1_1 - 1.69312169312171*G0_0_0_3_1_0_4_1_0 - 1.69312169312171*G0_0_0_3_1_0_5_1_1 + 1.69312169312171*G0_0_0_3_1_1_0_0_0 + 1.69312169312171*G0_0_0_3_1_1_0_0_1 - 1.69312169312171*G0_0_0_3_1_1_1_0_0 - 1.69312169312171*G0_0_0_3_1_1_2_0_1 + 1.69312169312171*G0_0_0_3_1_1_3_1_0 + 1.69312169312171*G0_0_0_3_1_1_3_1_1 - 1.69312169312171*G0_0_0_3_1_1_4_1_0 - 1.69312169312171*G0_0_0_3_1_1_5_1_1 - 1.69312169312171*G0_0_0_4_1_0_0_0_0 - 1.69312169312171*G0_0_0_4_1_0_0_0_1 + 1.69312169312171*G0_0_0_4_1_0_1_0_0 + 1.69312169312171*G0_0_0_4_1_0_2_0_1 - 1.69312169312171*G0_0_0_4_1_0_3_1_0 - 1.69312169312171*G0_0_0_4_1_0_3_1_1 + 1.69312169312171*G0_0_0_4_1_0_4_1_0 + 1.69312169312171*G0_0_0_4_1_0_5_1_1 - 1.69312169312171*G0_0_0_5_1_1_0_0_0 - 1.69312169312171*G0_0_0_5_1_1_0_0_1 + 1.69312169312171*G0_0_0_5_1_1_1_0_0 + 1.69312169312171*G0_0_0_5_1_1_2_0_1 - 1.69312169312171*G0_0_0_5_1_1_3_1_0 - 1.69312169312171*G0_0_0_5_1_1_3_1_1 + 1.69312169312171*G0_0_0_5_1_1_4_1_0 + 1.69312169312171*G0_0_0_5_1_1_5_1_1; + A[25] = 0.0; + A[726] = 0.0; + A[385] = 0.0; + A[829] = A[132]; + A[34] = A[181] - 0.42539682539683*G0_0_1_0_0_0_0_0_0 - 0.42539682539683*G0_0_1_0_0_0_0_0_1 + 0.42539682539683*G0_0_1_0_0_0_1_0_0 + 0.42539682539683*G0_0_1_0_0_0_2_0_1 - 0.42539682539683*G0_0_1_0_0_0_3_1_0 - 0.42539682539683*G0_0_1_0_0_0_3_1_1 + 0.42539682539683*G0_0_1_0_0_0_4_1_0 + 0.42539682539683*G0_0_1_0_0_0_5_1_1 - 0.42539682539683*G0_0_1_0_0_1_0_0_0 - 0.42539682539683*G0_0_1_0_0_1_0_0_1 + 0.42539682539683*G0_0_1_0_0_1_1_0_0 + 0.42539682539683*G0_0_1_0_0_1_2_0_1 - 0.42539682539683*G0_0_1_0_0_1_3_1_0 - 0.42539682539683*G0_0_1_0_0_1_3_1_1 + 0.42539682539683*G0_0_1_0_0_1_4_1_0 + 0.42539682539683*G0_0_1_0_0_1_5_1_1 + 0.42539682539683*G0_0_1_1_0_0_0_0_0 + 0.42539682539683*G0_0_1_1_0_0_0_0_1 - 0.42539682539683*G0_0_1_1_0_0_1_0_0 - 0.42539682539683*G0_0_1_1_0_0_2_0_1 + 0.42539682539683*G0_0_1_1_0_0_3_1_0 + 0.42539682539683*G0_0_1_1_0_0_3_1_1 - 0.42539682539683*G0_0_1_1_0_0_4_1_0 - 0.42539682539683*G0_0_1_1_0_0_5_1_1 + 0.42539682539683*G0_0_1_2_0_1_0_0_0 + 0.42539682539683*G0_0_1_2_0_1_0_0_1 - 0.42539682539683*G0_0_1_2_0_1_1_0_0 - 0.42539682539683*G0_0_1_2_0_1_2_0_1 + 0.42539682539683*G0_0_1_2_0_1_3_1_0 + 0.42539682539683*G0_0_1_2_0_1_3_1_1 - 0.42539682539683*G0_0_1_2_0_1_4_1_0 - 0.42539682539683*G0_0_1_2_0_1_5_1_1 - 0.42539682539683*G0_0_1_3_1_0_0_0_0 - 0.42539682539683*G0_0_1_3_1_0_0_0_1 + 0.42539682539683*G0_0_1_3_1_0_1_0_0 + 0.42539682539683*G0_0_1_3_1_0_2_0_1 - 0.42539682539683*G0_0_1_3_1_0_3_1_0 - 0.42539682539683*G0_0_1_3_1_0_3_1_1 + 0.42539682539683*G0_0_1_3_1_0_4_1_0 + 0.42539682539683*G0_0_1_3_1_0_5_1_1 - 0.42539682539683*G0_0_1_3_1_1_0_0_0 - 0.42539682539683*G0_0_1_3_1_1_0_0_1 + 0.42539682539683*G0_0_1_3_1_1_1_0_0 + 0.42539682539683*G0_0_1_3_1_1_2_0_1 - 0.42539682539683*G0_0_1_3_1_1_3_1_0 - 0.42539682539683*G0_0_1_3_1_1_3_1_1 + 0.42539682539683*G0_0_1_3_1_1_4_1_0 + 0.42539682539683*G0_0_1_3_1_1_5_1_1 + 0.42539682539683*G0_0_1_4_1_0_0_0_0 + 0.42539682539683*G0_0_1_4_1_0_0_0_1 - 0.42539682539683*G0_0_1_4_1_0_1_0_0 - 0.42539682539683*G0_0_1_4_1_0_2_0_1 + 0.42539682539683*G0_0_1_4_1_0_3_1_0 + 0.42539682539683*G0_0_1_4_1_0_3_1_1 - 0.42539682539683*G0_0_1_4_1_0_4_1_0 - 0.42539682539683*G0_0_1_4_1_0_5_1_1 + 0.42539682539683*G0_0_1_5_1_1_0_0_0 + 0.42539682539683*G0_0_1_5_1_1_0_0_1 - 0.42539682539683*G0_0_1_5_1_1_1_0_0 - 0.42539682539683*G0_0_1_5_1_1_2_0_1 + 0.42539682539683*G0_0_1_5_1_1_3_1_0 + 0.42539682539683*G0_0_1_5_1_1_3_1_1 - 0.42539682539683*G0_0_1_5_1_1_4_1_0 - 0.42539682539683*G0_0_1_5_1_1_5_1_1; + A[40] = -A[34] + 0.510052910052917*G0_0_0_0_0_0_0_0_0 + 0.510052910052917*G0_0_0_0_0_0_0_0_1 - 0.510052910052917*G0_0_0_0_0_0_1_0_0 - 0.510052910052917*G0_0_0_0_0_0_2_0_1 + 0.510052910052917*G0_0_0_0_0_0_3_1_0 + 0.510052910052917*G0_0_0_0_0_0_3_1_1 - 0.510052910052917*G0_0_0_0_0_0_4_1_0 - 0.510052910052917*G0_0_0_0_0_0_5_1_1 + 0.510052910052917*G0_0_0_0_0_1_0_0_0 + 0.510052910052917*G0_0_0_0_0_1_0_0_1 - 0.510052910052917*G0_0_0_0_0_1_1_0_0 - 0.510052910052917*G0_0_0_0_0_1_2_0_1 + 0.510052910052917*G0_0_0_0_0_1_3_1_0 + 0.510052910052917*G0_0_0_0_0_1_3_1_1 - 0.510052910052917*G0_0_0_0_0_1_4_1_0 - 0.510052910052917*G0_0_0_0_0_1_5_1_1 - 0.510052910052917*G0_0_0_1_0_0_0_0_0 - 0.510052910052917*G0_0_0_1_0_0_0_0_1 + 0.510052910052917*G0_0_0_1_0_0_1_0_0 + 0.510052910052917*G0_0_0_1_0_0_2_0_1 - 0.510052910052917*G0_0_0_1_0_0_3_1_0 - 0.510052910052917*G0_0_0_1_0_0_3_1_1 + 0.510052910052917*G0_0_0_1_0_0_4_1_0 + 0.510052910052917*G0_0_0_1_0_0_5_1_1 - 0.510052910052917*G0_0_0_2_0_1_0_0_0 - 0.510052910052917*G0_0_0_2_0_1_0_0_1 + 0.510052910052917*G0_0_0_2_0_1_1_0_0 + 0.510052910052917*G0_0_0_2_0_1_2_0_1 - 0.510052910052917*G0_0_0_2_0_1_3_1_0 - 0.510052910052917*G0_0_0_2_0_1_3_1_1 + 0.510052910052917*G0_0_0_2_0_1_4_1_0 + 0.510052910052917*G0_0_0_2_0_1_5_1_1 + 0.510052910052917*G0_0_0_3_1_0_0_0_0 + 0.510052910052917*G0_0_0_3_1_0_0_0_1 - 0.510052910052917*G0_0_0_3_1_0_1_0_0 - 0.510052910052917*G0_0_0_3_1_0_2_0_1 + 0.510052910052917*G0_0_0_3_1_0_3_1_0 + 0.510052910052917*G0_0_0_3_1_0_3_1_1 - 0.510052910052917*G0_0_0_3_1_0_4_1_0 - 0.510052910052917*G0_0_0_3_1_0_5_1_1 + 0.510052910052917*G0_0_0_3_1_1_0_0_0 + 0.510052910052917*G0_0_0_3_1_1_0_0_1 - 0.510052910052917*G0_0_0_3_1_1_1_0_0 - 0.510052910052917*G0_0_0_3_1_1_2_0_1 + 0.510052910052917*G0_0_0_3_1_1_3_1_0 + 0.510052910052917*G0_0_0_3_1_1_3_1_1 - 0.510052910052917*G0_0_0_3_1_1_4_1_0 - 0.510052910052917*G0_0_0_3_1_1_5_1_1 - 0.510052910052917*G0_0_0_4_1_0_0_0_0 - 0.510052910052917*G0_0_0_4_1_0_0_0_1 + 0.510052910052917*G0_0_0_4_1_0_1_0_0 + 0.510052910052917*G0_0_0_4_1_0_2_0_1 - 0.510052910052917*G0_0_0_4_1_0_3_1_0 - 0.510052910052917*G0_0_0_4_1_0_3_1_1 + 0.510052910052917*G0_0_0_4_1_0_4_1_0 + 0.510052910052917*G0_0_0_4_1_0_5_1_1 - 0.510052910052917*G0_0_0_5_1_1_0_0_0 - 0.510052910052917*G0_0_0_5_1_1_0_0_1 + 0.510052910052917*G0_0_0_5_1_1_1_0_0 + 0.510052910052917*G0_0_0_5_1_1_2_0_1 - 0.510052910052917*G0_0_0_5_1_1_3_1_0 - 0.510052910052917*G0_0_0_5_1_1_3_1_1 + 0.510052910052917*G0_0_0_5_1_1_4_1_0 + 0.510052910052917*G0_0_0_5_1_1_5_1_1; + A[757] = 0.0; + A[418] = 0.0; + A[860] = A[628]; + A[63] = -A[534] + 0.203174603174605*G0_1_0_0_0_0_0_0_0 + 0.203174603174605*G0_1_0_0_0_0_0_0_1 - 0.203174603174605*G0_1_0_0_0_0_1_0_0 - 0.203174603174605*G0_1_0_0_0_0_2_0_1 + 0.203174603174605*G0_1_0_0_0_0_3_1_0 + 0.203174603174605*G0_1_0_0_0_0_3_1_1 - 0.203174603174605*G0_1_0_0_0_0_4_1_0 - 0.203174603174605*G0_1_0_0_0_0_5_1_1 + 0.203174603174605*G0_1_0_0_0_1_0_0_0 + 0.203174603174605*G0_1_0_0_0_1_0_0_1 - 0.203174603174605*G0_1_0_0_0_1_1_0_0 - 0.203174603174605*G0_1_0_0_0_1_2_0_1 + 0.203174603174605*G0_1_0_0_0_1_3_1_0 + 0.203174603174605*G0_1_0_0_0_1_3_1_1 - 0.203174603174605*G0_1_0_0_0_1_4_1_0 - 0.203174603174605*G0_1_0_0_0_1_5_1_1 - 0.203174603174605*G0_1_0_1_0_0_0_0_0 - 0.203174603174605*G0_1_0_1_0_0_0_0_1 + 0.203174603174605*G0_1_0_1_0_0_1_0_0 + 0.203174603174605*G0_1_0_1_0_0_2_0_1 - 0.203174603174605*G0_1_0_1_0_0_3_1_0 - 0.203174603174605*G0_1_0_1_0_0_3_1_1 + 0.203174603174605*G0_1_0_1_0_0_4_1_0 + 0.203174603174605*G0_1_0_1_0_0_5_1_1 - 0.203174603174605*G0_1_0_2_0_1_0_0_0 - 0.203174603174605*G0_1_0_2_0_1_0_0_1 + 0.203174603174605*G0_1_0_2_0_1_1_0_0 + 0.203174603174605*G0_1_0_2_0_1_2_0_1 - 0.203174603174605*G0_1_0_2_0_1_3_1_0 - 0.203174603174605*G0_1_0_2_0_1_3_1_1 + 0.203174603174605*G0_1_0_2_0_1_4_1_0 + 0.203174603174605*G0_1_0_2_0_1_5_1_1 + 0.203174603174605*G0_1_0_3_1_0_0_0_0 + 0.203174603174605*G0_1_0_3_1_0_0_0_1 - 0.203174603174605*G0_1_0_3_1_0_1_0_0 - 0.203174603174605*G0_1_0_3_1_0_2_0_1 + 0.203174603174605*G0_1_0_3_1_0_3_1_0 + 0.203174603174605*G0_1_0_3_1_0_3_1_1 - 0.203174603174605*G0_1_0_3_1_0_4_1_0 - 0.203174603174605*G0_1_0_3_1_0_5_1_1 + 0.203174603174605*G0_1_0_3_1_1_0_0_0 + 0.203174603174605*G0_1_0_3_1_1_0_0_1 - 0.203174603174605*G0_1_0_3_1_1_1_0_0 - 0.203174603174605*G0_1_0_3_1_1_2_0_1 + 0.203174603174605*G0_1_0_3_1_1_3_1_0 + 0.203174603174605*G0_1_0_3_1_1_3_1_1 - 0.203174603174605*G0_1_0_3_1_1_4_1_0 - 0.203174603174605*G0_1_0_3_1_1_5_1_1 - 0.203174603174605*G0_1_0_4_1_0_0_0_0 - 0.203174603174605*G0_1_0_4_1_0_0_0_1 + 0.203174603174605*G0_1_0_4_1_0_1_0_0 + 0.203174603174605*G0_1_0_4_1_0_2_0_1 - 0.203174603174605*G0_1_0_4_1_0_3_1_0 - 0.203174603174605*G0_1_0_4_1_0_3_1_1 + 0.203174603174605*G0_1_0_4_1_0_4_1_0 + 0.203174603174605*G0_1_0_4_1_0_5_1_1 - 0.203174603174605*G0_1_0_5_1_1_0_0_0 - 0.203174603174605*G0_1_0_5_1_1_0_0_1 + 0.203174603174605*G0_1_0_5_1_1_1_0_0 + 0.203174603174605*G0_1_0_5_1_1_2_0_1 - 0.203174603174605*G0_1_0_5_1_1_3_1_0 - 0.203174603174605*G0_1_0_5_1_1_3_1_1 + 0.203174603174605*G0_1_0_5_1_1_4_1_0 + 0.203174603174605*G0_1_0_5_1_1_5_1_1; + A[784] = 0.0; + A[895] = A[314]; + A[116] = 0.0; + A[819] = 0.0; + A[185] = A[621]; + A[149] = 0.0; + A[210] = A[5] + 0.425396825396829*G0_1_0_0_0_0_0_0_0 + 0.425396825396829*G0_1_0_0_0_0_0_0_1 - 0.425396825396829*G0_1_0_0_0_0_1_0_0 - 0.425396825396829*G0_1_0_0_0_0_2_0_1 + 0.425396825396829*G0_1_0_0_0_0_3_1_0 + 0.425396825396829*G0_1_0_0_0_0_3_1_1 - 0.425396825396829*G0_1_0_0_0_0_4_1_0 - 0.425396825396829*G0_1_0_0_0_0_5_1_1 + 0.425396825396829*G0_1_0_0_0_1_0_0_0 + 0.425396825396829*G0_1_0_0_0_1_0_0_1 - 0.425396825396829*G0_1_0_0_0_1_1_0_0 - 0.425396825396829*G0_1_0_0_0_1_2_0_1 + 0.425396825396829*G0_1_0_0_0_1_3_1_0 + 0.425396825396829*G0_1_0_0_0_1_3_1_1 - 0.425396825396829*G0_1_0_0_0_1_4_1_0 - 0.425396825396829*G0_1_0_0_0_1_5_1_1 - 0.425396825396829*G0_1_0_1_0_0_0_0_0 - 0.425396825396829*G0_1_0_1_0_0_0_0_1 + 0.425396825396829*G0_1_0_1_0_0_1_0_0 + 0.425396825396829*G0_1_0_1_0_0_2_0_1 - 0.425396825396829*G0_1_0_1_0_0_3_1_0 - 0.425396825396829*G0_1_0_1_0_0_3_1_1 + 0.425396825396829*G0_1_0_1_0_0_4_1_0 + 0.425396825396829*G0_1_0_1_0_0_5_1_1 - 0.425396825396829*G0_1_0_2_0_1_0_0_0 - 0.425396825396829*G0_1_0_2_0_1_0_0_1 + 0.425396825396829*G0_1_0_2_0_1_1_0_0 + 0.425396825396829*G0_1_0_2_0_1_2_0_1 - 0.425396825396829*G0_1_0_2_0_1_3_1_0 - 0.425396825396829*G0_1_0_2_0_1_3_1_1 + 0.425396825396829*G0_1_0_2_0_1_4_1_0 + 0.425396825396829*G0_1_0_2_0_1_5_1_1 + 0.425396825396829*G0_1_0_3_1_0_0_0_0 + 0.425396825396829*G0_1_0_3_1_0_0_0_1 - 0.425396825396829*G0_1_0_3_1_0_1_0_0 - 0.425396825396829*G0_1_0_3_1_0_2_0_1 + 0.425396825396829*G0_1_0_3_1_0_3_1_0 + 0.425396825396829*G0_1_0_3_1_0_3_1_1 - 0.425396825396829*G0_1_0_3_1_0_4_1_0 - 0.425396825396829*G0_1_0_3_1_0_5_1_1 + 0.425396825396829*G0_1_0_3_1_1_0_0_0 + 0.425396825396829*G0_1_0_3_1_1_0_0_1 - 0.425396825396829*G0_1_0_3_1_1_1_0_0 - 0.425396825396829*G0_1_0_3_1_1_2_0_1 + 0.425396825396829*G0_1_0_3_1_1_3_1_0 + 0.425396825396829*G0_1_0_3_1_1_3_1_1 - 0.425396825396829*G0_1_0_3_1_1_4_1_0 - 0.425396825396829*G0_1_0_3_1_1_5_1_1 - 0.425396825396829*G0_1_0_4_1_0_0_0_0 - 0.425396825396829*G0_1_0_4_1_0_0_0_1 + 0.425396825396829*G0_1_0_4_1_0_1_0_0 + 0.425396825396829*G0_1_0_4_1_0_2_0_1 - 0.425396825396829*G0_1_0_4_1_0_3_1_0 - 0.425396825396829*G0_1_0_4_1_0_3_1_1 + 0.425396825396829*G0_1_0_4_1_0_4_1_0 + 0.425396825396829*G0_1_0_4_1_0_5_1_1 - 0.425396825396829*G0_1_0_5_1_1_0_0_0 - 0.425396825396829*G0_1_0_5_1_1_0_0_1 + 0.425396825396829*G0_1_0_5_1_1_1_0_0 + 0.425396825396829*G0_1_0_5_1_1_2_0_1 - 0.425396825396829*G0_1_0_5_1_1_3_1_0 - 0.425396825396829*G0_1_0_5_1_1_3_1_1 + 0.425396825396829*G0_1_0_5_1_1_4_1_0 + 0.425396825396829*G0_1_0_5_1_1_5_1_1 + 0.425396825396829*G0_1_1_0_0_0_0_0_0 + 0.425396825396829*G0_1_1_0_0_0_0_0_1 - 0.425396825396829*G0_1_1_0_0_0_1_0_0 - 0.425396825396829*G0_1_1_0_0_0_2_0_1 + 0.425396825396829*G0_1_1_0_0_0_3_1_0 + 0.425396825396829*G0_1_1_0_0_0_3_1_1 - 0.425396825396829*G0_1_1_0_0_0_4_1_0 - 0.425396825396829*G0_1_1_0_0_0_5_1_1 + 0.425396825396829*G0_1_1_0_0_1_0_0_0 + 0.425396825396829*G0_1_1_0_0_1_0_0_1 - 0.425396825396829*G0_1_1_0_0_1_1_0_0 - 0.425396825396829*G0_1_1_0_0_1_2_0_1 + 0.425396825396829*G0_1_1_0_0_1_3_1_0 + 0.425396825396829*G0_1_1_0_0_1_3_1_1 - 0.425396825396829*G0_1_1_0_0_1_4_1_0 - 0.425396825396829*G0_1_1_0_0_1_5_1_1 - 0.425396825396829*G0_1_1_1_0_0_0_0_0 - 0.425396825396829*G0_1_1_1_0_0_0_0_1 + 0.425396825396829*G0_1_1_1_0_0_1_0_0 + 0.425396825396829*G0_1_1_1_0_0_2_0_1 - 0.425396825396829*G0_1_1_1_0_0_3_1_0 - 0.425396825396829*G0_1_1_1_0_0_3_1_1 + 0.425396825396829*G0_1_1_1_0_0_4_1_0 + 0.425396825396829*G0_1_1_1_0_0_5_1_1 - 0.425396825396829*G0_1_1_2_0_1_0_0_0 - 0.425396825396829*G0_1_1_2_0_1_0_0_1 + 0.425396825396829*G0_1_1_2_0_1_1_0_0 + 0.425396825396829*G0_1_1_2_0_1_2_0_1 - 0.425396825396829*G0_1_1_2_0_1_3_1_0 - 0.425396825396829*G0_1_1_2_0_1_3_1_1 + 0.425396825396829*G0_1_1_2_0_1_4_1_0 + 0.425396825396829*G0_1_1_2_0_1_5_1_1 + 0.425396825396829*G0_1_1_3_1_0_0_0_0 + 0.425396825396829*G0_1_1_3_1_0_0_0_1 - 0.425396825396829*G0_1_1_3_1_0_1_0_0 - 0.425396825396829*G0_1_1_3_1_0_2_0_1 + 0.425396825396829*G0_1_1_3_1_0_3_1_0 + 0.425396825396829*G0_1_1_3_1_0_3_1_1 - 0.425396825396829*G0_1_1_3_1_0_4_1_0 - 0.425396825396829*G0_1_1_3_1_0_5_1_1 + 0.425396825396829*G0_1_1_3_1_1_0_0_0 + 0.425396825396829*G0_1_1_3_1_1_0_0_1 - 0.425396825396829*G0_1_1_3_1_1_1_0_0 - 0.425396825396829*G0_1_1_3_1_1_2_0_1 + 0.425396825396829*G0_1_1_3_1_1_3_1_0 + 0.425396825396829*G0_1_1_3_1_1_3_1_1 - 0.425396825396829*G0_1_1_3_1_1_4_1_0 - 0.425396825396829*G0_1_1_3_1_1_5_1_1 - 0.425396825396829*G0_1_1_4_1_0_0_0_0 - 0.425396825396829*G0_1_1_4_1_0_0_0_1 + 0.425396825396829*G0_1_1_4_1_0_1_0_0 + 0.425396825396829*G0_1_1_4_1_0_2_0_1 - 0.425396825396829*G0_1_1_4_1_0_3_1_0 - 0.425396825396829*G0_1_1_4_1_0_3_1_1 + 0.425396825396829*G0_1_1_4_1_0_4_1_0 + 0.425396825396829*G0_1_1_4_1_0_5_1_1 - 0.425396825396829*G0_1_1_5_1_1_0_0_0 - 0.425396825396829*G0_1_1_5_1_1_0_0_1 + 0.425396825396829*G0_1_1_5_1_1_1_0_0 + 0.425396825396829*G0_1_1_5_1_1_2_0_1 - 0.425396825396829*G0_1_1_5_1_1_3_1_0 - 0.425396825396829*G0_1_1_5_1_1_3_1_1 + 0.425396825396829*G0_1_1_5_1_1_4_1_0 + 0.425396825396829*G0_1_1_5_1_1_5_1_1; + A[166] = 0.0; + A[624] = -A[716] - 0.203174603174612*G0_1_1_0_0_0_0_0_0 - 0.203174603174612*G0_1_1_0_0_0_0_0_1 + 0.203174603174612*G0_1_1_0_0_0_1_0_0 + 0.203174603174612*G0_1_1_0_0_0_2_0_1 - 0.203174603174612*G0_1_1_0_0_0_3_1_0 - 0.203174603174612*G0_1_1_0_0_0_3_1_1 + 0.203174603174612*G0_1_1_0_0_0_4_1_0 + 0.203174603174612*G0_1_1_0_0_0_5_1_1 - 0.203174603174612*G0_1_1_0_0_1_0_0_0 - 0.203174603174612*G0_1_1_0_0_1_0_0_1 + 0.203174603174612*G0_1_1_0_0_1_1_0_0 + 0.203174603174612*G0_1_1_0_0_1_2_0_1 - 0.203174603174612*G0_1_1_0_0_1_3_1_0 - 0.203174603174612*G0_1_1_0_0_1_3_1_1 + 0.203174603174612*G0_1_1_0_0_1_4_1_0 + 0.203174603174612*G0_1_1_0_0_1_5_1_1 + 0.203174603174612*G0_1_1_1_0_0_0_0_0 + 0.203174603174612*G0_1_1_1_0_0_0_0_1 - 0.203174603174612*G0_1_1_1_0_0_1_0_0 - 0.203174603174612*G0_1_1_1_0_0_2_0_1 + 0.203174603174612*G0_1_1_1_0_0_3_1_0 + 0.203174603174612*G0_1_1_1_0_0_3_1_1 - 0.203174603174612*G0_1_1_1_0_0_4_1_0 - 0.203174603174612*G0_1_1_1_0_0_5_1_1 + 0.203174603174612*G0_1_1_2_0_1_0_0_0 + 0.203174603174612*G0_1_1_2_0_1_0_0_1 - 0.203174603174612*G0_1_1_2_0_1_1_0_0 - 0.203174603174612*G0_1_1_2_0_1_2_0_1 + 0.203174603174612*G0_1_1_2_0_1_3_1_0 + 0.203174603174612*G0_1_1_2_0_1_3_1_1 - 0.203174603174612*G0_1_1_2_0_1_4_1_0 - 0.203174603174612*G0_1_1_2_0_1_5_1_1 - 0.203174603174612*G0_1_1_3_1_0_0_0_0 - 0.203174603174612*G0_1_1_3_1_0_0_0_1 + 0.203174603174612*G0_1_1_3_1_0_1_0_0 + 0.203174603174612*G0_1_1_3_1_0_2_0_1 - 0.203174603174612*G0_1_1_3_1_0_3_1_0 - 0.203174603174612*G0_1_1_3_1_0_3_1_1 + 0.203174603174612*G0_1_1_3_1_0_4_1_0 + 0.203174603174612*G0_1_1_3_1_0_5_1_1 - 0.203174603174612*G0_1_1_3_1_1_0_0_0 - 0.203174603174612*G0_1_1_3_1_1_0_0_1 + 0.203174603174612*G0_1_1_3_1_1_1_0_0 + 0.203174603174612*G0_1_1_3_1_1_2_0_1 - 0.203174603174612*G0_1_1_3_1_1_3_1_0 - 0.203174603174612*G0_1_1_3_1_1_3_1_1 + 0.203174603174612*G0_1_1_3_1_1_4_1_0 + 0.203174603174612*G0_1_1_3_1_1_5_1_1 + 0.203174603174612*G0_1_1_4_1_0_0_0_0 + 0.203174603174612*G0_1_1_4_1_0_0_0_1 - 0.203174603174612*G0_1_1_4_1_0_1_0_0 - 0.203174603174612*G0_1_1_4_1_0_2_0_1 + 0.203174603174612*G0_1_1_4_1_0_3_1_0 + 0.203174603174612*G0_1_1_4_1_0_3_1_1 - 0.203174603174612*G0_1_1_4_1_0_4_1_0 - 0.203174603174612*G0_1_1_4_1_0_5_1_1 + 0.203174603174612*G0_1_1_5_1_1_0_0_0 + 0.203174603174612*G0_1_1_5_1_1_0_0_1 - 0.203174603174612*G0_1_1_5_1_1_1_0_0 - 0.203174603174612*G0_1_1_5_1_1_2_0_1 + 0.203174603174612*G0_1_1_5_1_1_3_1_0 + 0.203174603174612*G0_1_1_5_1_1_3_1_1 - 0.203174603174612*G0_1_1_5_1_1_4_1_0 - 0.203174603174612*G0_1_1_5_1_1_5_1_1; + A[488] = 0.0; + A[659] = A[658]; + A[575] = 0.0; + A[531] = -A[63] - 0.287830687830693*G0_1_1_0_0_0_0_0_0 - 0.287830687830693*G0_1_1_0_0_0_0_0_1 + 0.287830687830693*G0_1_1_0_0_0_1_0_0 + 0.287830687830693*G0_1_1_0_0_0_2_0_1 - 0.287830687830693*G0_1_1_0_0_0_3_1_0 - 0.287830687830693*G0_1_1_0_0_0_3_1_1 + 0.287830687830693*G0_1_1_0_0_0_4_1_0 + 0.287830687830693*G0_1_1_0_0_0_5_1_1 - 0.287830687830693*G0_1_1_0_0_1_0_0_0 - 0.287830687830693*G0_1_1_0_0_1_0_0_1 + 0.287830687830693*G0_1_1_0_0_1_1_0_0 + 0.287830687830693*G0_1_1_0_0_1_2_0_1 - 0.287830687830693*G0_1_1_0_0_1_3_1_0 - 0.287830687830693*G0_1_1_0_0_1_3_1_1 + 0.287830687830693*G0_1_1_0_0_1_4_1_0 + 0.287830687830693*G0_1_1_0_0_1_5_1_1 + 0.287830687830693*G0_1_1_1_0_0_0_0_0 + 0.287830687830693*G0_1_1_1_0_0_0_0_1 - 0.287830687830693*G0_1_1_1_0_0_1_0_0 - 0.287830687830693*G0_1_1_1_0_0_2_0_1 + 0.287830687830693*G0_1_1_1_0_0_3_1_0 + 0.287830687830693*G0_1_1_1_0_0_3_1_1 - 0.287830687830693*G0_1_1_1_0_0_4_1_0 - 0.287830687830693*G0_1_1_1_0_0_5_1_1 + 0.287830687830693*G0_1_1_2_0_1_0_0_0 + 0.287830687830693*G0_1_1_2_0_1_0_0_1 - 0.287830687830693*G0_1_1_2_0_1_1_0_0 - 0.287830687830693*G0_1_1_2_0_1_2_0_1 + 0.287830687830693*G0_1_1_2_0_1_3_1_0 + 0.287830687830693*G0_1_1_2_0_1_3_1_1 - 0.287830687830693*G0_1_1_2_0_1_4_1_0 - 0.287830687830693*G0_1_1_2_0_1_5_1_1 - 0.287830687830693*G0_1_1_3_1_0_0_0_0 - 0.287830687830693*G0_1_1_3_1_0_0_0_1 + 0.287830687830693*G0_1_1_3_1_0_1_0_0 + 0.287830687830693*G0_1_1_3_1_0_2_0_1 - 0.287830687830693*G0_1_1_3_1_0_3_1_0 - 0.287830687830693*G0_1_1_3_1_0_3_1_1 + 0.287830687830693*G0_1_1_3_1_0_4_1_0 + 0.287830687830693*G0_1_1_3_1_0_5_1_1 - 0.287830687830693*G0_1_1_3_1_1_0_0_0 - 0.287830687830693*G0_1_1_3_1_1_0_0_1 + 0.287830687830693*G0_1_1_3_1_1_1_0_0 + 0.287830687830693*G0_1_1_3_1_1_2_0_1 - 0.287830687830693*G0_1_1_3_1_1_3_1_0 - 0.287830687830693*G0_1_1_3_1_1_3_1_1 + 0.287830687830693*G0_1_1_3_1_1_4_1_0 + 0.287830687830693*G0_1_1_3_1_1_5_1_1 + 0.287830687830693*G0_1_1_4_1_0_0_0_0 + 0.287830687830693*G0_1_1_4_1_0_0_0_1 - 0.287830687830693*G0_1_1_4_1_0_1_0_0 - 0.287830687830693*G0_1_1_4_1_0_2_0_1 + 0.287830687830693*G0_1_1_4_1_0_3_1_0 + 0.287830687830693*G0_1_1_4_1_0_3_1_1 - 0.287830687830693*G0_1_1_4_1_0_4_1_0 - 0.287830687830693*G0_1_1_4_1_0_5_1_1 + 0.287830687830693*G0_1_1_5_1_1_0_0_0 + 0.287830687830693*G0_1_1_5_1_1_0_0_1 - 0.287830687830693*G0_1_1_5_1_1_1_0_0 - 0.287830687830693*G0_1_1_5_1_1_2_0_1 + 0.287830687830693*G0_1_1_5_1_1_3_1_0 + 0.287830687830693*G0_1_1_5_1_1_3_1_1 - 0.287830687830693*G0_1_1_5_1_1_4_1_0 - 0.287830687830693*G0_1_1_5_1_1_5_1_1; + A[678] = A[213]; + A[606] = 0.0; + A[558] = A[806]; + A[717] = A[252]; + A[637] = 0.0; + A[244] = A[709]; + A[271] = A[736]; + A[306] = A[219] + 0.169312169312181*G0_0_0_0_0_0_0_0_0 + 0.169312169312181*G0_0_0_0_0_0_0_0_1 - 0.169312169312181*G0_0_0_0_0_0_1_0_0 - 0.169312169312181*G0_0_0_0_0_0_2_0_1 + 0.169312169312181*G0_0_0_0_0_0_3_1_0 + 0.169312169312181*G0_0_0_0_0_0_3_1_1 - 0.169312169312181*G0_0_0_0_0_0_4_1_0 - 0.169312169312181*G0_0_0_0_0_0_5_1_1 + 0.169312169312181*G0_0_0_0_0_1_0_0_0 + 0.169312169312181*G0_0_0_0_0_1_0_0_1 - 0.169312169312181*G0_0_0_0_0_1_1_0_0 - 0.169312169312181*G0_0_0_0_0_1_2_0_1 + 0.169312169312181*G0_0_0_0_0_1_3_1_0 + 0.169312169312181*G0_0_0_0_0_1_3_1_1 - 0.169312169312181*G0_0_0_0_0_1_4_1_0 - 0.169312169312181*G0_0_0_0_0_1_5_1_1 - 0.169312169312181*G0_0_0_1_0_0_0_0_0 - 0.169312169312181*G0_0_0_1_0_0_0_0_1 + 0.169312169312181*G0_0_0_1_0_0_1_0_0 + 0.169312169312181*G0_0_0_1_0_0_2_0_1 - 0.169312169312181*G0_0_0_1_0_0_3_1_0 - 0.169312169312181*G0_0_0_1_0_0_3_1_1 + 0.169312169312181*G0_0_0_1_0_0_4_1_0 + 0.169312169312181*G0_0_0_1_0_0_5_1_1 - 0.169312169312181*G0_0_0_2_0_1_0_0_0 - 0.169312169312181*G0_0_0_2_0_1_0_0_1 + 0.169312169312181*G0_0_0_2_0_1_1_0_0 + 0.169312169312181*G0_0_0_2_0_1_2_0_1 - 0.169312169312181*G0_0_0_2_0_1_3_1_0 - 0.169312169312181*G0_0_0_2_0_1_3_1_1 + 0.169312169312181*G0_0_0_2_0_1_4_1_0 + 0.169312169312181*G0_0_0_2_0_1_5_1_1 + 0.169312169312181*G0_0_0_3_1_0_0_0_0 + 0.169312169312181*G0_0_0_3_1_0_0_0_1 - 0.169312169312181*G0_0_0_3_1_0_1_0_0 - 0.169312169312181*G0_0_0_3_1_0_2_0_1 + 0.169312169312181*G0_0_0_3_1_0_3_1_0 + 0.169312169312181*G0_0_0_3_1_0_3_1_1 - 0.169312169312181*G0_0_0_3_1_0_4_1_0 - 0.169312169312181*G0_0_0_3_1_0_5_1_1 + 0.169312169312181*G0_0_0_3_1_1_0_0_0 + 0.169312169312181*G0_0_0_3_1_1_0_0_1 - 0.169312169312181*G0_0_0_3_1_1_1_0_0 - 0.169312169312181*G0_0_0_3_1_1_2_0_1 + 0.169312169312181*G0_0_0_3_1_1_3_1_0 + 0.169312169312181*G0_0_0_3_1_1_3_1_1 - 0.169312169312181*G0_0_0_3_1_1_4_1_0 - 0.169312169312181*G0_0_0_3_1_1_5_1_1 - 0.169312169312181*G0_0_0_4_1_0_0_0_0 - 0.169312169312181*G0_0_0_4_1_0_0_0_1 + 0.169312169312181*G0_0_0_4_1_0_1_0_0 + 0.169312169312181*G0_0_0_4_1_0_2_0_1 - 0.169312169312181*G0_0_0_4_1_0_3_1_0 - 0.169312169312181*G0_0_0_4_1_0_3_1_1 + 0.169312169312181*G0_0_0_4_1_0_4_1_0 + 0.169312169312181*G0_0_0_4_1_0_5_1_1 - 0.169312169312181*G0_0_0_5_1_1_0_0_0 - 0.169312169312181*G0_0_0_5_1_1_0_0_1 + 0.169312169312181*G0_0_0_5_1_1_1_0_0 + 0.169312169312181*G0_0_0_5_1_1_2_0_1 - 0.169312169312181*G0_0_0_5_1_1_3_1_0 - 0.169312169312181*G0_0_0_5_1_1_3_1_1 + 0.169312169312181*G0_0_0_5_1_1_4_1_0 + 0.169312169312181*G0_0_0_5_1_1_5_1_1 - 0.169312169312183*G0_1_1_0_0_0_0_0_0 - 0.169312169312183*G0_1_1_0_0_0_0_0_1 + 0.169312169312183*G0_1_1_0_0_0_1_0_0 + 0.169312169312183*G0_1_1_0_0_0_2_0_1 - 0.169312169312183*G0_1_1_0_0_0_3_1_0 - 0.169312169312183*G0_1_1_0_0_0_3_1_1 + 0.169312169312183*G0_1_1_0_0_0_4_1_0 + 0.169312169312183*G0_1_1_0_0_0_5_1_1 - 0.169312169312183*G0_1_1_0_0_1_0_0_0 - 0.169312169312183*G0_1_1_0_0_1_0_0_1 + 0.169312169312183*G0_1_1_0_0_1_1_0_0 + 0.169312169312183*G0_1_1_0_0_1_2_0_1 - 0.169312169312183*G0_1_1_0_0_1_3_1_0 - 0.169312169312183*G0_1_1_0_0_1_3_1_1 + 0.169312169312183*G0_1_1_0_0_1_4_1_0 + 0.169312169312183*G0_1_1_0_0_1_5_1_1 + 0.169312169312183*G0_1_1_1_0_0_0_0_0 + 0.169312169312183*G0_1_1_1_0_0_0_0_1 - 0.169312169312183*G0_1_1_1_0_0_1_0_0 - 0.169312169312183*G0_1_1_1_0_0_2_0_1 + 0.169312169312183*G0_1_1_1_0_0_3_1_0 + 0.169312169312183*G0_1_1_1_0_0_3_1_1 - 0.169312169312183*G0_1_1_1_0_0_4_1_0 - 0.169312169312183*G0_1_1_1_0_0_5_1_1 + 0.169312169312183*G0_1_1_2_0_1_0_0_0 + 0.169312169312183*G0_1_1_2_0_1_0_0_1 - 0.169312169312183*G0_1_1_2_0_1_1_0_0 - 0.169312169312183*G0_1_1_2_0_1_2_0_1 + 0.169312169312183*G0_1_1_2_0_1_3_1_0 + 0.169312169312183*G0_1_1_2_0_1_3_1_1 - 0.169312169312183*G0_1_1_2_0_1_4_1_0 - 0.169312169312183*G0_1_1_2_0_1_5_1_1 - 0.169312169312183*G0_1_1_3_1_0_0_0_0 - 0.169312169312183*G0_1_1_3_1_0_0_0_1 + 0.169312169312183*G0_1_1_3_1_0_1_0_0 + 0.169312169312183*G0_1_1_3_1_0_2_0_1 - 0.169312169312183*G0_1_1_3_1_0_3_1_0 - 0.169312169312183*G0_1_1_3_1_0_3_1_1 + 0.169312169312183*G0_1_1_3_1_0_4_1_0 + 0.169312169312183*G0_1_1_3_1_0_5_1_1 - 0.169312169312183*G0_1_1_3_1_1_0_0_0 - 0.169312169312183*G0_1_1_3_1_1_0_0_1 + 0.169312169312183*G0_1_1_3_1_1_1_0_0 + 0.169312169312183*G0_1_1_3_1_1_2_0_1 - 0.169312169312183*G0_1_1_3_1_1_3_1_0 - 0.169312169312183*G0_1_1_3_1_1_3_1_1 + 0.169312169312183*G0_1_1_3_1_1_4_1_0 + 0.169312169312183*G0_1_1_3_1_1_5_1_1 + 0.169312169312183*G0_1_1_4_1_0_0_0_0 + 0.169312169312183*G0_1_1_4_1_0_0_0_1 - 0.169312169312183*G0_1_1_4_1_0_1_0_0 - 0.169312169312183*G0_1_1_4_1_0_2_0_1 + 0.169312169312183*G0_1_1_4_1_0_3_1_0 + 0.169312169312183*G0_1_1_4_1_0_3_1_1 - 0.169312169312183*G0_1_1_4_1_0_4_1_0 - 0.169312169312183*G0_1_1_4_1_0_5_1_1 + 0.169312169312183*G0_1_1_5_1_1_0_0_0 + 0.169312169312183*G0_1_1_5_1_1_0_0_1 - 0.169312169312183*G0_1_1_5_1_1_1_0_0 - 0.169312169312183*G0_1_1_5_1_1_2_0_1 + 0.169312169312183*G0_1_1_5_1_1_3_1_0 + 0.169312169312183*G0_1_1_5_1_1_3_1_1 - 0.169312169312183*G0_1_1_5_1_1_4_1_0 - 0.169312169312183*G0_1_1_5_1_1_5_1_1; + A[353] = 0.0; + A[16] = 0.0; + A[733] = 0.0; + A[420] = A[14]; + A[376] = 0.0; + A[59] = 0.0; + A[758] = 0.0; + A[455] = 0.0; + A[411] = 0.0; + A[859] = A[394]; + A[86] = 0.0; + A[795] = -A[5] - 0.203174603174605*G0_0_0_0_0_0_0_0_0 - 0.203174603174605*G0_0_0_0_0_0_0_0_1 + 0.203174603174605*G0_0_0_0_0_0_1_0_0 + 0.203174603174605*G0_0_0_0_0_0_2_0_1 - 0.203174603174605*G0_0_0_0_0_0_3_1_0 - 0.203174603174605*G0_0_0_0_0_0_3_1_1 + 0.203174603174605*G0_0_0_0_0_0_4_1_0 + 0.203174603174605*G0_0_0_0_0_0_5_1_1 - 0.203174603174605*G0_0_0_0_0_1_0_0_0 - 0.203174603174605*G0_0_0_0_0_1_0_0_1 + 0.203174603174605*G0_0_0_0_0_1_1_0_0 + 0.203174603174605*G0_0_0_0_0_1_2_0_1 - 0.203174603174605*G0_0_0_0_0_1_3_1_0 - 0.203174603174605*G0_0_0_0_0_1_3_1_1 + 0.203174603174605*G0_0_0_0_0_1_4_1_0 + 0.203174603174605*G0_0_0_0_0_1_5_1_1 + 0.203174603174605*G0_0_0_1_0_0_0_0_0 + 0.203174603174605*G0_0_0_1_0_0_0_0_1 - 0.203174603174605*G0_0_0_1_0_0_1_0_0 - 0.203174603174605*G0_0_0_1_0_0_2_0_1 + 0.203174603174605*G0_0_0_1_0_0_3_1_0 + 0.203174603174605*G0_0_0_1_0_0_3_1_1 - 0.203174603174605*G0_0_0_1_0_0_4_1_0 - 0.203174603174605*G0_0_0_1_0_0_5_1_1 + 0.203174603174605*G0_0_0_2_0_1_0_0_0 + 0.203174603174605*G0_0_0_2_0_1_0_0_1 - 0.203174603174605*G0_0_0_2_0_1_1_0_0 - 0.203174603174605*G0_0_0_2_0_1_2_0_1 + 0.203174603174605*G0_0_0_2_0_1_3_1_0 + 0.203174603174605*G0_0_0_2_0_1_3_1_1 - 0.203174603174605*G0_0_0_2_0_1_4_1_0 - 0.203174603174605*G0_0_0_2_0_1_5_1_1 - 0.203174603174605*G0_0_0_3_1_0_0_0_0 - 0.203174603174605*G0_0_0_3_1_0_0_0_1 + 0.203174603174605*G0_0_0_3_1_0_1_0_0 + 0.203174603174605*G0_0_0_3_1_0_2_0_1 - 0.203174603174605*G0_0_0_3_1_0_3_1_0 - 0.203174603174605*G0_0_0_3_1_0_3_1_1 + 0.203174603174605*G0_0_0_3_1_0_4_1_0 + 0.203174603174605*G0_0_0_3_1_0_5_1_1 - 0.203174603174605*G0_0_0_3_1_1_0_0_0 - 0.203174603174605*G0_0_0_3_1_1_0_0_1 + 0.203174603174605*G0_0_0_3_1_1_1_0_0 + 0.203174603174605*G0_0_0_3_1_1_2_0_1 - 0.203174603174605*G0_0_0_3_1_1_3_1_0 - 0.203174603174605*G0_0_0_3_1_1_3_1_1 + 0.203174603174605*G0_0_0_3_1_1_4_1_0 + 0.203174603174605*G0_0_0_3_1_1_5_1_1 + 0.203174603174605*G0_0_0_4_1_0_0_0_0 + 0.203174603174605*G0_0_0_4_1_0_0_0_1 - 0.203174603174605*G0_0_0_4_1_0_1_0_0 - 0.203174603174605*G0_0_0_4_1_0_2_0_1 + 0.203174603174605*G0_0_0_4_1_0_3_1_0 + 0.203174603174605*G0_0_0_4_1_0_3_1_1 - 0.203174603174605*G0_0_0_4_1_0_4_1_0 - 0.203174603174605*G0_0_0_4_1_0_5_1_1 + 0.203174603174605*G0_0_0_5_1_1_0_0_0 + 0.203174603174605*G0_0_0_5_1_1_0_0_1 - 0.203174603174605*G0_0_0_5_1_1_1_0_0 - 0.203174603174605*G0_0_0_5_1_1_2_0_1 + 0.203174603174605*G0_0_0_5_1_1_3_1_0 + 0.203174603174605*G0_0_0_5_1_1_3_1_1 - 0.203174603174605*G0_0_0_5_1_1_4_1_0 - 0.203174603174605*G0_0_0_5_1_1_5_1_1 - 0.203174603174603*G0_0_1_0_0_0_0_0_0 - 0.203174603174603*G0_0_1_0_0_0_0_0_1 + 0.203174603174603*G0_0_1_0_0_0_1_0_0 + 0.203174603174603*G0_0_1_0_0_0_2_0_1 - 0.203174603174603*G0_0_1_0_0_0_3_1_0 - 0.203174603174603*G0_0_1_0_0_0_3_1_1 + 0.203174603174603*G0_0_1_0_0_0_4_1_0 + 0.203174603174603*G0_0_1_0_0_0_5_1_1 - 0.203174603174603*G0_0_1_0_0_1_0_0_0 - 0.203174603174603*G0_0_1_0_0_1_0_0_1 + 0.203174603174603*G0_0_1_0_0_1_1_0_0 + 0.203174603174603*G0_0_1_0_0_1_2_0_1 - 0.203174603174603*G0_0_1_0_0_1_3_1_0 - 0.203174603174603*G0_0_1_0_0_1_3_1_1 + 0.203174603174603*G0_0_1_0_0_1_4_1_0 + 0.203174603174603*G0_0_1_0_0_1_5_1_1 + 0.203174603174603*G0_0_1_1_0_0_0_0_0 + 0.203174603174603*G0_0_1_1_0_0_0_0_1 - 0.203174603174603*G0_0_1_1_0_0_1_0_0 - 0.203174603174603*G0_0_1_1_0_0_2_0_1 + 0.203174603174603*G0_0_1_1_0_0_3_1_0 + 0.203174603174603*G0_0_1_1_0_0_3_1_1 - 0.203174603174603*G0_0_1_1_0_0_4_1_0 - 0.203174603174603*G0_0_1_1_0_0_5_1_1 + 0.203174603174603*G0_0_1_2_0_1_0_0_0 + 0.203174603174603*G0_0_1_2_0_1_0_0_1 - 0.203174603174603*G0_0_1_2_0_1_1_0_0 - 0.203174603174603*G0_0_1_2_0_1_2_0_1 + 0.203174603174603*G0_0_1_2_0_1_3_1_0 + 0.203174603174603*G0_0_1_2_0_1_3_1_1 - 0.203174603174603*G0_0_1_2_0_1_4_1_0 - 0.203174603174603*G0_0_1_2_0_1_5_1_1 - 0.203174603174603*G0_0_1_3_1_0_0_0_0 - 0.203174603174603*G0_0_1_3_1_0_0_0_1 + 0.203174603174603*G0_0_1_3_1_0_1_0_0 + 0.203174603174603*G0_0_1_3_1_0_2_0_1 - 0.203174603174603*G0_0_1_3_1_0_3_1_0 - 0.203174603174603*G0_0_1_3_1_0_3_1_1 + 0.203174603174603*G0_0_1_3_1_0_4_1_0 + 0.203174603174603*G0_0_1_3_1_0_5_1_1 - 0.203174603174603*G0_0_1_3_1_1_0_0_0 - 0.203174603174603*G0_0_1_3_1_1_0_0_1 + 0.203174603174603*G0_0_1_3_1_1_1_0_0 + 0.203174603174603*G0_0_1_3_1_1_2_0_1 - 0.203174603174603*G0_0_1_3_1_1_3_1_0 - 0.203174603174603*G0_0_1_3_1_1_3_1_1 + 0.203174603174603*G0_0_1_3_1_1_4_1_0 + 0.203174603174603*G0_0_1_3_1_1_5_1_1 + 0.203174603174603*G0_0_1_4_1_0_0_0_0 + 0.203174603174603*G0_0_1_4_1_0_0_0_1 - 0.203174603174603*G0_0_1_4_1_0_1_0_0 - 0.203174603174603*G0_0_1_4_1_0_2_0_1 + 0.203174603174603*G0_0_1_4_1_0_3_1_0 + 0.203174603174603*G0_0_1_4_1_0_3_1_1 - 0.203174603174603*G0_0_1_4_1_0_4_1_0 - 0.203174603174603*G0_0_1_4_1_0_5_1_1 + 0.203174603174603*G0_0_1_5_1_1_0_0_0 + 0.203174603174603*G0_0_1_5_1_1_0_0_1 - 0.203174603174603*G0_0_1_5_1_1_1_0_0 - 0.203174603174603*G0_0_1_5_1_1_2_0_1 + 0.203174603174603*G0_0_1_5_1_1_3_1_0 + 0.203174603174603*G0_0_1_5_1_1_3_1_1 - 0.203174603174603*G0_0_1_5_1_1_4_1_0 - 0.203174603174603*G0_0_1_5_1_1_5_1_1; + A[888] = A[569]; + A[93] = A[806]; + A[824] = 0.0; + A[124] = A[775] - 0.507936507936516*G0_0_0_0_0_0_0_0_0 - 0.507936507936516*G0_0_0_0_0_0_0_0_1 + 0.507936507936516*G0_0_0_0_0_0_1_0_0 + 0.507936507936516*G0_0_0_0_0_0_2_0_1 - 0.507936507936516*G0_0_0_0_0_0_3_1_0 - 0.507936507936516*G0_0_0_0_0_0_3_1_1 + 0.507936507936516*G0_0_0_0_0_0_4_1_0 + 0.507936507936516*G0_0_0_0_0_0_5_1_1 - 0.507936507936516*G0_0_0_0_0_1_0_0_0 - 0.507936507936516*G0_0_0_0_0_1_0_0_1 + 0.507936507936516*G0_0_0_0_0_1_1_0_0 + 0.507936507936516*G0_0_0_0_0_1_2_0_1 - 0.507936507936516*G0_0_0_0_0_1_3_1_0 - 0.507936507936516*G0_0_0_0_0_1_3_1_1 + 0.507936507936516*G0_0_0_0_0_1_4_1_0 + 0.507936507936516*G0_0_0_0_0_1_5_1_1 + 0.507936507936516*G0_0_0_1_0_0_0_0_0 + 0.507936507936516*G0_0_0_1_0_0_0_0_1 - 0.507936507936516*G0_0_0_1_0_0_1_0_0 - 0.507936507936516*G0_0_0_1_0_0_2_0_1 + 0.507936507936516*G0_0_0_1_0_0_3_1_0 + 0.507936507936516*G0_0_0_1_0_0_3_1_1 - 0.507936507936516*G0_0_0_1_0_0_4_1_0 - 0.507936507936516*G0_0_0_1_0_0_5_1_1 + 0.507936507936516*G0_0_0_2_0_1_0_0_0 + 0.507936507936516*G0_0_0_2_0_1_0_0_1 - 0.507936507936516*G0_0_0_2_0_1_1_0_0 - 0.507936507936516*G0_0_0_2_0_1_2_0_1 + 0.507936507936516*G0_0_0_2_0_1_3_1_0 + 0.507936507936516*G0_0_0_2_0_1_3_1_1 - 0.507936507936516*G0_0_0_2_0_1_4_1_0 - 0.507936507936516*G0_0_0_2_0_1_5_1_1 - 0.507936507936516*G0_0_0_3_1_0_0_0_0 - 0.507936507936516*G0_0_0_3_1_0_0_0_1 + 0.507936507936516*G0_0_0_3_1_0_1_0_0 + 0.507936507936516*G0_0_0_3_1_0_2_0_1 - 0.507936507936516*G0_0_0_3_1_0_3_1_0 - 0.507936507936516*G0_0_0_3_1_0_3_1_1 + 0.507936507936516*G0_0_0_3_1_0_4_1_0 + 0.507936507936516*G0_0_0_3_1_0_5_1_1 - 0.507936507936516*G0_0_0_3_1_1_0_0_0 - 0.507936507936516*G0_0_0_3_1_1_0_0_1 + 0.507936507936516*G0_0_0_3_1_1_1_0_0 + 0.507936507936516*G0_0_0_3_1_1_2_0_1 - 0.507936507936516*G0_0_0_3_1_1_3_1_0 - 0.507936507936516*G0_0_0_3_1_1_3_1_1 + 0.507936507936516*G0_0_0_3_1_1_4_1_0 + 0.507936507936516*G0_0_0_3_1_1_5_1_1 + 0.507936507936516*G0_0_0_4_1_0_0_0_0 + 0.507936507936516*G0_0_0_4_1_0_0_0_1 - 0.507936507936516*G0_0_0_4_1_0_1_0_0 - 0.507936507936516*G0_0_0_4_1_0_2_0_1 + 0.507936507936516*G0_0_0_4_1_0_3_1_0 + 0.507936507936516*G0_0_0_4_1_0_3_1_1 - 0.507936507936516*G0_0_0_4_1_0_4_1_0 - 0.507936507936516*G0_0_0_4_1_0_5_1_1 + 0.507936507936516*G0_0_0_5_1_1_0_0_0 + 0.507936507936516*G0_0_0_5_1_1_0_0_1 - 0.507936507936516*G0_0_0_5_1_1_1_0_0 - 0.507936507936516*G0_0_0_5_1_1_2_0_1 + 0.507936507936516*G0_0_0_5_1_1_3_1_0 + 0.507936507936516*G0_0_0_5_1_1_3_1_1 - 0.507936507936516*G0_0_0_5_1_1_4_1_0 - 0.507936507936516*G0_0_0_5_1_1_5_1_1 - 0.507936507936515*G0_0_1_0_0_0_0_0_0 - 0.507936507936515*G0_0_1_0_0_0_0_0_1 + 0.507936507936515*G0_0_1_0_0_0_1_0_0 + 0.507936507936515*G0_0_1_0_0_0_2_0_1 - 0.507936507936515*G0_0_1_0_0_0_3_1_0 - 0.507936507936515*G0_0_1_0_0_0_3_1_1 + 0.507936507936515*G0_0_1_0_0_0_4_1_0 + 0.507936507936515*G0_0_1_0_0_0_5_1_1 - 0.507936507936515*G0_0_1_0_0_1_0_0_0 - 0.507936507936515*G0_0_1_0_0_1_0_0_1 + 0.507936507936515*G0_0_1_0_0_1_1_0_0 + 0.507936507936515*G0_0_1_0_0_1_2_0_1 - 0.507936507936515*G0_0_1_0_0_1_3_1_0 - 0.507936507936515*G0_0_1_0_0_1_3_1_1 + 0.507936507936515*G0_0_1_0_0_1_4_1_0 + 0.507936507936515*G0_0_1_0_0_1_5_1_1 + 0.507936507936515*G0_0_1_1_0_0_0_0_0 + 0.507936507936515*G0_0_1_1_0_0_0_0_1 - 0.507936507936515*G0_0_1_1_0_0_1_0_0 - 0.507936507936515*G0_0_1_1_0_0_2_0_1 + 0.507936507936515*G0_0_1_1_0_0_3_1_0 + 0.507936507936515*G0_0_1_1_0_0_3_1_1 - 0.507936507936515*G0_0_1_1_0_0_4_1_0 - 0.507936507936515*G0_0_1_1_0_0_5_1_1 + 0.507936507936515*G0_0_1_2_0_1_0_0_0 + 0.507936507936515*G0_0_1_2_0_1_0_0_1 - 0.507936507936515*G0_0_1_2_0_1_1_0_0 - 0.507936507936515*G0_0_1_2_0_1_2_0_1 + 0.507936507936515*G0_0_1_2_0_1_3_1_0 + 0.507936507936515*G0_0_1_2_0_1_3_1_1 - 0.507936507936515*G0_0_1_2_0_1_4_1_0 - 0.507936507936515*G0_0_1_2_0_1_5_1_1 - 0.507936507936515*G0_0_1_3_1_0_0_0_0 - 0.507936507936515*G0_0_1_3_1_0_0_0_1 + 0.507936507936515*G0_0_1_3_1_0_1_0_0 + 0.507936507936515*G0_0_1_3_1_0_2_0_1 - 0.507936507936515*G0_0_1_3_1_0_3_1_0 - 0.507936507936515*G0_0_1_3_1_0_3_1_1 + 0.507936507936515*G0_0_1_3_1_0_4_1_0 + 0.507936507936515*G0_0_1_3_1_0_5_1_1 - 0.507936507936515*G0_0_1_3_1_1_0_0_0 - 0.507936507936515*G0_0_1_3_1_1_0_0_1 + 0.507936507936515*G0_0_1_3_1_1_1_0_0 + 0.507936507936515*G0_0_1_3_1_1_2_0_1 - 0.507936507936515*G0_0_1_3_1_1_3_1_0 - 0.507936507936515*G0_0_1_3_1_1_3_1_1 + 0.507936507936515*G0_0_1_3_1_1_4_1_0 + 0.507936507936515*G0_0_1_3_1_1_5_1_1 + 0.507936507936515*G0_0_1_4_1_0_0_0_0 + 0.507936507936515*G0_0_1_4_1_0_0_0_1 - 0.507936507936515*G0_0_1_4_1_0_1_0_0 - 0.507936507936515*G0_0_1_4_1_0_2_0_1 + 0.507936507936515*G0_0_1_4_1_0_3_1_0 + 0.507936507936515*G0_0_1_4_1_0_3_1_1 - 0.507936507936515*G0_0_1_4_1_0_4_1_0 - 0.507936507936515*G0_0_1_4_1_0_5_1_1 + 0.507936507936515*G0_0_1_5_1_1_0_0_0 + 0.507936507936515*G0_0_1_5_1_1_0_0_1 - 0.507936507936515*G0_0_1_5_1_1_1_0_0 - 0.507936507936515*G0_0_1_5_1_1_2_0_1 + 0.507936507936515*G0_0_1_5_1_1_3_1_0 + 0.507936507936515*G0_0_1_5_1_1_3_1_1 - 0.507936507936515*G0_0_1_5_1_1_4_1_0 - 0.507936507936515*G0_0_1_5_1_1_5_1_1 - 0.507936507936515*G0_1_0_0_0_0_0_0_0 - 0.507936507936515*G0_1_0_0_0_0_0_0_1 + 0.507936507936515*G0_1_0_0_0_0_1_0_0 + 0.507936507936515*G0_1_0_0_0_0_2_0_1 - 0.507936507936515*G0_1_0_0_0_0_3_1_0 - 0.507936507936515*G0_1_0_0_0_0_3_1_1 + 0.507936507936515*G0_1_0_0_0_0_4_1_0 + 0.507936507936515*G0_1_0_0_0_0_5_1_1 - 0.507936507936515*G0_1_0_0_0_1_0_0_0 - 0.507936507936515*G0_1_0_0_0_1_0_0_1 + 0.507936507936515*G0_1_0_0_0_1_1_0_0 + 0.507936507936515*G0_1_0_0_0_1_2_0_1 - 0.507936507936515*G0_1_0_0_0_1_3_1_0 - 0.507936507936515*G0_1_0_0_0_1_3_1_1 + 0.507936507936515*G0_1_0_0_0_1_4_1_0 + 0.507936507936515*G0_1_0_0_0_1_5_1_1 + 0.507936507936515*G0_1_0_1_0_0_0_0_0 + 0.507936507936515*G0_1_0_1_0_0_0_0_1 - 0.507936507936515*G0_1_0_1_0_0_1_0_0 - 0.507936507936515*G0_1_0_1_0_0_2_0_1 + 0.507936507936515*G0_1_0_1_0_0_3_1_0 + 0.507936507936515*G0_1_0_1_0_0_3_1_1 - 0.507936507936515*G0_1_0_1_0_0_4_1_0 - 0.507936507936515*G0_1_0_1_0_0_5_1_1 + 0.507936507936515*G0_1_0_2_0_1_0_0_0 + 0.507936507936515*G0_1_0_2_0_1_0_0_1 - 0.507936507936515*G0_1_0_2_0_1_1_0_0 - 0.507936507936515*G0_1_0_2_0_1_2_0_1 + 0.507936507936515*G0_1_0_2_0_1_3_1_0 + 0.507936507936515*G0_1_0_2_0_1_3_1_1 - 0.507936507936515*G0_1_0_2_0_1_4_1_0 - 0.507936507936515*G0_1_0_2_0_1_5_1_1 - 0.507936507936515*G0_1_0_3_1_0_0_0_0 - 0.507936507936515*G0_1_0_3_1_0_0_0_1 + 0.507936507936515*G0_1_0_3_1_0_1_0_0 + 0.507936507936515*G0_1_0_3_1_0_2_0_1 - 0.507936507936515*G0_1_0_3_1_0_3_1_0 - 0.507936507936515*G0_1_0_3_1_0_3_1_1 + 0.507936507936515*G0_1_0_3_1_0_4_1_0 + 0.507936507936515*G0_1_0_3_1_0_5_1_1 - 0.507936507936515*G0_1_0_3_1_1_0_0_0 - 0.507936507936515*G0_1_0_3_1_1_0_0_1 + 0.507936507936515*G0_1_0_3_1_1_1_0_0 + 0.507936507936515*G0_1_0_3_1_1_2_0_1 - 0.507936507936515*G0_1_0_3_1_1_3_1_0 - 0.507936507936515*G0_1_0_3_1_1_3_1_1 + 0.507936507936515*G0_1_0_3_1_1_4_1_0 + 0.507936507936515*G0_1_0_3_1_1_5_1_1 + 0.507936507936515*G0_1_0_4_1_0_0_0_0 + 0.507936507936515*G0_1_0_4_1_0_0_0_1 - 0.507936507936515*G0_1_0_4_1_0_1_0_0 - 0.507936507936515*G0_1_0_4_1_0_2_0_1 + 0.507936507936515*G0_1_0_4_1_0_3_1_0 + 0.507936507936515*G0_1_0_4_1_0_3_1_1 - 0.507936507936515*G0_1_0_4_1_0_4_1_0 - 0.507936507936515*G0_1_0_4_1_0_5_1_1 + 0.507936507936515*G0_1_0_5_1_1_0_0_0 + 0.507936507936515*G0_1_0_5_1_1_0_0_1 - 0.507936507936515*G0_1_0_5_1_1_1_0_0 - 0.507936507936515*G0_1_0_5_1_1_2_0_1 + 0.507936507936515*G0_1_0_5_1_1_3_1_0 + 0.507936507936515*G0_1_0_5_1_1_3_1_1 - 0.507936507936515*G0_1_0_5_1_1_4_1_0 - 0.507936507936515*G0_1_0_5_1_1_5_1_1; + A[849] = 0.0; + A[175] = 0.0; + A[882] = 0.0; + A[495] = A[30]; + A[202] = 0.0; + A[580] = 0.0; + A[524] = 0.0; + A[233] = 0.0; + A[681] = A[216]; + A[613] = 0.0; + A[553] = 0.0; + A[706] = A[181]; + A[630] = 0.0; + A[251] = A[716]; + A[675] = A[210]; + A[280] = A[745]; + A[704] = 0.0; + A[301] = A[766]; + A[257] = 0.0; + A[342] = A[836]; + A[23] = 0.0; + A[740] = A[624]; + A[431] = A[836]; + A[375] = 0.0; + A[52] = 0.0; + A[767] = A[534]; + A[452] = 0.0; + A[404] = A[869]; + A[81] = 0.0; + A[802] = A[221]; + A[13] = A[14]; + A[98] = -A[716] - 0.338624338624345*G0_0_0_0_0_0_0_0_0 - 0.338624338624345*G0_0_0_0_0_0_0_0_1 + 0.338624338624345*G0_0_0_0_0_0_1_0_0 + 0.338624338624345*G0_0_0_0_0_0_2_0_1 - 0.338624338624345*G0_0_0_0_0_0_3_1_0 - 0.338624338624345*G0_0_0_0_0_0_3_1_1 + 0.338624338624345*G0_0_0_0_0_0_4_1_0 + 0.338624338624345*G0_0_0_0_0_0_5_1_1 - 0.338624338624345*G0_0_0_0_0_1_0_0_0 - 0.338624338624345*G0_0_0_0_0_1_0_0_1 + 0.338624338624345*G0_0_0_0_0_1_1_0_0 + 0.338624338624345*G0_0_0_0_0_1_2_0_1 - 0.338624338624345*G0_0_0_0_0_1_3_1_0 - 0.338624338624345*G0_0_0_0_0_1_3_1_1 + 0.338624338624345*G0_0_0_0_0_1_4_1_0 + 0.338624338624345*G0_0_0_0_0_1_5_1_1 + 0.338624338624345*G0_0_0_1_0_0_0_0_0 + 0.338624338624345*G0_0_0_1_0_0_0_0_1 - 0.338624338624345*G0_0_0_1_0_0_1_0_0 - 0.338624338624345*G0_0_0_1_0_0_2_0_1 + 0.338624338624345*G0_0_0_1_0_0_3_1_0 + 0.338624338624345*G0_0_0_1_0_0_3_1_1 - 0.338624338624345*G0_0_0_1_0_0_4_1_0 - 0.338624338624345*G0_0_0_1_0_0_5_1_1 + 0.338624338624345*G0_0_0_2_0_1_0_0_0 + 0.338624338624345*G0_0_0_2_0_1_0_0_1 - 0.338624338624345*G0_0_0_2_0_1_1_0_0 - 0.338624338624345*G0_0_0_2_0_1_2_0_1 + 0.338624338624345*G0_0_0_2_0_1_3_1_0 + 0.338624338624345*G0_0_0_2_0_1_3_1_1 - 0.338624338624345*G0_0_0_2_0_1_4_1_0 - 0.338624338624345*G0_0_0_2_0_1_5_1_1 - 0.338624338624345*G0_0_0_3_1_0_0_0_0 - 0.338624338624345*G0_0_0_3_1_0_0_0_1 + 0.338624338624345*G0_0_0_3_1_0_1_0_0 + 0.338624338624345*G0_0_0_3_1_0_2_0_1 - 0.338624338624345*G0_0_0_3_1_0_3_1_0 - 0.338624338624345*G0_0_0_3_1_0_3_1_1 + 0.338624338624345*G0_0_0_3_1_0_4_1_0 + 0.338624338624345*G0_0_0_3_1_0_5_1_1 - 0.338624338624345*G0_0_0_3_1_1_0_0_0 - 0.338624338624345*G0_0_0_3_1_1_0_0_1 + 0.338624338624345*G0_0_0_3_1_1_1_0_0 + 0.338624338624345*G0_0_0_3_1_1_2_0_1 - 0.338624338624345*G0_0_0_3_1_1_3_1_0 - 0.338624338624345*G0_0_0_3_1_1_3_1_1 + 0.338624338624345*G0_0_0_3_1_1_4_1_0 + 0.338624338624345*G0_0_0_3_1_1_5_1_1 + 0.338624338624345*G0_0_0_4_1_0_0_0_0 + 0.338624338624345*G0_0_0_4_1_0_0_0_1 - 0.338624338624345*G0_0_0_4_1_0_1_0_0 - 0.338624338624345*G0_0_0_4_1_0_2_0_1 + 0.338624338624345*G0_0_0_4_1_0_3_1_0 + 0.338624338624345*G0_0_0_4_1_0_3_1_1 - 0.338624338624345*G0_0_0_4_1_0_4_1_0 - 0.338624338624345*G0_0_0_4_1_0_5_1_1 + 0.338624338624345*G0_0_0_5_1_1_0_0_0 + 0.338624338624345*G0_0_0_5_1_1_0_0_1 - 0.338624338624345*G0_0_0_5_1_1_1_0_0 - 0.338624338624345*G0_0_0_5_1_1_2_0_1 + 0.338624338624345*G0_0_0_5_1_1_3_1_0 + 0.338624338624345*G0_0_0_5_1_1_3_1_1 - 0.338624338624345*G0_0_0_5_1_1_4_1_0 - 0.338624338624345*G0_0_0_5_1_1_5_1_1; + A[560] = -A[98] - 0.541798941798936*G0_0_1_0_0_0_0_0_0 - 0.541798941798936*G0_0_1_0_0_0_0_0_1 + 0.541798941798936*G0_0_1_0_0_0_1_0_0 + 0.541798941798936*G0_0_1_0_0_0_2_0_1 - 0.541798941798936*G0_0_1_0_0_0_3_1_0 - 0.541798941798936*G0_0_1_0_0_0_3_1_1 + 0.541798941798936*G0_0_1_0_0_0_4_1_0 + 0.541798941798936*G0_0_1_0_0_0_5_1_1 - 0.541798941798936*G0_0_1_0_0_1_0_0_0 - 0.541798941798936*G0_0_1_0_0_1_0_0_1 + 0.541798941798936*G0_0_1_0_0_1_1_0_0 + 0.541798941798936*G0_0_1_0_0_1_2_0_1 - 0.541798941798936*G0_0_1_0_0_1_3_1_0 - 0.541798941798936*G0_0_1_0_0_1_3_1_1 + 0.541798941798936*G0_0_1_0_0_1_4_1_0 + 0.541798941798936*G0_0_1_0_0_1_5_1_1 + 0.541798941798936*G0_0_1_1_0_0_0_0_0 + 0.541798941798936*G0_0_1_1_0_0_0_0_1 - 0.541798941798936*G0_0_1_1_0_0_1_0_0 - 0.541798941798936*G0_0_1_1_0_0_2_0_1 + 0.541798941798936*G0_0_1_1_0_0_3_1_0 + 0.541798941798936*G0_0_1_1_0_0_3_1_1 - 0.541798941798936*G0_0_1_1_0_0_4_1_0 - 0.541798941798936*G0_0_1_1_0_0_5_1_1 + 0.541798941798936*G0_0_1_2_0_1_0_0_0 + 0.541798941798936*G0_0_1_2_0_1_0_0_1 - 0.541798941798936*G0_0_1_2_0_1_1_0_0 - 0.541798941798936*G0_0_1_2_0_1_2_0_1 + 0.541798941798936*G0_0_1_2_0_1_3_1_0 + 0.541798941798936*G0_0_1_2_0_1_3_1_1 - 0.541798941798936*G0_0_1_2_0_1_4_1_0 - 0.541798941798936*G0_0_1_2_0_1_5_1_1 - 0.541798941798936*G0_0_1_3_1_0_0_0_0 - 0.541798941798936*G0_0_1_3_1_0_0_0_1 + 0.541798941798936*G0_0_1_3_1_0_1_0_0 + 0.541798941798936*G0_0_1_3_1_0_2_0_1 - 0.541798941798936*G0_0_1_3_1_0_3_1_0 - 0.541798941798936*G0_0_1_3_1_0_3_1_1 + 0.541798941798936*G0_0_1_3_1_0_4_1_0 + 0.541798941798936*G0_0_1_3_1_0_5_1_1 - 0.541798941798936*G0_0_1_3_1_1_0_0_0 - 0.541798941798936*G0_0_1_3_1_1_0_0_1 + 0.541798941798936*G0_0_1_3_1_1_1_0_0 + 0.541798941798936*G0_0_1_3_1_1_2_0_1 - 0.541798941798936*G0_0_1_3_1_1_3_1_0 - 0.541798941798936*G0_0_1_3_1_1_3_1_1 + 0.541798941798936*G0_0_1_3_1_1_4_1_0 + 0.541798941798936*G0_0_1_3_1_1_5_1_1 + 0.541798941798936*G0_0_1_4_1_0_0_0_0 + 0.541798941798936*G0_0_1_4_1_0_0_0_1 - 0.541798941798936*G0_0_1_4_1_0_1_0_0 - 0.541798941798936*G0_0_1_4_1_0_2_0_1 + 0.541798941798936*G0_0_1_4_1_0_3_1_0 + 0.541798941798936*G0_0_1_4_1_0_3_1_1 - 0.541798941798936*G0_0_1_4_1_0_4_1_0 - 0.541798941798936*G0_0_1_4_1_0_5_1_1 + 0.541798941798936*G0_0_1_5_1_1_0_0_0 + 0.541798941798936*G0_0_1_5_1_1_0_0_1 - 0.541798941798936*G0_0_1_5_1_1_1_0_0 - 0.541798941798936*G0_0_1_5_1_1_2_0_1 + 0.541798941798936*G0_0_1_5_1_1_3_1_0 + 0.541798941798936*G0_0_1_5_1_1_3_1_1 - 0.541798941798936*G0_0_1_5_1_1_4_1_0 - 0.541798941798936*G0_0_1_5_1_1_5_1_1 + 0.338624338624348*G0_1_1_0_0_0_0_0_0 + 0.338624338624348*G0_1_1_0_0_0_0_0_1 - 0.338624338624348*G0_1_1_0_0_0_1_0_0 - 0.338624338624348*G0_1_1_0_0_0_2_0_1 + 0.338624338624348*G0_1_1_0_0_0_3_1_0 + 0.338624338624348*G0_1_1_0_0_0_3_1_1 - 0.338624338624348*G0_1_1_0_0_0_4_1_0 - 0.338624338624348*G0_1_1_0_0_0_5_1_1 + 0.338624338624348*G0_1_1_0_0_1_0_0_0 + 0.338624338624348*G0_1_1_0_0_1_0_0_1 - 0.338624338624348*G0_1_1_0_0_1_1_0_0 - 0.338624338624348*G0_1_1_0_0_1_2_0_1 + 0.338624338624348*G0_1_1_0_0_1_3_1_0 + 0.338624338624348*G0_1_1_0_0_1_3_1_1 - 0.338624338624348*G0_1_1_0_0_1_4_1_0 - 0.338624338624348*G0_1_1_0_0_1_5_1_1 - 0.338624338624348*G0_1_1_1_0_0_0_0_0 - 0.338624338624348*G0_1_1_1_0_0_0_0_1 + 0.338624338624348*G0_1_1_1_0_0_1_0_0 + 0.338624338624348*G0_1_1_1_0_0_2_0_1 - 0.338624338624348*G0_1_1_1_0_0_3_1_0 - 0.338624338624348*G0_1_1_1_0_0_3_1_1 + 0.338624338624348*G0_1_1_1_0_0_4_1_0 + 0.338624338624348*G0_1_1_1_0_0_5_1_1 - 0.338624338624348*G0_1_1_2_0_1_0_0_0 - 0.338624338624348*G0_1_1_2_0_1_0_0_1 + 0.338624338624348*G0_1_1_2_0_1_1_0_0 + 0.338624338624348*G0_1_1_2_0_1_2_0_1 - 0.338624338624348*G0_1_1_2_0_1_3_1_0 - 0.338624338624348*G0_1_1_2_0_1_3_1_1 + 0.338624338624348*G0_1_1_2_0_1_4_1_0 + 0.338624338624348*G0_1_1_2_0_1_5_1_1 + 0.338624338624348*G0_1_1_3_1_0_0_0_0 + 0.338624338624348*G0_1_1_3_1_0_0_0_1 - 0.338624338624348*G0_1_1_3_1_0_1_0_0 - 0.338624338624348*G0_1_1_3_1_0_2_0_1 + 0.338624338624348*G0_1_1_3_1_0_3_1_0 + 0.338624338624348*G0_1_1_3_1_0_3_1_1 - 0.338624338624348*G0_1_1_3_1_0_4_1_0 - 0.338624338624348*G0_1_1_3_1_0_5_1_1 + 0.338624338624348*G0_1_1_3_1_1_0_0_0 + 0.338624338624348*G0_1_1_3_1_1_0_0_1 - 0.338624338624348*G0_1_1_3_1_1_1_0_0 - 0.338624338624348*G0_1_1_3_1_1_2_0_1 + 0.338624338624348*G0_1_1_3_1_1_3_1_0 + 0.338624338624348*G0_1_1_3_1_1_3_1_1 - 0.338624338624348*G0_1_1_3_1_1_4_1_0 - 0.338624338624348*G0_1_1_3_1_1_5_1_1 - 0.338624338624348*G0_1_1_4_1_0_0_0_0 - 0.338624338624348*G0_1_1_4_1_0_0_0_1 + 0.338624338624348*G0_1_1_4_1_0_1_0_0 + 0.338624338624348*G0_1_1_4_1_0_2_0_1 - 0.338624338624348*G0_1_1_4_1_0_3_1_0 - 0.338624338624348*G0_1_1_4_1_0_3_1_1 + 0.338624338624348*G0_1_1_4_1_0_4_1_0 + 0.338624338624348*G0_1_1_4_1_0_5_1_1 - 0.338624338624348*G0_1_1_5_1_1_0_0_0 - 0.338624338624348*G0_1_1_5_1_1_0_0_1 + 0.338624338624348*G0_1_1_5_1_1_1_0_0 + 0.338624338624348*G0_1_1_5_1_1_2_0_1 - 0.338624338624348*G0_1_1_5_1_1_3_1_0 - 0.338624338624348*G0_1_1_5_1_1_3_1_1 + 0.338624338624348*G0_1_1_5_1_1_4_1_0 + 0.338624338624348*G0_1_1_5_1_1_5_1_1; + A[817] = 0.0; + A[38] = A[181]; + A[123] = A[588]; + A[840] = 0.0; + A[75] = 0.0; + A[152] = A[617]; + A[875] = 0.0; + A[486] = 0.0; + A[189] = A[741]; + A[589] = A[124]; + A[517] = 0.0; + A[222] = A[367]; + A[620] = -A[245] + 1.69312169312171*G0_1_1_0_0_0_0_0_0 + 1.69312169312171*G0_1_1_0_0_0_0_0_1 - 1.69312169312171*G0_1_1_0_0_0_1_0_0 - 1.69312169312171*G0_1_1_0_0_0_2_0_1 + 1.69312169312171*G0_1_1_0_0_0_3_1_0 + 1.69312169312171*G0_1_1_0_0_0_3_1_1 - 1.69312169312171*G0_1_1_0_0_0_4_1_0 - 1.69312169312171*G0_1_1_0_0_0_5_1_1 + 1.69312169312171*G0_1_1_0_0_1_0_0_0 + 1.69312169312171*G0_1_1_0_0_1_0_0_1 - 1.69312169312171*G0_1_1_0_0_1_1_0_0 - 1.69312169312171*G0_1_1_0_0_1_2_0_1 + 1.69312169312171*G0_1_1_0_0_1_3_1_0 + 1.69312169312171*G0_1_1_0_0_1_3_1_1 - 1.69312169312171*G0_1_1_0_0_1_4_1_0 - 1.69312169312171*G0_1_1_0_0_1_5_1_1 - 1.69312169312171*G0_1_1_1_0_0_0_0_0 - 1.69312169312171*G0_1_1_1_0_0_0_0_1 + 1.69312169312171*G0_1_1_1_0_0_1_0_0 + 1.69312169312171*G0_1_1_1_0_0_2_0_1 - 1.69312169312171*G0_1_1_1_0_0_3_1_0 - 1.69312169312171*G0_1_1_1_0_0_3_1_1 + 1.69312169312171*G0_1_1_1_0_0_4_1_0 + 1.69312169312171*G0_1_1_1_0_0_5_1_1 - 1.69312169312171*G0_1_1_2_0_1_0_0_0 - 1.69312169312171*G0_1_1_2_0_1_0_0_1 + 1.69312169312171*G0_1_1_2_0_1_1_0_0 + 1.69312169312171*G0_1_1_2_0_1_2_0_1 - 1.69312169312171*G0_1_1_2_0_1_3_1_0 - 1.69312169312171*G0_1_1_2_0_1_3_1_1 + 1.69312169312171*G0_1_1_2_0_1_4_1_0 + 1.69312169312171*G0_1_1_2_0_1_5_1_1 + 1.69312169312171*G0_1_1_3_1_0_0_0_0 + 1.69312169312171*G0_1_1_3_1_0_0_0_1 - 1.69312169312171*G0_1_1_3_1_0_1_0_0 - 1.69312169312171*G0_1_1_3_1_0_2_0_1 + 1.69312169312171*G0_1_1_3_1_0_3_1_0 + 1.69312169312171*G0_1_1_3_1_0_3_1_1 - 1.69312169312171*G0_1_1_3_1_0_4_1_0 - 1.69312169312171*G0_1_1_3_1_0_5_1_1 + 1.69312169312171*G0_1_1_3_1_1_0_0_0 + 1.69312169312171*G0_1_1_3_1_1_0_0_1 - 1.69312169312171*G0_1_1_3_1_1_1_0_0 - 1.69312169312171*G0_1_1_3_1_1_2_0_1 + 1.69312169312171*G0_1_1_3_1_1_3_1_0 + 1.69312169312171*G0_1_1_3_1_1_3_1_1 - 1.69312169312171*G0_1_1_3_1_1_4_1_0 - 1.69312169312171*G0_1_1_3_1_1_5_1_1 - 1.69312169312171*G0_1_1_4_1_0_0_0_0 - 1.69312169312171*G0_1_1_4_1_0_0_0_1 + 1.69312169312171*G0_1_1_4_1_0_1_0_0 + 1.69312169312171*G0_1_1_4_1_0_2_0_1 - 1.69312169312171*G0_1_1_4_1_0_3_1_0 - 1.69312169312171*G0_1_1_4_1_0_3_1_1 + 1.69312169312171*G0_1_1_4_1_0_4_1_0 + 1.69312169312171*G0_1_1_4_1_0_5_1_1 - 1.69312169312171*G0_1_1_5_1_1_0_0_0 - 1.69312169312171*G0_1_1_5_1_1_0_0_1 + 1.69312169312171*G0_1_1_5_1_1_1_0_0 + 1.69312169312171*G0_1_1_5_1_1_2_0_1 - 1.69312169312171*G0_1_1_5_1_1_3_1_0 - 1.69312169312171*G0_1_1_5_1_1_3_1_1 + 1.69312169312171*G0_1_1_5_1_1_4_1_0 + 1.69312169312171*G0_1_1_5_1_1_5_1_1; + A[544] = 0.0; + A[508] = A[421]; + A[639] = 0.0; + A[535] = A[534]; + A[666] = 0.0; + A[697] = 0.0; + A[308] = A[715]; + A[264] = 0.0; + A[335] = -A[716] - 0.338624338624348*G0_1_1_0_0_0_0_0_0 - 0.338624338624348*G0_1_1_0_0_0_0_0_1 + 0.338624338624348*G0_1_1_0_0_0_1_0_0 + 0.338624338624348*G0_1_1_0_0_0_2_0_1 - 0.338624338624348*G0_1_1_0_0_0_3_1_0 - 0.338624338624348*G0_1_1_0_0_0_3_1_1 + 0.338624338624348*G0_1_1_0_0_0_4_1_0 + 0.338624338624348*G0_1_1_0_0_0_5_1_1 - 0.338624338624348*G0_1_1_0_0_1_0_0_0 - 0.338624338624348*G0_1_1_0_0_1_0_0_1 + 0.338624338624348*G0_1_1_0_0_1_1_0_0 + 0.338624338624348*G0_1_1_0_0_1_2_0_1 - 0.338624338624348*G0_1_1_0_0_1_3_1_0 - 0.338624338624348*G0_1_1_0_0_1_3_1_1 + 0.338624338624348*G0_1_1_0_0_1_4_1_0 + 0.338624338624348*G0_1_1_0_0_1_5_1_1 + 0.338624338624348*G0_1_1_1_0_0_0_0_0 + 0.338624338624348*G0_1_1_1_0_0_0_0_1 - 0.338624338624348*G0_1_1_1_0_0_1_0_0 - 0.338624338624348*G0_1_1_1_0_0_2_0_1 + 0.338624338624348*G0_1_1_1_0_0_3_1_0 + 0.338624338624348*G0_1_1_1_0_0_3_1_1 - 0.338624338624348*G0_1_1_1_0_0_4_1_0 - 0.338624338624348*G0_1_1_1_0_0_5_1_1 + 0.338624338624348*G0_1_1_2_0_1_0_0_0 + 0.338624338624348*G0_1_1_2_0_1_0_0_1 - 0.338624338624348*G0_1_1_2_0_1_1_0_0 - 0.338624338624348*G0_1_1_2_0_1_2_0_1 + 0.338624338624348*G0_1_1_2_0_1_3_1_0 + 0.338624338624348*G0_1_1_2_0_1_3_1_1 - 0.338624338624348*G0_1_1_2_0_1_4_1_0 - 0.338624338624348*G0_1_1_2_0_1_5_1_1 - 0.338624338624348*G0_1_1_3_1_0_0_0_0 - 0.338624338624348*G0_1_1_3_1_0_0_0_1 + 0.338624338624348*G0_1_1_3_1_0_1_0_0 + 0.338624338624348*G0_1_1_3_1_0_2_0_1 - 0.338624338624348*G0_1_1_3_1_0_3_1_0 - 0.338624338624348*G0_1_1_3_1_0_3_1_1 + 0.338624338624348*G0_1_1_3_1_0_4_1_0 + 0.338624338624348*G0_1_1_3_1_0_5_1_1 - 0.338624338624348*G0_1_1_3_1_1_0_0_0 - 0.338624338624348*G0_1_1_3_1_1_0_0_1 + 0.338624338624348*G0_1_1_3_1_1_1_0_0 + 0.338624338624348*G0_1_1_3_1_1_2_0_1 - 0.338624338624348*G0_1_1_3_1_1_3_1_0 - 0.338624338624348*G0_1_1_3_1_1_3_1_1 + 0.338624338624348*G0_1_1_3_1_1_4_1_0 + 0.338624338624348*G0_1_1_3_1_1_5_1_1 + 0.338624338624348*G0_1_1_4_1_0_0_0_0 + 0.338624338624348*G0_1_1_4_1_0_0_0_1 - 0.338624338624348*G0_1_1_4_1_0_1_0_0 - 0.338624338624348*G0_1_1_4_1_0_2_0_1 + 0.338624338624348*G0_1_1_4_1_0_3_1_0 + 0.338624338624348*G0_1_1_4_1_0_3_1_1 - 0.338624338624348*G0_1_1_4_1_0_4_1_0 - 0.338624338624348*G0_1_1_4_1_0_5_1_1 + 0.338624338624348*G0_1_1_5_1_1_0_0_0 + 0.338624338624348*G0_1_1_5_1_1_0_0_1 - 0.338624338624348*G0_1_1_5_1_1_1_0_0 - 0.338624338624348*G0_1_1_5_1_1_2_0_1 + 0.338624338624348*G0_1_1_5_1_1_3_1_0 + 0.338624338624348*G0_1_1_5_1_1_3_1_1 - 0.338624338624348*G0_1_1_5_1_1_4_1_0 - 0.338624338624348*G0_1_1_5_1_1_5_1_1; + A[291] = 0.0; + A[747] = A[834]; + A[438] = 0.0; + A[366] = A[192]; + A[318] = 0.0; + A[776] = A[805] + 1.11746031746033*G0_0_1_0_0_0_0_0_0 + 1.11746031746033*G0_0_1_0_0_0_0_0_1 - 1.11746031746033*G0_0_1_0_0_0_1_0_0 - 1.11746031746033*G0_0_1_0_0_0_2_0_1 + 1.11746031746033*G0_0_1_0_0_0_3_1_0 + 1.11746031746033*G0_0_1_0_0_0_3_1_1 - 1.11746031746033*G0_0_1_0_0_0_4_1_0 - 1.11746031746033*G0_0_1_0_0_0_5_1_1 + 1.11746031746033*G0_0_1_0_0_1_0_0_0 + 1.11746031746033*G0_0_1_0_0_1_0_0_1 - 1.11746031746033*G0_0_1_0_0_1_1_0_0 - 1.11746031746033*G0_0_1_0_0_1_2_0_1 + 1.11746031746033*G0_0_1_0_0_1_3_1_0 + 1.11746031746033*G0_0_1_0_0_1_3_1_1 - 1.11746031746033*G0_0_1_0_0_1_4_1_0 - 1.11746031746033*G0_0_1_0_0_1_5_1_1 - 1.11746031746033*G0_0_1_1_0_0_0_0_0 - 1.11746031746033*G0_0_1_1_0_0_0_0_1 + 1.11746031746033*G0_0_1_1_0_0_1_0_0 + 1.11746031746033*G0_0_1_1_0_0_2_0_1 - 1.11746031746033*G0_0_1_1_0_0_3_1_0 - 1.11746031746033*G0_0_1_1_0_0_3_1_1 + 1.11746031746033*G0_0_1_1_0_0_4_1_0 + 1.11746031746033*G0_0_1_1_0_0_5_1_1 - 1.11746031746033*G0_0_1_2_0_1_0_0_0 - 1.11746031746033*G0_0_1_2_0_1_0_0_1 + 1.11746031746033*G0_0_1_2_0_1_1_0_0 + 1.11746031746033*G0_0_1_2_0_1_2_0_1 - 1.11746031746033*G0_0_1_2_0_1_3_1_0 - 1.11746031746033*G0_0_1_2_0_1_3_1_1 + 1.11746031746033*G0_0_1_2_0_1_4_1_0 + 1.11746031746033*G0_0_1_2_0_1_5_1_1 + 1.11746031746033*G0_0_1_3_1_0_0_0_0 + 1.11746031746033*G0_0_1_3_1_0_0_0_1 - 1.11746031746033*G0_0_1_3_1_0_1_0_0 - 1.11746031746033*G0_0_1_3_1_0_2_0_1 + 1.11746031746033*G0_0_1_3_1_0_3_1_0 + 1.11746031746033*G0_0_1_3_1_0_3_1_1 - 1.11746031746033*G0_0_1_3_1_0_4_1_0 - 1.11746031746033*G0_0_1_3_1_0_5_1_1 + 1.11746031746033*G0_0_1_3_1_1_0_0_0 + 1.11746031746033*G0_0_1_3_1_1_0_0_1 - 1.11746031746033*G0_0_1_3_1_1_1_0_0 - 1.11746031746033*G0_0_1_3_1_1_2_0_1 + 1.11746031746033*G0_0_1_3_1_1_3_1_0 + 1.11746031746033*G0_0_1_3_1_1_3_1_1 - 1.11746031746033*G0_0_1_3_1_1_4_1_0 - 1.11746031746033*G0_0_1_3_1_1_5_1_1 - 1.11746031746033*G0_0_1_4_1_0_0_0_0 - 1.11746031746033*G0_0_1_4_1_0_0_0_1 + 1.11746031746033*G0_0_1_4_1_0_1_0_0 + 1.11746031746033*G0_0_1_4_1_0_2_0_1 - 1.11746031746033*G0_0_1_4_1_0_3_1_0 - 1.11746031746033*G0_0_1_4_1_0_3_1_1 + 1.11746031746033*G0_0_1_4_1_0_4_1_0 + 1.11746031746033*G0_0_1_4_1_0_5_1_1 - 1.11746031746033*G0_0_1_5_1_1_0_0_0 - 1.11746031746033*G0_0_1_5_1_1_0_0_1 + 1.11746031746033*G0_0_1_5_1_1_1_0_0 + 1.11746031746033*G0_0_1_5_1_1_2_0_1 - 1.11746031746033*G0_0_1_5_1_1_3_1_0 - 1.11746031746033*G0_0_1_5_1_1_3_1_1 + 1.11746031746033*G0_0_1_5_1_1_4_1_0 + 1.11746031746033*G0_0_1_5_1_1_5_1_1 - 1.11746031746033*G0_1_0_0_0_0_0_0_0 - 1.11746031746033*G0_1_0_0_0_0_0_0_1 + 1.11746031746033*G0_1_0_0_0_0_1_0_0 + 1.11746031746033*G0_1_0_0_0_0_2_0_1 - 1.11746031746033*G0_1_0_0_0_0_3_1_0 - 1.11746031746033*G0_1_0_0_0_0_3_1_1 + 1.11746031746033*G0_1_0_0_0_0_4_1_0 + 1.11746031746033*G0_1_0_0_0_0_5_1_1 - 1.11746031746033*G0_1_0_0_0_1_0_0_0 - 1.11746031746033*G0_1_0_0_0_1_0_0_1 + 1.11746031746033*G0_1_0_0_0_1_1_0_0 + 1.11746031746033*G0_1_0_0_0_1_2_0_1 - 1.11746031746033*G0_1_0_0_0_1_3_1_0 - 1.11746031746033*G0_1_0_0_0_1_3_1_1 + 1.11746031746033*G0_1_0_0_0_1_4_1_0 + 1.11746031746033*G0_1_0_0_0_1_5_1_1 + 1.11746031746033*G0_1_0_1_0_0_0_0_0 + 1.11746031746033*G0_1_0_1_0_0_0_0_1 - 1.11746031746033*G0_1_0_1_0_0_1_0_0 - 1.11746031746033*G0_1_0_1_0_0_2_0_1 + 1.11746031746033*G0_1_0_1_0_0_3_1_0 + 1.11746031746033*G0_1_0_1_0_0_3_1_1 - 1.11746031746033*G0_1_0_1_0_0_4_1_0 - 1.11746031746033*G0_1_0_1_0_0_5_1_1 + 1.11746031746033*G0_1_0_2_0_1_0_0_0 + 1.11746031746033*G0_1_0_2_0_1_0_0_1 - 1.11746031746033*G0_1_0_2_0_1_1_0_0 - 1.11746031746033*G0_1_0_2_0_1_2_0_1 + 1.11746031746033*G0_1_0_2_0_1_3_1_0 + 1.11746031746033*G0_1_0_2_0_1_3_1_1 - 1.11746031746033*G0_1_0_2_0_1_4_1_0 - 1.11746031746033*G0_1_0_2_0_1_5_1_1 - 1.11746031746033*G0_1_0_3_1_0_0_0_0 - 1.11746031746033*G0_1_0_3_1_0_0_0_1 + 1.11746031746033*G0_1_0_3_1_0_1_0_0 + 1.11746031746033*G0_1_0_3_1_0_2_0_1 - 1.11746031746033*G0_1_0_3_1_0_3_1_0 - 1.11746031746033*G0_1_0_3_1_0_3_1_1 + 1.11746031746033*G0_1_0_3_1_0_4_1_0 + 1.11746031746033*G0_1_0_3_1_0_5_1_1 - 1.11746031746033*G0_1_0_3_1_1_0_0_0 - 1.11746031746033*G0_1_0_3_1_1_0_0_1 + 1.11746031746033*G0_1_0_3_1_1_1_0_0 + 1.11746031746033*G0_1_0_3_1_1_2_0_1 - 1.11746031746033*G0_1_0_3_1_1_3_1_0 - 1.11746031746033*G0_1_0_3_1_1_3_1_1 + 1.11746031746033*G0_1_0_3_1_1_4_1_0 + 1.11746031746033*G0_1_0_3_1_1_5_1_1 + 1.11746031746033*G0_1_0_4_1_0_0_0_0 + 1.11746031746033*G0_1_0_4_1_0_0_0_1 - 1.11746031746033*G0_1_0_4_1_0_1_0_0 - 1.11746031746033*G0_1_0_4_1_0_2_0_1 + 1.11746031746033*G0_1_0_4_1_0_3_1_0 + 1.11746031746033*G0_1_0_4_1_0_3_1_1 - 1.11746031746033*G0_1_0_4_1_0_4_1_0 - 1.11746031746033*G0_1_0_4_1_0_5_1_1 + 1.11746031746033*G0_1_0_5_1_1_0_0_0 + 1.11746031746033*G0_1_0_5_1_1_0_0_1 - 1.11746031746033*G0_1_0_5_1_1_1_0_0 - 1.11746031746033*G0_1_0_5_1_1_2_0_1 + 1.11746031746033*G0_1_0_5_1_1_3_1_0 + 1.11746031746033*G0_1_0_5_1_1_3_1_1 - 1.11746031746033*G0_1_0_5_1_1_4_1_0 - 1.11746031746033*G0_1_0_5_1_1_5_1_1; + A[461] = 0.0; + A[397] = A[688]; + A[357] = 0.0; + A[797] = A[534]; + A[4] = A[5]; + A[721] = 0.0; + A[388] = 0.0; + A[838] = A[373]; + A[31] = -4.40624999999983*A[421]; + A[130] = A[769]; + A[66] = A[531]; + A[161] = A[335]; + A[113] = 0.0; + A[180] = A[645]; + A[136] = 0.0; + A[594] = A[274]; + A[215] = -A[683] - 1.11746031746033*G0_0_1_0_0_0_0_0_0 - 1.11746031746033*G0_0_1_0_0_0_0_0_1 + 1.11746031746033*G0_0_1_0_0_0_1_0_0 + 1.11746031746033*G0_0_1_0_0_0_2_0_1 - 1.11746031746033*G0_0_1_0_0_0_3_1_0 - 1.11746031746033*G0_0_1_0_0_0_3_1_1 + 1.11746031746033*G0_0_1_0_0_0_4_1_0 + 1.11746031746033*G0_0_1_0_0_0_5_1_1 - 1.11746031746033*G0_0_1_0_0_1_0_0_0 - 1.11746031746033*G0_0_1_0_0_1_0_0_1 + 1.11746031746033*G0_0_1_0_0_1_1_0_0 + 1.11746031746033*G0_0_1_0_0_1_2_0_1 - 1.11746031746033*G0_0_1_0_0_1_3_1_0 - 1.11746031746033*G0_0_1_0_0_1_3_1_1 + 1.11746031746033*G0_0_1_0_0_1_4_1_0 + 1.11746031746033*G0_0_1_0_0_1_5_1_1 + 1.11746031746033*G0_0_1_1_0_0_0_0_0 + 1.11746031746033*G0_0_1_1_0_0_0_0_1 - 1.11746031746033*G0_0_1_1_0_0_1_0_0 - 1.11746031746033*G0_0_1_1_0_0_2_0_1 + 1.11746031746033*G0_0_1_1_0_0_3_1_0 + 1.11746031746033*G0_0_1_1_0_0_3_1_1 - 1.11746031746033*G0_0_1_1_0_0_4_1_0 - 1.11746031746033*G0_0_1_1_0_0_5_1_1 + 1.11746031746033*G0_0_1_2_0_1_0_0_0 + 1.11746031746033*G0_0_1_2_0_1_0_0_1 - 1.11746031746033*G0_0_1_2_0_1_1_0_0 - 1.11746031746033*G0_0_1_2_0_1_2_0_1 + 1.11746031746033*G0_0_1_2_0_1_3_1_0 + 1.11746031746033*G0_0_1_2_0_1_3_1_1 - 1.11746031746033*G0_0_1_2_0_1_4_1_0 - 1.11746031746033*G0_0_1_2_0_1_5_1_1 - 1.11746031746033*G0_0_1_3_1_0_0_0_0 - 1.11746031746033*G0_0_1_3_1_0_0_0_1 + 1.11746031746033*G0_0_1_3_1_0_1_0_0 + 1.11746031746033*G0_0_1_3_1_0_2_0_1 - 1.11746031746033*G0_0_1_3_1_0_3_1_0 - 1.11746031746033*G0_0_1_3_1_0_3_1_1 + 1.11746031746033*G0_0_1_3_1_0_4_1_0 + 1.11746031746033*G0_0_1_3_1_0_5_1_1 - 1.11746031746033*G0_0_1_3_1_1_0_0_0 - 1.11746031746033*G0_0_1_3_1_1_0_0_1 + 1.11746031746033*G0_0_1_3_1_1_1_0_0 + 1.11746031746033*G0_0_1_3_1_1_2_0_1 - 1.11746031746033*G0_0_1_3_1_1_3_1_0 - 1.11746031746033*G0_0_1_3_1_1_3_1_1 + 1.11746031746033*G0_0_1_3_1_1_4_1_0 + 1.11746031746033*G0_0_1_3_1_1_5_1_1 + 1.11746031746033*G0_0_1_4_1_0_0_0_0 + 1.11746031746033*G0_0_1_4_1_0_0_0_1 - 1.11746031746033*G0_0_1_4_1_0_1_0_0 - 1.11746031746033*G0_0_1_4_1_0_2_0_1 + 1.11746031746033*G0_0_1_4_1_0_3_1_0 + 1.11746031746033*G0_0_1_4_1_0_3_1_1 - 1.11746031746033*G0_0_1_4_1_0_4_1_0 - 1.11746031746033*G0_0_1_4_1_0_5_1_1 + 1.11746031746033*G0_0_1_5_1_1_0_0_0 + 1.11746031746033*G0_0_1_5_1_1_0_0_1 - 1.11746031746033*G0_0_1_5_1_1_1_0_0 - 1.11746031746033*G0_0_1_5_1_1_2_0_1 + 1.11746031746033*G0_0_1_5_1_1_3_1_0 + 1.11746031746033*G0_0_1_5_1_1_3_1_1 - 1.11746031746033*G0_0_1_5_1_1_4_1_0 - 1.11746031746033*G0_0_1_5_1_1_5_1_1 - 1.84550264550266*G0_1_1_0_0_0_0_0_0 - 1.84550264550266*G0_1_1_0_0_0_0_0_1 + 1.84550264550266*G0_1_1_0_0_0_1_0_0 + 1.84550264550266*G0_1_1_0_0_0_2_0_1 - 1.84550264550266*G0_1_1_0_0_0_3_1_0 - 1.84550264550266*G0_1_1_0_0_0_3_1_1 + 1.84550264550266*G0_1_1_0_0_0_4_1_0 + 1.84550264550266*G0_1_1_0_0_0_5_1_1 - 1.84550264550266*G0_1_1_0_0_1_0_0_0 - 1.84550264550266*G0_1_1_0_0_1_0_0_1 + 1.84550264550266*G0_1_1_0_0_1_1_0_0 + 1.84550264550266*G0_1_1_0_0_1_2_0_1 - 1.84550264550266*G0_1_1_0_0_1_3_1_0 - 1.84550264550266*G0_1_1_0_0_1_3_1_1 + 1.84550264550266*G0_1_1_0_0_1_4_1_0 + 1.84550264550266*G0_1_1_0_0_1_5_1_1 + 1.84550264550266*G0_1_1_1_0_0_0_0_0 + 1.84550264550266*G0_1_1_1_0_0_0_0_1 - 1.84550264550266*G0_1_1_1_0_0_1_0_0 - 1.84550264550266*G0_1_1_1_0_0_2_0_1 + 1.84550264550266*G0_1_1_1_0_0_3_1_0 + 1.84550264550266*G0_1_1_1_0_0_3_1_1 - 1.84550264550266*G0_1_1_1_0_0_4_1_0 - 1.84550264550266*G0_1_1_1_0_0_5_1_1 + 1.84550264550266*G0_1_1_2_0_1_0_0_0 + 1.84550264550266*G0_1_1_2_0_1_0_0_1 - 1.84550264550266*G0_1_1_2_0_1_1_0_0 - 1.84550264550266*G0_1_1_2_0_1_2_0_1 + 1.84550264550266*G0_1_1_2_0_1_3_1_0 + 1.84550264550266*G0_1_1_2_0_1_3_1_1 - 1.84550264550266*G0_1_1_2_0_1_4_1_0 - 1.84550264550266*G0_1_1_2_0_1_5_1_1 - 1.84550264550266*G0_1_1_3_1_0_0_0_0 - 1.84550264550266*G0_1_1_3_1_0_0_0_1 + 1.84550264550266*G0_1_1_3_1_0_1_0_0 + 1.84550264550266*G0_1_1_3_1_0_2_0_1 - 1.84550264550266*G0_1_1_3_1_0_3_1_0 - 1.84550264550266*G0_1_1_3_1_0_3_1_1 + 1.84550264550266*G0_1_1_3_1_0_4_1_0 + 1.84550264550266*G0_1_1_3_1_0_5_1_1 - 1.84550264550266*G0_1_1_3_1_1_0_0_0 - 1.84550264550266*G0_1_1_3_1_1_0_0_1 + 1.84550264550266*G0_1_1_3_1_1_1_0_0 + 1.84550264550266*G0_1_1_3_1_1_2_0_1 - 1.84550264550266*G0_1_1_3_1_1_3_1_0 - 1.84550264550266*G0_1_1_3_1_1_3_1_1 + 1.84550264550266*G0_1_1_3_1_1_4_1_0 + 1.84550264550266*G0_1_1_3_1_1_5_1_1 + 1.84550264550266*G0_1_1_4_1_0_0_0_0 + 1.84550264550266*G0_1_1_4_1_0_0_0_1 - 1.84550264550266*G0_1_1_4_1_0_1_0_0 - 1.84550264550266*G0_1_1_4_1_0_2_0_1 + 1.84550264550266*G0_1_1_4_1_0_3_1_0 + 1.84550264550266*G0_1_1_4_1_0_3_1_1 - 1.84550264550266*G0_1_1_4_1_0_4_1_0 - 1.84550264550266*G0_1_1_4_1_0_5_1_1 + 1.84550264550266*G0_1_1_5_1_1_0_0_0 + 1.84550264550266*G0_1_1_5_1_1_0_0_1 - 1.84550264550266*G0_1_1_5_1_1_1_0_0 - 1.84550264550266*G0_1_1_5_1_1_2_0_1 + 1.84550264550266*G0_1_1_5_1_1_3_1_0 + 1.84550264550266*G0_1_1_5_1_1_3_1_1 - 1.84550264550266*G0_1_1_5_1_1_4_1_0 - 1.84550264550266*G0_1_1_5_1_1_5_1_1; + A[892] = -A[215] - 2.08253968253974*G0_0_0_0_0_0_0_0_0 - 2.08253968253974*G0_0_0_0_0_0_0_0_1 + 2.08253968253974*G0_0_0_0_0_0_1_0_0 + 2.08253968253974*G0_0_0_0_0_0_2_0_1 - 2.08253968253974*G0_0_0_0_0_0_3_1_0 - 2.08253968253974*G0_0_0_0_0_0_3_1_1 + 2.08253968253974*G0_0_0_0_0_0_4_1_0 + 2.08253968253974*G0_0_0_0_0_0_5_1_1 - 2.08253968253974*G0_0_0_0_0_1_0_0_0 - 2.08253968253974*G0_0_0_0_0_1_0_0_1 + 2.08253968253974*G0_0_0_0_0_1_1_0_0 + 2.08253968253974*G0_0_0_0_0_1_2_0_1 - 2.08253968253974*G0_0_0_0_0_1_3_1_0 - 2.08253968253974*G0_0_0_0_0_1_3_1_1 + 2.08253968253974*G0_0_0_0_0_1_4_1_0 + 2.08253968253974*G0_0_0_0_0_1_5_1_1 + 2.08253968253974*G0_0_0_1_0_0_0_0_0 + 2.08253968253974*G0_0_0_1_0_0_0_0_1 - 2.08253968253974*G0_0_0_1_0_0_1_0_0 - 2.08253968253974*G0_0_0_1_0_0_2_0_1 + 2.08253968253974*G0_0_0_1_0_0_3_1_0 + 2.08253968253974*G0_0_0_1_0_0_3_1_1 - 2.08253968253974*G0_0_0_1_0_0_4_1_0 - 2.08253968253974*G0_0_0_1_0_0_5_1_1 + 2.08253968253974*G0_0_0_2_0_1_0_0_0 + 2.08253968253974*G0_0_0_2_0_1_0_0_1 - 2.08253968253974*G0_0_0_2_0_1_1_0_0 - 2.08253968253974*G0_0_0_2_0_1_2_0_1 + 2.08253968253974*G0_0_0_2_0_1_3_1_0 + 2.08253968253974*G0_0_0_2_0_1_3_1_1 - 2.08253968253974*G0_0_0_2_0_1_4_1_0 - 2.08253968253974*G0_0_0_2_0_1_5_1_1 - 2.08253968253974*G0_0_0_3_1_0_0_0_0 - 2.08253968253974*G0_0_0_3_1_0_0_0_1 + 2.08253968253974*G0_0_0_3_1_0_1_0_0 + 2.08253968253974*G0_0_0_3_1_0_2_0_1 - 2.08253968253974*G0_0_0_3_1_0_3_1_0 - 2.08253968253974*G0_0_0_3_1_0_3_1_1 + 2.08253968253974*G0_0_0_3_1_0_4_1_0 + 2.08253968253974*G0_0_0_3_1_0_5_1_1 - 2.08253968253974*G0_0_0_3_1_1_0_0_0 - 2.08253968253974*G0_0_0_3_1_1_0_0_1 + 2.08253968253974*G0_0_0_3_1_1_1_0_0 + 2.08253968253974*G0_0_0_3_1_1_2_0_1 - 2.08253968253974*G0_0_0_3_1_1_3_1_0 - 2.08253968253974*G0_0_0_3_1_1_3_1_1 + 2.08253968253974*G0_0_0_3_1_1_4_1_0 + 2.08253968253974*G0_0_0_3_1_1_5_1_1 + 2.08253968253974*G0_0_0_4_1_0_0_0_0 + 2.08253968253974*G0_0_0_4_1_0_0_0_1 - 2.08253968253974*G0_0_0_4_1_0_1_0_0 - 2.08253968253974*G0_0_0_4_1_0_2_0_1 + 2.08253968253974*G0_0_0_4_1_0_3_1_0 + 2.08253968253974*G0_0_0_4_1_0_3_1_1 - 2.08253968253974*G0_0_0_4_1_0_4_1_0 - 2.08253968253974*G0_0_0_4_1_0_5_1_1 + 2.08253968253974*G0_0_0_5_1_1_0_0_0 + 2.08253968253974*G0_0_0_5_1_1_0_0_1 - 2.08253968253974*G0_0_0_5_1_1_1_0_0 - 2.08253968253974*G0_0_0_5_1_1_2_0_1 + 2.08253968253974*G0_0_0_5_1_1_3_1_0 + 2.08253968253974*G0_0_0_5_1_1_3_1_1 - 2.08253968253974*G0_0_0_5_1_1_4_1_0 - 2.08253968253974*G0_0_0_5_1_1_5_1_1 - 1.21058201058204*G0_0_1_0_0_0_0_0_0 - 1.21058201058204*G0_0_1_0_0_0_0_0_1 + 1.21058201058204*G0_0_1_0_0_0_1_0_0 + 1.21058201058204*G0_0_1_0_0_0_2_0_1 - 1.21058201058204*G0_0_1_0_0_0_3_1_0 - 1.21058201058204*G0_0_1_0_0_0_3_1_1 + 1.21058201058204*G0_0_1_0_0_0_4_1_0 + 1.21058201058204*G0_0_1_0_0_0_5_1_1 - 1.21058201058204*G0_0_1_0_0_1_0_0_0 - 1.21058201058204*G0_0_1_0_0_1_0_0_1 + 1.21058201058204*G0_0_1_0_0_1_1_0_0 + 1.21058201058204*G0_0_1_0_0_1_2_0_1 - 1.21058201058204*G0_0_1_0_0_1_3_1_0 - 1.21058201058204*G0_0_1_0_0_1_3_1_1 + 1.21058201058204*G0_0_1_0_0_1_4_1_0 + 1.21058201058204*G0_0_1_0_0_1_5_1_1 + 1.21058201058204*G0_0_1_1_0_0_0_0_0 + 1.21058201058204*G0_0_1_1_0_0_0_0_1 - 1.21058201058204*G0_0_1_1_0_0_1_0_0 - 1.21058201058204*G0_0_1_1_0_0_2_0_1 + 1.21058201058204*G0_0_1_1_0_0_3_1_0 + 1.21058201058204*G0_0_1_1_0_0_3_1_1 - 1.21058201058204*G0_0_1_1_0_0_4_1_0 - 1.21058201058204*G0_0_1_1_0_0_5_1_1 + 1.21058201058204*G0_0_1_2_0_1_0_0_0 + 1.21058201058204*G0_0_1_2_0_1_0_0_1 - 1.21058201058204*G0_0_1_2_0_1_1_0_0 - 1.21058201058204*G0_0_1_2_0_1_2_0_1 + 1.21058201058204*G0_0_1_2_0_1_3_1_0 + 1.21058201058204*G0_0_1_2_0_1_3_1_1 - 1.21058201058204*G0_0_1_2_0_1_4_1_0 - 1.21058201058204*G0_0_1_2_0_1_5_1_1 - 1.21058201058204*G0_0_1_3_1_0_0_0_0 - 1.21058201058204*G0_0_1_3_1_0_0_0_1 + 1.21058201058204*G0_0_1_3_1_0_1_0_0 + 1.21058201058204*G0_0_1_3_1_0_2_0_1 - 1.21058201058204*G0_0_1_3_1_0_3_1_0 - 1.21058201058204*G0_0_1_3_1_0_3_1_1 + 1.21058201058204*G0_0_1_3_1_0_4_1_0 + 1.21058201058204*G0_0_1_3_1_0_5_1_1 - 1.21058201058204*G0_0_1_3_1_1_0_0_0 - 1.21058201058204*G0_0_1_3_1_1_0_0_1 + 1.21058201058204*G0_0_1_3_1_1_1_0_0 + 1.21058201058204*G0_0_1_3_1_1_2_0_1 - 1.21058201058204*G0_0_1_3_1_1_3_1_0 - 1.21058201058204*G0_0_1_3_1_1_3_1_1 + 1.21058201058204*G0_0_1_3_1_1_4_1_0 + 1.21058201058204*G0_0_1_3_1_1_5_1_1 + 1.21058201058204*G0_0_1_4_1_0_0_0_0 + 1.21058201058204*G0_0_1_4_1_0_0_0_1 - 1.21058201058204*G0_0_1_4_1_0_1_0_0 - 1.21058201058204*G0_0_1_4_1_0_2_0_1 + 1.21058201058204*G0_0_1_4_1_0_3_1_0 + 1.21058201058204*G0_0_1_4_1_0_3_1_1 - 1.21058201058204*G0_0_1_4_1_0_4_1_0 - 1.21058201058204*G0_0_1_4_1_0_5_1_1 + 1.21058201058204*G0_0_1_5_1_1_0_0_0 + 1.21058201058204*G0_0_1_5_1_1_0_0_1 - 1.21058201058204*G0_0_1_5_1_1_1_0_0 - 1.21058201058204*G0_0_1_5_1_1_2_0_1 + 1.21058201058204*G0_0_1_5_1_1_3_1_0 + 1.21058201058204*G0_0_1_5_1_1_3_1_1 - 1.21058201058204*G0_0_1_5_1_1_4_1_0 - 1.21058201058204*G0_0_1_5_1_1_5_1_1 - 1.21058201058203*G0_1_0_0_0_0_0_0_0 - 1.21058201058203*G0_1_0_0_0_0_0_0_1 + 1.21058201058203*G0_1_0_0_0_0_1_0_0 + 1.21058201058203*G0_1_0_0_0_0_2_0_1 - 1.21058201058203*G0_1_0_0_0_0_3_1_0 - 1.21058201058203*G0_1_0_0_0_0_3_1_1 + 1.21058201058203*G0_1_0_0_0_0_4_1_0 + 1.21058201058203*G0_1_0_0_0_0_5_1_1 - 1.21058201058203*G0_1_0_0_0_1_0_0_0 - 1.21058201058203*G0_1_0_0_0_1_0_0_1 + 1.21058201058203*G0_1_0_0_0_1_1_0_0 + 1.21058201058203*G0_1_0_0_0_1_2_0_1 - 1.21058201058203*G0_1_0_0_0_1_3_1_0 - 1.21058201058203*G0_1_0_0_0_1_3_1_1 + 1.21058201058203*G0_1_0_0_0_1_4_1_0 + 1.21058201058203*G0_1_0_0_0_1_5_1_1 + 1.21058201058203*G0_1_0_1_0_0_0_0_0 + 1.21058201058203*G0_1_0_1_0_0_0_0_1 - 1.21058201058203*G0_1_0_1_0_0_1_0_0 - 1.21058201058203*G0_1_0_1_0_0_2_0_1 + 1.21058201058203*G0_1_0_1_0_0_3_1_0 + 1.21058201058203*G0_1_0_1_0_0_3_1_1 - 1.21058201058203*G0_1_0_1_0_0_4_1_0 - 1.21058201058203*G0_1_0_1_0_0_5_1_1 + 1.21058201058203*G0_1_0_2_0_1_0_0_0 + 1.21058201058203*G0_1_0_2_0_1_0_0_1 - 1.21058201058203*G0_1_0_2_0_1_1_0_0 - 1.21058201058203*G0_1_0_2_0_1_2_0_1 + 1.21058201058203*G0_1_0_2_0_1_3_1_0 + 1.21058201058203*G0_1_0_2_0_1_3_1_1 - 1.21058201058203*G0_1_0_2_0_1_4_1_0 - 1.21058201058203*G0_1_0_2_0_1_5_1_1 - 1.21058201058203*G0_1_0_3_1_0_0_0_0 - 1.21058201058203*G0_1_0_3_1_0_0_0_1 + 1.21058201058203*G0_1_0_3_1_0_1_0_0 + 1.21058201058203*G0_1_0_3_1_0_2_0_1 - 1.21058201058203*G0_1_0_3_1_0_3_1_0 - 1.21058201058203*G0_1_0_3_1_0_3_1_1 + 1.21058201058203*G0_1_0_3_1_0_4_1_0 + 1.21058201058203*G0_1_0_3_1_0_5_1_1 - 1.21058201058203*G0_1_0_3_1_1_0_0_0 - 1.21058201058203*G0_1_0_3_1_1_0_0_1 + 1.21058201058203*G0_1_0_3_1_1_1_0_0 + 1.21058201058203*G0_1_0_3_1_1_2_0_1 - 1.21058201058203*G0_1_0_3_1_1_3_1_0 - 1.21058201058203*G0_1_0_3_1_1_3_1_1 + 1.21058201058203*G0_1_0_3_1_1_4_1_0 + 1.21058201058203*G0_1_0_3_1_1_5_1_1 + 1.21058201058203*G0_1_0_4_1_0_0_0_0 + 1.21058201058203*G0_1_0_4_1_0_0_0_1 - 1.21058201058203*G0_1_0_4_1_0_1_0_0 - 1.21058201058203*G0_1_0_4_1_0_2_0_1 + 1.21058201058203*G0_1_0_4_1_0_3_1_0 + 1.21058201058203*G0_1_0_4_1_0_3_1_1 - 1.21058201058203*G0_1_0_4_1_0_4_1_0 - 1.21058201058203*G0_1_0_4_1_0_5_1_1 + 1.21058201058203*G0_1_0_5_1_1_0_0_0 + 1.21058201058203*G0_1_0_5_1_1_0_0_1 - 1.21058201058203*G0_1_0_5_1_1_1_0_0 - 1.21058201058203*G0_1_0_5_1_1_2_0_1 + 1.21058201058203*G0_1_0_5_1_1_3_1_0 + 1.21058201058203*G0_1_0_5_1_1_3_1_1 - 1.21058201058203*G0_1_0_5_1_1_4_1_0 - 1.21058201058203*G0_1_0_5_1_1_5_1_1; + A[427] = A[892]; + A[171] = 0.0; + A[619] = A[154]; + A[499] = A[34]; + A[206] = 0.0; + A[648] = A[96]; + A[528] = A[63]; + A[685] = A[307]; + A[565] = A[303]; + A[718] = A[252]; + A[441] = 0.0; + A[329] = 0.0; + A[390] = A[14]; + A[346] = 0.0; + A[804] = -A[273] + 0.880423280423283*G0_0_0_0_0_0_0_0_0 + 0.880423280423283*G0_0_0_0_0_0_0_0_1 - 0.880423280423283*G0_0_0_0_0_0_1_0_0 - 0.880423280423283*G0_0_0_0_0_0_2_0_1 + 0.880423280423283*G0_0_0_0_0_0_3_1_0 + 0.880423280423283*G0_0_0_0_0_0_3_1_1 - 0.880423280423283*G0_0_0_0_0_0_4_1_0 - 0.880423280423283*G0_0_0_0_0_0_5_1_1 + 0.880423280423283*G0_0_0_0_0_1_0_0_0 + 0.880423280423283*G0_0_0_0_0_1_0_0_1 - 0.880423280423283*G0_0_0_0_0_1_1_0_0 - 0.880423280423283*G0_0_0_0_0_1_2_0_1 + 0.880423280423283*G0_0_0_0_0_1_3_1_0 + 0.880423280423283*G0_0_0_0_0_1_3_1_1 - 0.880423280423283*G0_0_0_0_0_1_4_1_0 - 0.880423280423283*G0_0_0_0_0_1_5_1_1 - 0.880423280423283*G0_0_0_1_0_0_0_0_0 - 0.880423280423283*G0_0_0_1_0_0_0_0_1 + 0.880423280423283*G0_0_0_1_0_0_1_0_0 + 0.880423280423283*G0_0_0_1_0_0_2_0_1 - 0.880423280423283*G0_0_0_1_0_0_3_1_0 - 0.880423280423283*G0_0_0_1_0_0_3_1_1 + 0.880423280423283*G0_0_0_1_0_0_4_1_0 + 0.880423280423283*G0_0_0_1_0_0_5_1_1 - 0.880423280423283*G0_0_0_2_0_1_0_0_0 - 0.880423280423283*G0_0_0_2_0_1_0_0_1 + 0.880423280423283*G0_0_0_2_0_1_1_0_0 + 0.880423280423283*G0_0_0_2_0_1_2_0_1 - 0.880423280423283*G0_0_0_2_0_1_3_1_0 - 0.880423280423283*G0_0_0_2_0_1_3_1_1 + 0.880423280423283*G0_0_0_2_0_1_4_1_0 + 0.880423280423283*G0_0_0_2_0_1_5_1_1 + 0.880423280423283*G0_0_0_3_1_0_0_0_0 + 0.880423280423283*G0_0_0_3_1_0_0_0_1 - 0.880423280423283*G0_0_0_3_1_0_1_0_0 - 0.880423280423283*G0_0_0_3_1_0_2_0_1 + 0.880423280423283*G0_0_0_3_1_0_3_1_0 + 0.880423280423283*G0_0_0_3_1_0_3_1_1 - 0.880423280423283*G0_0_0_3_1_0_4_1_0 - 0.880423280423283*G0_0_0_3_1_0_5_1_1 + 0.880423280423283*G0_0_0_3_1_1_0_0_0 + 0.880423280423283*G0_0_0_3_1_1_0_0_1 - 0.880423280423283*G0_0_0_3_1_1_1_0_0 - 0.880423280423283*G0_0_0_3_1_1_2_0_1 + 0.880423280423283*G0_0_0_3_1_1_3_1_0 + 0.880423280423283*G0_0_0_3_1_1_3_1_1 - 0.880423280423283*G0_0_0_3_1_1_4_1_0 - 0.880423280423283*G0_0_0_3_1_1_5_1_1 - 0.880423280423283*G0_0_0_4_1_0_0_0_0 - 0.880423280423283*G0_0_0_4_1_0_0_0_1 + 0.880423280423283*G0_0_0_4_1_0_1_0_0 + 0.880423280423283*G0_0_0_4_1_0_2_0_1 - 0.880423280423283*G0_0_0_4_1_0_3_1_0 - 0.880423280423283*G0_0_0_4_1_0_3_1_1 + 0.880423280423283*G0_0_0_4_1_0_4_1_0 + 0.880423280423283*G0_0_0_4_1_0_5_1_1 - 0.880423280423283*G0_0_0_5_1_1_0_0_0 - 0.880423280423283*G0_0_0_5_1_1_0_0_1 + 0.880423280423283*G0_0_0_5_1_1_1_0_0 + 0.880423280423283*G0_0_0_5_1_1_2_0_1 - 0.880423280423283*G0_0_0_5_1_1_3_1_0 - 0.880423280423283*G0_0_0_5_1_1_3_1_1 + 0.880423280423283*G0_0_0_5_1_1_4_1_0 + 0.880423280423283*G0_0_0_5_1_1_5_1_1 + 0.541798941798942*G0_0_1_0_0_0_0_0_0 + 0.541798941798942*G0_0_1_0_0_0_0_0_1 - 0.541798941798942*G0_0_1_0_0_0_1_0_0 - 0.541798941798942*G0_0_1_0_0_0_2_0_1 + 0.541798941798942*G0_0_1_0_0_0_3_1_0 + 0.541798941798942*G0_0_1_0_0_0_3_1_1 - 0.541798941798942*G0_0_1_0_0_0_4_1_0 - 0.541798941798942*G0_0_1_0_0_0_5_1_1 + 0.541798941798942*G0_0_1_0_0_1_0_0_0 + 0.541798941798942*G0_0_1_0_0_1_0_0_1 - 0.541798941798942*G0_0_1_0_0_1_1_0_0 - 0.541798941798942*G0_0_1_0_0_1_2_0_1 + 0.541798941798942*G0_0_1_0_0_1_3_1_0 + 0.541798941798942*G0_0_1_0_0_1_3_1_1 - 0.541798941798942*G0_0_1_0_0_1_4_1_0 - 0.541798941798942*G0_0_1_0_0_1_5_1_1 - 0.541798941798942*G0_0_1_1_0_0_0_0_0 - 0.541798941798942*G0_0_1_1_0_0_0_0_1 + 0.541798941798942*G0_0_1_1_0_0_1_0_0 + 0.541798941798942*G0_0_1_1_0_0_2_0_1 - 0.541798941798942*G0_0_1_1_0_0_3_1_0 - 0.541798941798942*G0_0_1_1_0_0_3_1_1 + 0.541798941798942*G0_0_1_1_0_0_4_1_0 + 0.541798941798942*G0_0_1_1_0_0_5_1_1 - 0.541798941798942*G0_0_1_2_0_1_0_0_0 - 0.541798941798942*G0_0_1_2_0_1_0_0_1 + 0.541798941798942*G0_0_1_2_0_1_1_0_0 + 0.541798941798942*G0_0_1_2_0_1_2_0_1 - 0.541798941798942*G0_0_1_2_0_1_3_1_0 - 0.541798941798942*G0_0_1_2_0_1_3_1_1 + 0.541798941798942*G0_0_1_2_0_1_4_1_0 + 0.541798941798942*G0_0_1_2_0_1_5_1_1 + 0.541798941798942*G0_0_1_3_1_0_0_0_0 + 0.541798941798942*G0_0_1_3_1_0_0_0_1 - 0.541798941798942*G0_0_1_3_1_0_1_0_0 - 0.541798941798942*G0_0_1_3_1_0_2_0_1 + 0.541798941798942*G0_0_1_3_1_0_3_1_0 + 0.541798941798942*G0_0_1_3_1_0_3_1_1 - 0.541798941798942*G0_0_1_3_1_0_4_1_0 - 0.541798941798942*G0_0_1_3_1_0_5_1_1 + 0.541798941798942*G0_0_1_3_1_1_0_0_0 + 0.541798941798942*G0_0_1_3_1_1_0_0_1 - 0.541798941798942*G0_0_1_3_1_1_1_0_0 - 0.541798941798942*G0_0_1_3_1_1_2_0_1 + 0.541798941798942*G0_0_1_3_1_1_3_1_0 + 0.541798941798942*G0_0_1_3_1_1_3_1_1 - 0.541798941798942*G0_0_1_3_1_1_4_1_0 - 0.541798941798942*G0_0_1_3_1_1_5_1_1 - 0.541798941798942*G0_0_1_4_1_0_0_0_0 - 0.541798941798942*G0_0_1_4_1_0_0_0_1 + 0.541798941798942*G0_0_1_4_1_0_1_0_0 + 0.541798941798942*G0_0_1_4_1_0_2_0_1 - 0.541798941798942*G0_0_1_4_1_0_3_1_0 - 0.541798941798942*G0_0_1_4_1_0_3_1_1 + 0.541798941798942*G0_0_1_4_1_0_4_1_0 + 0.541798941798942*G0_0_1_4_1_0_5_1_1 - 0.541798941798942*G0_0_1_5_1_1_0_0_0 - 0.541798941798942*G0_0_1_5_1_1_0_0_1 + 0.541798941798942*G0_0_1_5_1_1_1_0_0 + 0.541798941798942*G0_0_1_5_1_1_2_0_1 - 0.541798941798942*G0_0_1_5_1_1_3_1_0 - 0.541798941798942*G0_0_1_5_1_1_3_1_1 + 0.541798941798942*G0_0_1_5_1_1_4_1_0 + 0.541798941798942*G0_0_1_5_1_1_5_1_1; + A[27] = 0.0; + A[728] = 0.0; + A[387] = 0.0; + A[831] = A[192]; + A[56] = 0.0; + A[755] = 0.0; + A[416] = 0.0; + A[862] = A[688]; + A[61] = -0.0566137566137575*G0_1_0_0_0_0_0_0_0 - 0.0566137566137575*G0_1_0_0_0_0_0_0_1 + 0.0566137566137575*G0_1_0_0_0_0_1_0_0 + 0.0566137566137575*G0_1_0_0_0_0_2_0_1 - 0.0566137566137575*G0_1_0_0_0_0_3_1_0 - 0.0566137566137575*G0_1_0_0_0_0_3_1_1 + 0.0566137566137575*G0_1_0_0_0_0_4_1_0 + 0.0566137566137575*G0_1_0_0_0_0_5_1_1 - 0.0566137566137575*G0_1_0_0_0_1_0_0_0 - 0.0566137566137575*G0_1_0_0_0_1_0_0_1 + 0.0566137566137575*G0_1_0_0_0_1_1_0_0 + 0.0566137566137575*G0_1_0_0_0_1_2_0_1 - 0.0566137566137575*G0_1_0_0_0_1_3_1_0 - 0.0566137566137575*G0_1_0_0_0_1_3_1_1 + 0.0566137566137575*G0_1_0_0_0_1_4_1_0 + 0.0566137566137575*G0_1_0_0_0_1_5_1_1 + 0.0566137566137575*G0_1_0_1_0_0_0_0_0 + 0.0566137566137575*G0_1_0_1_0_0_0_0_1 - 0.0566137566137575*G0_1_0_1_0_0_1_0_0 - 0.0566137566137575*G0_1_0_1_0_0_2_0_1 + 0.0566137566137575*G0_1_0_1_0_0_3_1_0 + 0.0566137566137575*G0_1_0_1_0_0_3_1_1 - 0.0566137566137575*G0_1_0_1_0_0_4_1_0 - 0.0566137566137575*G0_1_0_1_0_0_5_1_1 + 0.0566137566137575*G0_1_0_2_0_1_0_0_0 + 0.0566137566137575*G0_1_0_2_0_1_0_0_1 - 0.0566137566137575*G0_1_0_2_0_1_1_0_0 - 0.0566137566137575*G0_1_0_2_0_1_2_0_1 + 0.0566137566137575*G0_1_0_2_0_1_3_1_0 + 0.0566137566137575*G0_1_0_2_0_1_3_1_1 - 0.0566137566137575*G0_1_0_2_0_1_4_1_0 - 0.0566137566137575*G0_1_0_2_0_1_5_1_1 - 0.0566137566137575*G0_1_0_3_1_0_0_0_0 - 0.0566137566137575*G0_1_0_3_1_0_0_0_1 + 0.0566137566137575*G0_1_0_3_1_0_1_0_0 + 0.0566137566137575*G0_1_0_3_1_0_2_0_1 - 0.0566137566137575*G0_1_0_3_1_0_3_1_0 - 0.0566137566137575*G0_1_0_3_1_0_3_1_1 + 0.0566137566137575*G0_1_0_3_1_0_4_1_0 + 0.0566137566137575*G0_1_0_3_1_0_5_1_1 - 0.0566137566137575*G0_1_0_3_1_1_0_0_0 - 0.0566137566137575*G0_1_0_3_1_1_0_0_1 + 0.0566137566137575*G0_1_0_3_1_1_1_0_0 + 0.0566137566137575*G0_1_0_3_1_1_2_0_1 - 0.0566137566137575*G0_1_0_3_1_1_3_1_0 - 0.0566137566137575*G0_1_0_3_1_1_3_1_1 + 0.0566137566137575*G0_1_0_3_1_1_4_1_0 + 0.0566137566137575*G0_1_0_3_1_1_5_1_1 + 0.0566137566137575*G0_1_0_4_1_0_0_0_0 + 0.0566137566137575*G0_1_0_4_1_0_0_0_1 - 0.0566137566137575*G0_1_0_4_1_0_1_0_0 - 0.0566137566137575*G0_1_0_4_1_0_2_0_1 + 0.0566137566137575*G0_1_0_4_1_0_3_1_0 + 0.0566137566137575*G0_1_0_4_1_0_3_1_1 - 0.0566137566137575*G0_1_0_4_1_0_4_1_0 - 0.0566137566137575*G0_1_0_4_1_0_5_1_1 + 0.0566137566137575*G0_1_0_5_1_1_0_0_0 + 0.0566137566137575*G0_1_0_5_1_1_0_0_1 - 0.0566137566137575*G0_1_0_5_1_1_1_0_0 - 0.0566137566137575*G0_1_0_5_1_1_2_0_1 + 0.0566137566137575*G0_1_0_5_1_1_3_1_0 + 0.0566137566137575*G0_1_0_5_1_1_3_1_1 - 0.0566137566137575*G0_1_0_5_1_1_4_1_0 - 0.0566137566137575*G0_1_0_5_1_1_5_1_1; + A[466] = -A[61] + 0.0566137566137574*G0_0_0_0_0_0_0_0_0 + 0.0566137566137574*G0_0_0_0_0_0_0_0_1 - 0.0566137566137574*G0_0_0_0_0_0_1_0_0 - 0.0566137566137574*G0_0_0_0_0_0_2_0_1 + 0.0566137566137574*G0_0_0_0_0_0_3_1_0 + 0.0566137566137574*G0_0_0_0_0_0_3_1_1 - 0.0566137566137574*G0_0_0_0_0_0_4_1_0 - 0.0566137566137574*G0_0_0_0_0_0_5_1_1 + 0.0566137566137574*G0_0_0_0_0_1_0_0_0 + 0.0566137566137574*G0_0_0_0_0_1_0_0_1 - 0.0566137566137574*G0_0_0_0_0_1_1_0_0 - 0.0566137566137574*G0_0_0_0_0_1_2_0_1 + 0.0566137566137574*G0_0_0_0_0_1_3_1_0 + 0.0566137566137574*G0_0_0_0_0_1_3_1_1 - 0.0566137566137574*G0_0_0_0_0_1_4_1_0 - 0.0566137566137574*G0_0_0_0_0_1_5_1_1 - 0.0566137566137574*G0_0_0_1_0_0_0_0_0 - 0.0566137566137574*G0_0_0_1_0_0_0_0_1 + 0.0566137566137574*G0_0_0_1_0_0_1_0_0 + 0.0566137566137574*G0_0_0_1_0_0_2_0_1 - 0.0566137566137574*G0_0_0_1_0_0_3_1_0 - 0.0566137566137574*G0_0_0_1_0_0_3_1_1 + 0.0566137566137574*G0_0_0_1_0_0_4_1_0 + 0.0566137566137574*G0_0_0_1_0_0_5_1_1 - 0.0566137566137574*G0_0_0_2_0_1_0_0_0 - 0.0566137566137574*G0_0_0_2_0_1_0_0_1 + 0.0566137566137574*G0_0_0_2_0_1_1_0_0 + 0.0566137566137574*G0_0_0_2_0_1_2_0_1 - 0.0566137566137574*G0_0_0_2_0_1_3_1_0 - 0.0566137566137574*G0_0_0_2_0_1_3_1_1 + 0.0566137566137574*G0_0_0_2_0_1_4_1_0 + 0.0566137566137574*G0_0_0_2_0_1_5_1_1 + 0.0566137566137574*G0_0_0_3_1_0_0_0_0 + 0.0566137566137574*G0_0_0_3_1_0_0_0_1 - 0.0566137566137574*G0_0_0_3_1_0_1_0_0 - 0.0566137566137574*G0_0_0_3_1_0_2_0_1 + 0.0566137566137574*G0_0_0_3_1_0_3_1_0 + 0.0566137566137574*G0_0_0_3_1_0_3_1_1 - 0.0566137566137574*G0_0_0_3_1_0_4_1_0 - 0.0566137566137574*G0_0_0_3_1_0_5_1_1 + 0.0566137566137574*G0_0_0_3_1_1_0_0_0 + 0.0566137566137574*G0_0_0_3_1_1_0_0_1 - 0.0566137566137574*G0_0_0_3_1_1_1_0_0 - 0.0566137566137574*G0_0_0_3_1_1_2_0_1 + 0.0566137566137574*G0_0_0_3_1_1_3_1_0 + 0.0566137566137574*G0_0_0_3_1_1_3_1_1 - 0.0566137566137574*G0_0_0_3_1_1_4_1_0 - 0.0566137566137574*G0_0_0_3_1_1_5_1_1 - 0.0566137566137574*G0_0_0_4_1_0_0_0_0 - 0.0566137566137574*G0_0_0_4_1_0_0_0_1 + 0.0566137566137574*G0_0_0_4_1_0_1_0_0 + 0.0566137566137574*G0_0_0_4_1_0_2_0_1 - 0.0566137566137574*G0_0_0_4_1_0_3_1_0 - 0.0566137566137574*G0_0_0_4_1_0_3_1_1 + 0.0566137566137574*G0_0_0_4_1_0_4_1_0 + 0.0566137566137574*G0_0_0_4_1_0_5_1_1 - 0.0566137566137574*G0_0_0_5_1_1_0_0_0 - 0.0566137566137574*G0_0_0_5_1_1_0_0_1 + 0.0566137566137574*G0_0_0_5_1_1_1_0_0 + 0.0566137566137574*G0_0_0_5_1_1_2_0_1 - 0.0566137566137574*G0_0_0_5_1_1_3_1_0 - 0.0566137566137574*G0_0_0_5_1_1_3_1_1 + 0.0566137566137574*G0_0_0_5_1_1_4_1_0 + 0.0566137566137574*G0_0_0_5_1_1_5_1_1; + A[782] = 0.0; + A[893] = A[428]; + A[118] = 0.0; + A[821] = 0.0; + A[852] = 0.0; + A[212] = A[677]; + A[626] = A[335]; + A[490] = 0.0; + A[209] = 0.0; + A[657] = A[192]; + A[577] = 0.0; + A[521] = 0.0; + A[234] = 0.0; + A[676] = A[181]; + A[600] = 0.0; + A[556] = A[91]; + A[711] = -A[621] + 0.541798941798938*G0_1_0_0_0_0_0_0_0 + 0.541798941798938*G0_1_0_0_0_0_0_0_1 - 0.541798941798938*G0_1_0_0_0_0_1_0_0 - 0.541798941798938*G0_1_0_0_0_0_2_0_1 + 0.541798941798938*G0_1_0_0_0_0_3_1_0 + 0.541798941798938*G0_1_0_0_0_0_3_1_1 - 0.541798941798938*G0_1_0_0_0_0_4_1_0 - 0.541798941798938*G0_1_0_0_0_0_5_1_1 + 0.541798941798938*G0_1_0_0_0_1_0_0_0 + 0.541798941798938*G0_1_0_0_0_1_0_0_1 - 0.541798941798938*G0_1_0_0_0_1_1_0_0 - 0.541798941798938*G0_1_0_0_0_1_2_0_1 + 0.541798941798938*G0_1_0_0_0_1_3_1_0 + 0.541798941798938*G0_1_0_0_0_1_3_1_1 - 0.541798941798938*G0_1_0_0_0_1_4_1_0 - 0.541798941798938*G0_1_0_0_0_1_5_1_1 - 0.541798941798938*G0_1_0_1_0_0_0_0_0 - 0.541798941798938*G0_1_0_1_0_0_0_0_1 + 0.541798941798938*G0_1_0_1_0_0_1_0_0 + 0.541798941798938*G0_1_0_1_0_0_2_0_1 - 0.541798941798938*G0_1_0_1_0_0_3_1_0 - 0.541798941798938*G0_1_0_1_0_0_3_1_1 + 0.541798941798938*G0_1_0_1_0_0_4_1_0 + 0.541798941798938*G0_1_0_1_0_0_5_1_1 - 0.541798941798938*G0_1_0_2_0_1_0_0_0 - 0.541798941798938*G0_1_0_2_0_1_0_0_1 + 0.541798941798938*G0_1_0_2_0_1_1_0_0 + 0.541798941798938*G0_1_0_2_0_1_2_0_1 - 0.541798941798938*G0_1_0_2_0_1_3_1_0 - 0.541798941798938*G0_1_0_2_0_1_3_1_1 + 0.541798941798938*G0_1_0_2_0_1_4_1_0 + 0.541798941798938*G0_1_0_2_0_1_5_1_1 + 0.541798941798938*G0_1_0_3_1_0_0_0_0 + 0.541798941798938*G0_1_0_3_1_0_0_0_1 - 0.541798941798938*G0_1_0_3_1_0_1_0_0 - 0.541798941798938*G0_1_0_3_1_0_2_0_1 + 0.541798941798938*G0_1_0_3_1_0_3_1_0 + 0.541798941798938*G0_1_0_3_1_0_3_1_1 - 0.541798941798938*G0_1_0_3_1_0_4_1_0 - 0.541798941798938*G0_1_0_3_1_0_5_1_1 + 0.541798941798938*G0_1_0_3_1_1_0_0_0 + 0.541798941798938*G0_1_0_3_1_1_0_0_1 - 0.541798941798938*G0_1_0_3_1_1_1_0_0 - 0.541798941798938*G0_1_0_3_1_1_2_0_1 + 0.541798941798938*G0_1_0_3_1_1_3_1_0 + 0.541798941798938*G0_1_0_3_1_1_3_1_1 - 0.541798941798938*G0_1_0_3_1_1_4_1_0 - 0.541798941798938*G0_1_0_3_1_1_5_1_1 - 0.541798941798938*G0_1_0_4_1_0_0_0_0 - 0.541798941798938*G0_1_0_4_1_0_0_0_1 + 0.541798941798938*G0_1_0_4_1_0_1_0_0 + 0.541798941798938*G0_1_0_4_1_0_2_0_1 - 0.541798941798938*G0_1_0_4_1_0_3_1_0 - 0.541798941798938*G0_1_0_4_1_0_3_1_1 + 0.541798941798938*G0_1_0_4_1_0_4_1_0 + 0.541798941798938*G0_1_0_4_1_0_5_1_1 - 0.541798941798938*G0_1_0_5_1_1_0_0_0 - 0.541798941798938*G0_1_0_5_1_1_0_0_1 + 0.541798941798938*G0_1_0_5_1_1_1_0_0 + 0.541798941798938*G0_1_0_5_1_1_2_0_1 - 0.541798941798938*G0_1_0_5_1_1_3_1_0 - 0.541798941798938*G0_1_0_5_1_1_3_1_1 + 0.541798941798938*G0_1_0_5_1_1_4_1_0 + 0.541798941798938*G0_1_0_5_1_1_5_1_1 + 0.880423280423282*G0_1_1_0_0_0_0_0_0 + 0.880423280423282*G0_1_1_0_0_0_0_0_1 - 0.880423280423282*G0_1_1_0_0_0_1_0_0 - 0.880423280423282*G0_1_1_0_0_0_2_0_1 + 0.880423280423282*G0_1_1_0_0_0_3_1_0 + 0.880423280423282*G0_1_1_0_0_0_3_1_1 - 0.880423280423282*G0_1_1_0_0_0_4_1_0 - 0.880423280423282*G0_1_1_0_0_0_5_1_1 + 0.880423280423282*G0_1_1_0_0_1_0_0_0 + 0.880423280423282*G0_1_1_0_0_1_0_0_1 - 0.880423280423282*G0_1_1_0_0_1_1_0_0 - 0.880423280423282*G0_1_1_0_0_1_2_0_1 + 0.880423280423282*G0_1_1_0_0_1_3_1_0 + 0.880423280423282*G0_1_1_0_0_1_3_1_1 - 0.880423280423282*G0_1_1_0_0_1_4_1_0 - 0.880423280423282*G0_1_1_0_0_1_5_1_1 - 0.880423280423282*G0_1_1_1_0_0_0_0_0 - 0.880423280423282*G0_1_1_1_0_0_0_0_1 + 0.880423280423282*G0_1_1_1_0_0_1_0_0 + 0.880423280423282*G0_1_1_1_0_0_2_0_1 - 0.880423280423282*G0_1_1_1_0_0_3_1_0 - 0.880423280423282*G0_1_1_1_0_0_3_1_1 + 0.880423280423282*G0_1_1_1_0_0_4_1_0 + 0.880423280423282*G0_1_1_1_0_0_5_1_1 - 0.880423280423282*G0_1_1_2_0_1_0_0_0 - 0.880423280423282*G0_1_1_2_0_1_0_0_1 + 0.880423280423282*G0_1_1_2_0_1_1_0_0 + 0.880423280423282*G0_1_1_2_0_1_2_0_1 - 0.880423280423282*G0_1_1_2_0_1_3_1_0 - 0.880423280423282*G0_1_1_2_0_1_3_1_1 + 0.880423280423282*G0_1_1_2_0_1_4_1_0 + 0.880423280423282*G0_1_1_2_0_1_5_1_1 + 0.880423280423282*G0_1_1_3_1_0_0_0_0 + 0.880423280423282*G0_1_1_3_1_0_0_0_1 - 0.880423280423282*G0_1_1_3_1_0_1_0_0 - 0.880423280423282*G0_1_1_3_1_0_2_0_1 + 0.880423280423282*G0_1_1_3_1_0_3_1_0 + 0.880423280423282*G0_1_1_3_1_0_3_1_1 - 0.880423280423282*G0_1_1_3_1_0_4_1_0 - 0.880423280423282*G0_1_1_3_1_0_5_1_1 + 0.880423280423282*G0_1_1_3_1_1_0_0_0 + 0.880423280423282*G0_1_1_3_1_1_0_0_1 - 0.880423280423282*G0_1_1_3_1_1_1_0_0 - 0.880423280423282*G0_1_1_3_1_1_2_0_1 + 0.880423280423282*G0_1_1_3_1_1_3_1_0 + 0.880423280423282*G0_1_1_3_1_1_3_1_1 - 0.880423280423282*G0_1_1_3_1_1_4_1_0 - 0.880423280423282*G0_1_1_3_1_1_5_1_1 - 0.880423280423282*G0_1_1_4_1_0_0_0_0 - 0.880423280423282*G0_1_1_4_1_0_0_0_1 + 0.880423280423282*G0_1_1_4_1_0_1_0_0 + 0.880423280423282*G0_1_1_4_1_0_2_0_1 - 0.880423280423282*G0_1_1_4_1_0_3_1_0 - 0.880423280423282*G0_1_1_4_1_0_3_1_1 + 0.880423280423282*G0_1_1_4_1_0_4_1_0 + 0.880423280423282*G0_1_1_4_1_0_5_1_1 - 0.880423280423282*G0_1_1_5_1_1_0_0_0 - 0.880423280423282*G0_1_1_5_1_1_0_0_1 + 0.880423280423282*G0_1_1_5_1_1_1_0_0 + 0.880423280423282*G0_1_1_5_1_1_2_0_1 - 0.880423280423282*G0_1_1_5_1_1_3_1_0 - 0.880423280423282*G0_1_1_5_1_1_3_1_1 + 0.880423280423282*G0_1_1_5_1_1_4_1_0 + 0.880423280423282*G0_1_1_5_1_1_5_1_1; + A[635] = 0.0; + A[246] = A[711]; + A[670] = 0.0; + A[277] = A[219]; + A[448] = 0.0; + A[304] = A[769]; + A[475] = A[5] + 0.42539682539683*G0_0_0_0_0_0_0_0_0 + 0.42539682539683*G0_0_0_0_0_0_0_0_1 - 0.42539682539683*G0_0_0_0_0_0_1_0_0 - 0.42539682539683*G0_0_0_0_0_0_2_0_1 + 0.42539682539683*G0_0_0_0_0_0_3_1_0 + 0.42539682539683*G0_0_0_0_0_0_3_1_1 - 0.42539682539683*G0_0_0_0_0_0_4_1_0 - 0.42539682539683*G0_0_0_0_0_0_5_1_1 + 0.42539682539683*G0_0_0_0_0_1_0_0_0 + 0.42539682539683*G0_0_0_0_0_1_0_0_1 - 0.42539682539683*G0_0_0_0_0_1_1_0_0 - 0.42539682539683*G0_0_0_0_0_1_2_0_1 + 0.42539682539683*G0_0_0_0_0_1_3_1_0 + 0.42539682539683*G0_0_0_0_0_1_3_1_1 - 0.42539682539683*G0_0_0_0_0_1_4_1_0 - 0.42539682539683*G0_0_0_0_0_1_5_1_1 - 0.42539682539683*G0_0_0_1_0_0_0_0_0 - 0.42539682539683*G0_0_0_1_0_0_0_0_1 + 0.42539682539683*G0_0_0_1_0_0_1_0_0 + 0.42539682539683*G0_0_0_1_0_0_2_0_1 - 0.42539682539683*G0_0_0_1_0_0_3_1_0 - 0.42539682539683*G0_0_0_1_0_0_3_1_1 + 0.42539682539683*G0_0_0_1_0_0_4_1_0 + 0.42539682539683*G0_0_0_1_0_0_5_1_1 - 0.42539682539683*G0_0_0_2_0_1_0_0_0 - 0.42539682539683*G0_0_0_2_0_1_0_0_1 + 0.42539682539683*G0_0_0_2_0_1_1_0_0 + 0.42539682539683*G0_0_0_2_0_1_2_0_1 - 0.42539682539683*G0_0_0_2_0_1_3_1_0 - 0.42539682539683*G0_0_0_2_0_1_3_1_1 + 0.42539682539683*G0_0_0_2_0_1_4_1_0 + 0.42539682539683*G0_0_0_2_0_1_5_1_1 + 0.42539682539683*G0_0_0_3_1_0_0_0_0 + 0.42539682539683*G0_0_0_3_1_0_0_0_1 - 0.42539682539683*G0_0_0_3_1_0_1_0_0 - 0.42539682539683*G0_0_0_3_1_0_2_0_1 + 0.42539682539683*G0_0_0_3_1_0_3_1_0 + 0.42539682539683*G0_0_0_3_1_0_3_1_1 - 0.42539682539683*G0_0_0_3_1_0_4_1_0 - 0.42539682539683*G0_0_0_3_1_0_5_1_1 + 0.42539682539683*G0_0_0_3_1_1_0_0_0 + 0.42539682539683*G0_0_0_3_1_1_0_0_1 - 0.42539682539683*G0_0_0_3_1_1_1_0_0 - 0.42539682539683*G0_0_0_3_1_1_2_0_1 + 0.42539682539683*G0_0_0_3_1_1_3_1_0 + 0.42539682539683*G0_0_0_3_1_1_3_1_1 - 0.42539682539683*G0_0_0_3_1_1_4_1_0 - 0.42539682539683*G0_0_0_3_1_1_5_1_1 - 0.42539682539683*G0_0_0_4_1_0_0_0_0 - 0.42539682539683*G0_0_0_4_1_0_0_0_1 + 0.42539682539683*G0_0_0_4_1_0_1_0_0 + 0.42539682539683*G0_0_0_4_1_0_2_0_1 - 0.42539682539683*G0_0_0_4_1_0_3_1_0 - 0.42539682539683*G0_0_0_4_1_0_3_1_1 + 0.42539682539683*G0_0_0_4_1_0_4_1_0 + 0.42539682539683*G0_0_0_4_1_0_5_1_1 - 0.42539682539683*G0_0_0_5_1_1_0_0_0 - 0.42539682539683*G0_0_0_5_1_1_0_0_1 + 0.42539682539683*G0_0_0_5_1_1_1_0_0 + 0.42539682539683*G0_0_0_5_1_1_2_0_1 - 0.42539682539683*G0_0_0_5_1_1_3_1_0 - 0.42539682539683*G0_0_0_5_1_1_3_1_1 + 0.42539682539683*G0_0_0_5_1_1_4_1_0 + 0.42539682539683*G0_0_0_5_1_1_5_1_1 + 0.425396825396829*G0_1_0_0_0_0_0_0_0 + 0.425396825396829*G0_1_0_0_0_0_0_0_1 - 0.425396825396829*G0_1_0_0_0_0_1_0_0 - 0.425396825396829*G0_1_0_0_0_0_2_0_1 + 0.425396825396829*G0_1_0_0_0_0_3_1_0 + 0.425396825396829*G0_1_0_0_0_0_3_1_1 - 0.425396825396829*G0_1_0_0_0_0_4_1_0 - 0.425396825396829*G0_1_0_0_0_0_5_1_1 + 0.425396825396829*G0_1_0_0_0_1_0_0_0 + 0.425396825396829*G0_1_0_0_0_1_0_0_1 - 0.425396825396829*G0_1_0_0_0_1_1_0_0 - 0.425396825396829*G0_1_0_0_0_1_2_0_1 + 0.425396825396829*G0_1_0_0_0_1_3_1_0 + 0.425396825396829*G0_1_0_0_0_1_3_1_1 - 0.425396825396829*G0_1_0_0_0_1_4_1_0 - 0.425396825396829*G0_1_0_0_0_1_5_1_1 - 0.425396825396829*G0_1_0_1_0_0_0_0_0 - 0.425396825396829*G0_1_0_1_0_0_0_0_1 + 0.425396825396829*G0_1_0_1_0_0_1_0_0 + 0.425396825396829*G0_1_0_1_0_0_2_0_1 - 0.425396825396829*G0_1_0_1_0_0_3_1_0 - 0.425396825396829*G0_1_0_1_0_0_3_1_1 + 0.425396825396829*G0_1_0_1_0_0_4_1_0 + 0.425396825396829*G0_1_0_1_0_0_5_1_1 - 0.425396825396829*G0_1_0_2_0_1_0_0_0 - 0.425396825396829*G0_1_0_2_0_1_0_0_1 + 0.425396825396829*G0_1_0_2_0_1_1_0_0 + 0.425396825396829*G0_1_0_2_0_1_2_0_1 - 0.425396825396829*G0_1_0_2_0_1_3_1_0 - 0.425396825396829*G0_1_0_2_0_1_3_1_1 + 0.425396825396829*G0_1_0_2_0_1_4_1_0 + 0.425396825396829*G0_1_0_2_0_1_5_1_1 + 0.425396825396829*G0_1_0_3_1_0_0_0_0 + 0.425396825396829*G0_1_0_3_1_0_0_0_1 - 0.425396825396829*G0_1_0_3_1_0_1_0_0 - 0.425396825396829*G0_1_0_3_1_0_2_0_1 + 0.425396825396829*G0_1_0_3_1_0_3_1_0 + 0.425396825396829*G0_1_0_3_1_0_3_1_1 - 0.425396825396829*G0_1_0_3_1_0_4_1_0 - 0.425396825396829*G0_1_0_3_1_0_5_1_1 + 0.425396825396829*G0_1_0_3_1_1_0_0_0 + 0.425396825396829*G0_1_0_3_1_1_0_0_1 - 0.425396825396829*G0_1_0_3_1_1_1_0_0 - 0.425396825396829*G0_1_0_3_1_1_2_0_1 + 0.425396825396829*G0_1_0_3_1_1_3_1_0 + 0.425396825396829*G0_1_0_3_1_1_3_1_1 - 0.425396825396829*G0_1_0_3_1_1_4_1_0 - 0.425396825396829*G0_1_0_3_1_1_5_1_1 - 0.425396825396829*G0_1_0_4_1_0_0_0_0 - 0.425396825396829*G0_1_0_4_1_0_0_0_1 + 0.425396825396829*G0_1_0_4_1_0_1_0_0 + 0.425396825396829*G0_1_0_4_1_0_2_0_1 - 0.425396825396829*G0_1_0_4_1_0_3_1_0 - 0.425396825396829*G0_1_0_4_1_0_3_1_1 + 0.425396825396829*G0_1_0_4_1_0_4_1_0 + 0.425396825396829*G0_1_0_4_1_0_5_1_1 - 0.425396825396829*G0_1_0_5_1_1_0_0_0 - 0.425396825396829*G0_1_0_5_1_1_0_0_1 + 0.425396825396829*G0_1_0_5_1_1_1_0_0 + 0.425396825396829*G0_1_0_5_1_1_2_0_1 - 0.425396825396829*G0_1_0_5_1_1_3_1_0 - 0.425396825396829*G0_1_0_5_1_1_3_1_1 + 0.425396825396829*G0_1_0_5_1_1_4_1_0 + 0.425396825396829*G0_1_0_5_1_1_5_1_1; + A[339] = A[804]; + A[18] = 0.0; + A[735] = A[270]; + A[426] = A[658]; + A[378] = 0.0; + A[49] = 0.0; + A[764] = 0.0; + A[457] = 0.0; + A[409] = 0.0; + A[84] = 0.0; + A[793] = 0.0; + A[8] = -A[5] - 0.203174603174604*G0_0_1_0_0_0_0_0_0 - 0.203174603174604*G0_0_1_0_0_0_0_0_1 + 0.203174603174604*G0_0_1_0_0_0_1_0_0 + 0.203174603174604*G0_0_1_0_0_0_2_0_1 - 0.203174603174604*G0_0_1_0_0_0_3_1_0 - 0.203174603174604*G0_0_1_0_0_0_3_1_1 + 0.203174603174604*G0_0_1_0_0_0_4_1_0 + 0.203174603174604*G0_0_1_0_0_0_5_1_1 - 0.203174603174604*G0_0_1_0_0_1_0_0_0 - 0.203174603174604*G0_0_1_0_0_1_0_0_1 + 0.203174603174604*G0_0_1_0_0_1_1_0_0 + 0.203174603174604*G0_0_1_0_0_1_2_0_1 - 0.203174603174604*G0_0_1_0_0_1_3_1_0 - 0.203174603174604*G0_0_1_0_0_1_3_1_1 + 0.203174603174604*G0_0_1_0_0_1_4_1_0 + 0.203174603174604*G0_0_1_0_0_1_5_1_1 + 0.203174603174604*G0_0_1_1_0_0_0_0_0 + 0.203174603174604*G0_0_1_1_0_0_0_0_1 - 0.203174603174604*G0_0_1_1_0_0_1_0_0 - 0.203174603174604*G0_0_1_1_0_0_2_0_1 + 0.203174603174604*G0_0_1_1_0_0_3_1_0 + 0.203174603174604*G0_0_1_1_0_0_3_1_1 - 0.203174603174604*G0_0_1_1_0_0_4_1_0 - 0.203174603174604*G0_0_1_1_0_0_5_1_1 + 0.203174603174604*G0_0_1_2_0_1_0_0_0 + 0.203174603174604*G0_0_1_2_0_1_0_0_1 - 0.203174603174604*G0_0_1_2_0_1_1_0_0 - 0.203174603174604*G0_0_1_2_0_1_2_0_1 + 0.203174603174604*G0_0_1_2_0_1_3_1_0 + 0.203174603174604*G0_0_1_2_0_1_3_1_1 - 0.203174603174604*G0_0_1_2_0_1_4_1_0 - 0.203174603174604*G0_0_1_2_0_1_5_1_1 - 0.203174603174604*G0_0_1_3_1_0_0_0_0 - 0.203174603174604*G0_0_1_3_1_0_0_0_1 + 0.203174603174604*G0_0_1_3_1_0_1_0_0 + 0.203174603174604*G0_0_1_3_1_0_2_0_1 - 0.203174603174604*G0_0_1_3_1_0_3_1_0 - 0.203174603174604*G0_0_1_3_1_0_3_1_1 + 0.203174603174604*G0_0_1_3_1_0_4_1_0 + 0.203174603174604*G0_0_1_3_1_0_5_1_1 - 0.203174603174604*G0_0_1_3_1_1_0_0_0 - 0.203174603174604*G0_0_1_3_1_1_0_0_1 + 0.203174603174604*G0_0_1_3_1_1_1_0_0 + 0.203174603174604*G0_0_1_3_1_1_2_0_1 - 0.203174603174604*G0_0_1_3_1_1_3_1_0 - 0.203174603174604*G0_0_1_3_1_1_3_1_1 + 0.203174603174604*G0_0_1_3_1_1_4_1_0 + 0.203174603174604*G0_0_1_3_1_1_5_1_1 + 0.203174603174604*G0_0_1_4_1_0_0_0_0 + 0.203174603174604*G0_0_1_4_1_0_0_0_1 - 0.203174603174604*G0_0_1_4_1_0_1_0_0 - 0.203174603174604*G0_0_1_4_1_0_2_0_1 + 0.203174603174604*G0_0_1_4_1_0_3_1_0 + 0.203174603174604*G0_0_1_4_1_0_3_1_1 - 0.203174603174604*G0_0_1_4_1_0_4_1_0 - 0.203174603174604*G0_0_1_4_1_0_5_1_1 + 0.203174603174604*G0_0_1_5_1_1_0_0_0 + 0.203174603174604*G0_0_1_5_1_1_0_0_1 - 0.203174603174604*G0_0_1_5_1_1_1_0_0 - 0.203174603174604*G0_0_1_5_1_1_2_0_1 + 0.203174603174604*G0_0_1_5_1_1_3_1_0 + 0.203174603174604*G0_0_1_5_1_1_3_1_1 - 0.203174603174604*G0_0_1_5_1_1_4_1_0 - 0.203174603174604*G0_0_1_5_1_1_5_1_1 - 0.203174603174604*G0_1_1_0_0_0_0_0_0 - 0.203174603174604*G0_1_1_0_0_0_0_0_1 + 0.203174603174604*G0_1_1_0_0_0_1_0_0 + 0.203174603174604*G0_1_1_0_0_0_2_0_1 - 0.203174603174604*G0_1_1_0_0_0_3_1_0 - 0.203174603174604*G0_1_1_0_0_0_3_1_1 + 0.203174603174604*G0_1_1_0_0_0_4_1_0 + 0.203174603174604*G0_1_1_0_0_0_5_1_1 - 0.203174603174604*G0_1_1_0_0_1_0_0_0 - 0.203174603174604*G0_1_1_0_0_1_0_0_1 + 0.203174603174604*G0_1_1_0_0_1_1_0_0 + 0.203174603174604*G0_1_1_0_0_1_2_0_1 - 0.203174603174604*G0_1_1_0_0_1_3_1_0 - 0.203174603174604*G0_1_1_0_0_1_3_1_1 + 0.203174603174604*G0_1_1_0_0_1_4_1_0 + 0.203174603174604*G0_1_1_0_0_1_5_1_1 + 0.203174603174604*G0_1_1_1_0_0_0_0_0 + 0.203174603174604*G0_1_1_1_0_0_0_0_1 - 0.203174603174604*G0_1_1_1_0_0_1_0_0 - 0.203174603174604*G0_1_1_1_0_0_2_0_1 + 0.203174603174604*G0_1_1_1_0_0_3_1_0 + 0.203174603174604*G0_1_1_1_0_0_3_1_1 - 0.203174603174604*G0_1_1_1_0_0_4_1_0 - 0.203174603174604*G0_1_1_1_0_0_5_1_1 + 0.203174603174604*G0_1_1_2_0_1_0_0_0 + 0.203174603174604*G0_1_1_2_0_1_0_0_1 - 0.203174603174604*G0_1_1_2_0_1_1_0_0 - 0.203174603174604*G0_1_1_2_0_1_2_0_1 + 0.203174603174604*G0_1_1_2_0_1_3_1_0 + 0.203174603174604*G0_1_1_2_0_1_3_1_1 - 0.203174603174604*G0_1_1_2_0_1_4_1_0 - 0.203174603174604*G0_1_1_2_0_1_5_1_1 - 0.203174603174604*G0_1_1_3_1_0_0_0_0 - 0.203174603174604*G0_1_1_3_1_0_0_0_1 + 0.203174603174604*G0_1_1_3_1_0_1_0_0 + 0.203174603174604*G0_1_1_3_1_0_2_0_1 - 0.203174603174604*G0_1_1_3_1_0_3_1_0 - 0.203174603174604*G0_1_1_3_1_0_3_1_1 + 0.203174603174604*G0_1_1_3_1_0_4_1_0 + 0.203174603174604*G0_1_1_3_1_0_5_1_1 - 0.203174603174604*G0_1_1_3_1_1_0_0_0 - 0.203174603174604*G0_1_1_3_1_1_0_0_1 + 0.203174603174604*G0_1_1_3_1_1_1_0_0 + 0.203174603174604*G0_1_1_3_1_1_2_0_1 - 0.203174603174604*G0_1_1_3_1_1_3_1_0 - 0.203174603174604*G0_1_1_3_1_1_3_1_1 + 0.203174603174604*G0_1_1_3_1_1_4_1_0 + 0.203174603174604*G0_1_1_3_1_1_5_1_1 + 0.203174603174604*G0_1_1_4_1_0_0_0_0 + 0.203174603174604*G0_1_1_4_1_0_0_0_1 - 0.203174603174604*G0_1_1_4_1_0_1_0_0 - 0.203174603174604*G0_1_1_4_1_0_2_0_1 + 0.203174603174604*G0_1_1_4_1_0_3_1_0 + 0.203174603174604*G0_1_1_4_1_0_3_1_1 - 0.203174603174604*G0_1_1_4_1_0_4_1_0 - 0.203174603174604*G0_1_1_4_1_0_5_1_1 + 0.203174603174604*G0_1_1_5_1_1_0_0_0 + 0.203174603174604*G0_1_1_5_1_1_0_0_1 - 0.203174603174604*G0_1_1_5_1_1_1_0_0 - 0.203174603174604*G0_1_1_5_1_1_2_0_1 + 0.203174603174604*G0_1_1_5_1_1_3_1_0 + 0.203174603174604*G0_1_1_5_1_1_3_1_1 - 0.203174603174604*G0_1_1_5_1_1_4_1_0 - 0.203174603174604*G0_1_1_5_1_1_5_1_1; + A[886] = A[421]; + A[95] = A[560]; + A[810] = 0.0; + A[126] = A[274] - 0.0846560846560904*G0_0_0_0_0_0_0_0_0 - 0.0846560846560904*G0_0_0_0_0_0_0_0_1 + 0.0846560846560904*G0_0_0_0_0_0_1_0_0 + 0.0846560846560904*G0_0_0_0_0_0_2_0_1 - 0.0846560846560904*G0_0_0_0_0_0_3_1_0 - 0.0846560846560904*G0_0_0_0_0_0_3_1_1 + 0.0846560846560904*G0_0_0_0_0_0_4_1_0 + 0.0846560846560904*G0_0_0_0_0_0_5_1_1 - 0.0846560846560904*G0_0_0_0_0_1_0_0_0 - 0.0846560846560904*G0_0_0_0_0_1_0_0_1 + 0.0846560846560904*G0_0_0_0_0_1_1_0_0 + 0.0846560846560904*G0_0_0_0_0_1_2_0_1 - 0.0846560846560904*G0_0_0_0_0_1_3_1_0 - 0.0846560846560904*G0_0_0_0_0_1_3_1_1 + 0.0846560846560904*G0_0_0_0_0_1_4_1_0 + 0.0846560846560904*G0_0_0_0_0_1_5_1_1 + 0.0846560846560904*G0_0_0_1_0_0_0_0_0 + 0.0846560846560904*G0_0_0_1_0_0_0_0_1 - 0.0846560846560904*G0_0_0_1_0_0_1_0_0 - 0.0846560846560904*G0_0_0_1_0_0_2_0_1 + 0.0846560846560904*G0_0_0_1_0_0_3_1_0 + 0.0846560846560904*G0_0_0_1_0_0_3_1_1 - 0.0846560846560904*G0_0_0_1_0_0_4_1_0 - 0.0846560846560904*G0_0_0_1_0_0_5_1_1 + 0.0846560846560904*G0_0_0_2_0_1_0_0_0 + 0.0846560846560904*G0_0_0_2_0_1_0_0_1 - 0.0846560846560904*G0_0_0_2_0_1_1_0_0 - 0.0846560846560904*G0_0_0_2_0_1_2_0_1 + 0.0846560846560904*G0_0_0_2_0_1_3_1_0 + 0.0846560846560904*G0_0_0_2_0_1_3_1_1 - 0.0846560846560904*G0_0_0_2_0_1_4_1_0 - 0.0846560846560904*G0_0_0_2_0_1_5_1_1 - 0.0846560846560904*G0_0_0_3_1_0_0_0_0 - 0.0846560846560904*G0_0_0_3_1_0_0_0_1 + 0.0846560846560904*G0_0_0_3_1_0_1_0_0 + 0.0846560846560904*G0_0_0_3_1_0_2_0_1 - 0.0846560846560904*G0_0_0_3_1_0_3_1_0 - 0.0846560846560904*G0_0_0_3_1_0_3_1_1 + 0.0846560846560904*G0_0_0_3_1_0_4_1_0 + 0.0846560846560904*G0_0_0_3_1_0_5_1_1 - 0.0846560846560904*G0_0_0_3_1_1_0_0_0 - 0.0846560846560904*G0_0_0_3_1_1_0_0_1 + 0.0846560846560904*G0_0_0_3_1_1_1_0_0 + 0.0846560846560904*G0_0_0_3_1_1_2_0_1 - 0.0846560846560904*G0_0_0_3_1_1_3_1_0 - 0.0846560846560904*G0_0_0_3_1_1_3_1_1 + 0.0846560846560904*G0_0_0_3_1_1_4_1_0 + 0.0846560846560904*G0_0_0_3_1_1_5_1_1 + 0.0846560846560904*G0_0_0_4_1_0_0_0_0 + 0.0846560846560904*G0_0_0_4_1_0_0_0_1 - 0.0846560846560904*G0_0_0_4_1_0_1_0_0 - 0.0846560846560904*G0_0_0_4_1_0_2_0_1 + 0.0846560846560904*G0_0_0_4_1_0_3_1_0 + 0.0846560846560904*G0_0_0_4_1_0_3_1_1 - 0.0846560846560904*G0_0_0_4_1_0_4_1_0 - 0.0846560846560904*G0_0_0_4_1_0_5_1_1 + 0.0846560846560904*G0_0_0_5_1_1_0_0_0 + 0.0846560846560904*G0_0_0_5_1_1_0_0_1 - 0.0846560846560904*G0_0_0_5_1_1_1_0_0 - 0.0846560846560904*G0_0_0_5_1_1_2_0_1 + 0.0846560846560904*G0_0_0_5_1_1_3_1_0 + 0.0846560846560904*G0_0_0_5_1_1_3_1_1 - 0.0846560846560904*G0_0_0_5_1_1_4_1_0 - 0.0846560846560904*G0_0_0_5_1_1_5_1_1 + 0.0846560846560903*G0_1_1_0_0_0_0_0_0 + 0.0846560846560903*G0_1_1_0_0_0_0_0_1 - 0.0846560846560903*G0_1_1_0_0_0_1_0_0 - 0.0846560846560903*G0_1_1_0_0_0_2_0_1 + 0.0846560846560903*G0_1_1_0_0_0_3_1_0 + 0.0846560846560903*G0_1_1_0_0_0_3_1_1 - 0.0846560846560903*G0_1_1_0_0_0_4_1_0 - 0.0846560846560903*G0_1_1_0_0_0_5_1_1 + 0.0846560846560903*G0_1_1_0_0_1_0_0_0 + 0.0846560846560903*G0_1_1_0_0_1_0_0_1 - 0.0846560846560903*G0_1_1_0_0_1_1_0_0 - 0.0846560846560903*G0_1_1_0_0_1_2_0_1 + 0.0846560846560903*G0_1_1_0_0_1_3_1_0 + 0.0846560846560903*G0_1_1_0_0_1_3_1_1 - 0.0846560846560903*G0_1_1_0_0_1_4_1_0 - 0.0846560846560903*G0_1_1_0_0_1_5_1_1 - 0.0846560846560903*G0_1_1_1_0_0_0_0_0 - 0.0846560846560903*G0_1_1_1_0_0_0_0_1 + 0.0846560846560903*G0_1_1_1_0_0_1_0_0 + 0.0846560846560903*G0_1_1_1_0_0_2_0_1 - 0.0846560846560903*G0_1_1_1_0_0_3_1_0 - 0.0846560846560903*G0_1_1_1_0_0_3_1_1 + 0.0846560846560903*G0_1_1_1_0_0_4_1_0 + 0.0846560846560903*G0_1_1_1_0_0_5_1_1 - 0.0846560846560903*G0_1_1_2_0_1_0_0_0 - 0.0846560846560903*G0_1_1_2_0_1_0_0_1 + 0.0846560846560903*G0_1_1_2_0_1_1_0_0 + 0.0846560846560903*G0_1_1_2_0_1_2_0_1 - 0.0846560846560903*G0_1_1_2_0_1_3_1_0 - 0.0846560846560903*G0_1_1_2_0_1_3_1_1 + 0.0846560846560903*G0_1_1_2_0_1_4_1_0 + 0.0846560846560903*G0_1_1_2_0_1_5_1_1 + 0.0846560846560903*G0_1_1_3_1_0_0_0_0 + 0.0846560846560903*G0_1_1_3_1_0_0_0_1 - 0.0846560846560903*G0_1_1_3_1_0_1_0_0 - 0.0846560846560903*G0_1_1_3_1_0_2_0_1 + 0.0846560846560903*G0_1_1_3_1_0_3_1_0 + 0.0846560846560903*G0_1_1_3_1_0_3_1_1 - 0.0846560846560903*G0_1_1_3_1_0_4_1_0 - 0.0846560846560903*G0_1_1_3_1_0_5_1_1 + 0.0846560846560903*G0_1_1_3_1_1_0_0_0 + 0.0846560846560903*G0_1_1_3_1_1_0_0_1 - 0.0846560846560903*G0_1_1_3_1_1_1_0_0 - 0.0846560846560903*G0_1_1_3_1_1_2_0_1 + 0.0846560846560903*G0_1_1_3_1_1_3_1_0 + 0.0846560846560903*G0_1_1_3_1_1_3_1_1 - 0.0846560846560903*G0_1_1_3_1_1_4_1_0 - 0.0846560846560903*G0_1_1_3_1_1_5_1_1 - 0.0846560846560903*G0_1_1_4_1_0_0_0_0 - 0.0846560846560903*G0_1_1_4_1_0_0_0_1 + 0.0846560846560903*G0_1_1_4_1_0_1_0_0 + 0.0846560846560903*G0_1_1_4_1_0_2_0_1 - 0.0846560846560903*G0_1_1_4_1_0_3_1_0 - 0.0846560846560903*G0_1_1_4_1_0_3_1_1 + 0.0846560846560903*G0_1_1_4_1_0_4_1_0 + 0.0846560846560903*G0_1_1_4_1_0_5_1_1 - 0.0846560846560903*G0_1_1_5_1_1_0_0_0 - 0.0846560846560903*G0_1_1_5_1_1_0_0_1 + 0.0846560846560903*G0_1_1_5_1_1_1_0_0 + 0.0846560846560903*G0_1_1_5_1_1_2_0_1 - 0.0846560846560903*G0_1_1_5_1_1_3_1_0 - 0.0846560846560903*G0_1_1_5_1_1_3_1_1 + 0.0846560846560903*G0_1_1_5_1_1_4_1_0 + 0.0846560846560903*G0_1_1_5_1_1_5_1_1; + A[851] = 0.0; + A[157] = A[215]; + A[880] = 0.0; + A[481] = 0.0; + A[200] = 0.0; + A[582] = 0.0; + A[522] = 0.0; + A[227] = 0.0; + A[615] = A[5]; + A[551] = 0.0; + A[708] = A[98]; + A[644] = 0.0; + A[253] = A[252]; + A[673] = 0.0; + A[278] = A[743]; + A[698] = 0.0; + A[315] = 0.0; + A[259] = 0.0; + A[344] = A[836]; + A[288] = 0.0; + A[742] = A[219]; + A[429] = A[748]; + A[369] = A[834]; + A[50] = 0.0; + A[773] = A[715]; + A[462] = 0.0; + A[402] = A[373]; + A[79] = 0.0; + A[800] = A[335]; + A[15] = 0.0; + A[100] = A[303]; + A[835] = A[312]; + A[44] = A[421]; + A[133] = A[394]; + A[842] = 0.0; + A[73] = A[887]; + A[150] = A[5]; + A[873] = 0.0; + A[106] = 0.0; + A[195] = 0.0; + A[591] = A[126]; + A[515] = 0.0; + A[224] = A[892]; + A[622] = A[215]; + A[542] = 0.0; + A[653] = -A[621] + 0.541798941798943*G0_0_1_0_0_0_0_0_0 + 0.541798941798943*G0_0_1_0_0_0_0_0_1 - 0.541798941798943*G0_0_1_0_0_0_1_0_0 - 0.541798941798943*G0_0_1_0_0_0_2_0_1 + 0.541798941798943*G0_0_1_0_0_0_3_1_0 + 0.541798941798943*G0_0_1_0_0_0_3_1_1 - 0.541798941798943*G0_0_1_0_0_0_4_1_0 - 0.541798941798943*G0_0_1_0_0_0_5_1_1 + 0.541798941798943*G0_0_1_0_0_1_0_0_0 + 0.541798941798943*G0_0_1_0_0_1_0_0_1 - 0.541798941798943*G0_0_1_0_0_1_1_0_0 - 0.541798941798943*G0_0_1_0_0_1_2_0_1 + 0.541798941798943*G0_0_1_0_0_1_3_1_0 + 0.541798941798943*G0_0_1_0_0_1_3_1_1 - 0.541798941798943*G0_0_1_0_0_1_4_1_0 - 0.541798941798943*G0_0_1_0_0_1_5_1_1 - 0.541798941798943*G0_0_1_1_0_0_0_0_0 - 0.541798941798943*G0_0_1_1_0_0_0_0_1 + 0.541798941798943*G0_0_1_1_0_0_1_0_0 + 0.541798941798943*G0_0_1_1_0_0_2_0_1 - 0.541798941798943*G0_0_1_1_0_0_3_1_0 - 0.541798941798943*G0_0_1_1_0_0_3_1_1 + 0.541798941798943*G0_0_1_1_0_0_4_1_0 + 0.541798941798943*G0_0_1_1_0_0_5_1_1 - 0.541798941798943*G0_0_1_2_0_1_0_0_0 - 0.541798941798943*G0_0_1_2_0_1_0_0_1 + 0.541798941798943*G0_0_1_2_0_1_1_0_0 + 0.541798941798943*G0_0_1_2_0_1_2_0_1 - 0.541798941798943*G0_0_1_2_0_1_3_1_0 - 0.541798941798943*G0_0_1_2_0_1_3_1_1 + 0.541798941798943*G0_0_1_2_0_1_4_1_0 + 0.541798941798943*G0_0_1_2_0_1_5_1_1 + 0.541798941798943*G0_0_1_3_1_0_0_0_0 + 0.541798941798943*G0_0_1_3_1_0_0_0_1 - 0.541798941798943*G0_0_1_3_1_0_1_0_0 - 0.541798941798943*G0_0_1_3_1_0_2_0_1 + 0.541798941798943*G0_0_1_3_1_0_3_1_0 + 0.541798941798943*G0_0_1_3_1_0_3_1_1 - 0.541798941798943*G0_0_1_3_1_0_4_1_0 - 0.541798941798943*G0_0_1_3_1_0_5_1_1 + 0.541798941798943*G0_0_1_3_1_1_0_0_0 + 0.541798941798943*G0_0_1_3_1_1_0_0_1 - 0.541798941798943*G0_0_1_3_1_1_1_0_0 - 0.541798941798943*G0_0_1_3_1_1_2_0_1 + 0.541798941798943*G0_0_1_3_1_1_3_1_0 + 0.541798941798943*G0_0_1_3_1_1_3_1_1 - 0.541798941798943*G0_0_1_3_1_1_4_1_0 - 0.541798941798943*G0_0_1_3_1_1_5_1_1 - 0.541798941798943*G0_0_1_4_1_0_0_0_0 - 0.541798941798943*G0_0_1_4_1_0_0_0_1 + 0.541798941798943*G0_0_1_4_1_0_1_0_0 + 0.541798941798943*G0_0_1_4_1_0_2_0_1 - 0.541798941798943*G0_0_1_4_1_0_3_1_0 - 0.541798941798943*G0_0_1_4_1_0_3_1_1 + 0.541798941798943*G0_0_1_4_1_0_4_1_0 + 0.541798941798943*G0_0_1_4_1_0_5_1_1 - 0.541798941798943*G0_0_1_5_1_1_0_0_0 - 0.541798941798943*G0_0_1_5_1_1_0_0_1 + 0.541798941798943*G0_0_1_5_1_1_1_0_0 + 0.541798941798943*G0_0_1_5_1_1_2_0_1 - 0.541798941798943*G0_0_1_5_1_1_3_1_0 - 0.541798941798943*G0_0_1_5_1_1_3_1_1 + 0.541798941798943*G0_0_1_5_1_1_4_1_0 + 0.541798941798943*G0_0_1_5_1_1_5_1_1 + 0.880423280423282*G0_1_1_0_0_0_0_0_0 + 0.880423280423282*G0_1_1_0_0_0_0_0_1 - 0.880423280423282*G0_1_1_0_0_0_1_0_0 - 0.880423280423282*G0_1_1_0_0_0_2_0_1 + 0.880423280423282*G0_1_1_0_0_0_3_1_0 + 0.880423280423282*G0_1_1_0_0_0_3_1_1 - 0.880423280423282*G0_1_1_0_0_0_4_1_0 - 0.880423280423282*G0_1_1_0_0_0_5_1_1 + 0.880423280423282*G0_1_1_0_0_1_0_0_0 + 0.880423280423282*G0_1_1_0_0_1_0_0_1 - 0.880423280423282*G0_1_1_0_0_1_1_0_0 - 0.880423280423282*G0_1_1_0_0_1_2_0_1 + 0.880423280423282*G0_1_1_0_0_1_3_1_0 + 0.880423280423282*G0_1_1_0_0_1_3_1_1 - 0.880423280423282*G0_1_1_0_0_1_4_1_0 - 0.880423280423282*G0_1_1_0_0_1_5_1_1 - 0.880423280423282*G0_1_1_1_0_0_0_0_0 - 0.880423280423282*G0_1_1_1_0_0_0_0_1 + 0.880423280423282*G0_1_1_1_0_0_1_0_0 + 0.880423280423282*G0_1_1_1_0_0_2_0_1 - 0.880423280423282*G0_1_1_1_0_0_3_1_0 - 0.880423280423282*G0_1_1_1_0_0_3_1_1 + 0.880423280423282*G0_1_1_1_0_0_4_1_0 + 0.880423280423282*G0_1_1_1_0_0_5_1_1 - 0.880423280423282*G0_1_1_2_0_1_0_0_0 - 0.880423280423282*G0_1_1_2_0_1_0_0_1 + 0.880423280423282*G0_1_1_2_0_1_1_0_0 + 0.880423280423282*G0_1_1_2_0_1_2_0_1 - 0.880423280423282*G0_1_1_2_0_1_3_1_0 - 0.880423280423282*G0_1_1_2_0_1_3_1_1 + 0.880423280423282*G0_1_1_2_0_1_4_1_0 + 0.880423280423282*G0_1_1_2_0_1_5_1_1 + 0.880423280423282*G0_1_1_3_1_0_0_0_0 + 0.880423280423282*G0_1_1_3_1_0_0_0_1 - 0.880423280423282*G0_1_1_3_1_0_1_0_0 - 0.880423280423282*G0_1_1_3_1_0_2_0_1 + 0.880423280423282*G0_1_1_3_1_0_3_1_0 + 0.880423280423282*G0_1_1_3_1_0_3_1_1 - 0.880423280423282*G0_1_1_3_1_0_4_1_0 - 0.880423280423282*G0_1_1_3_1_0_5_1_1 + 0.880423280423282*G0_1_1_3_1_1_0_0_0 + 0.880423280423282*G0_1_1_3_1_1_0_0_1 - 0.880423280423282*G0_1_1_3_1_1_1_0_0 - 0.880423280423282*G0_1_1_3_1_1_2_0_1 + 0.880423280423282*G0_1_1_3_1_1_3_1_0 + 0.880423280423282*G0_1_1_3_1_1_3_1_1 - 0.880423280423282*G0_1_1_3_1_1_4_1_0 - 0.880423280423282*G0_1_1_3_1_1_5_1_1 - 0.880423280423282*G0_1_1_4_1_0_0_0_0 - 0.880423280423282*G0_1_1_4_1_0_0_0_1 + 0.880423280423282*G0_1_1_4_1_0_1_0_0 + 0.880423280423282*G0_1_1_4_1_0_2_0_1 - 0.880423280423282*G0_1_1_4_1_0_3_1_0 - 0.880423280423282*G0_1_1_4_1_0_3_1_1 + 0.880423280423282*G0_1_1_4_1_0_4_1_0 + 0.880423280423282*G0_1_1_4_1_0_5_1_1 - 0.880423280423282*G0_1_1_5_1_1_0_0_0 - 0.880423280423282*G0_1_1_5_1_1_0_0_1 + 0.880423280423282*G0_1_1_5_1_1_1_0_0 + 0.880423280423282*G0_1_1_5_1_1_2_0_1 - 0.880423280423282*G0_1_1_5_1_1_3_1_0 - 0.880423280423282*G0_1_1_5_1_1_3_1_1 + 0.880423280423282*G0_1_1_5_1_1_4_1_0 + 0.880423280423282*G0_1_1_5_1_1_5_1_1; + A[664] = 0.0; + A[568] = A[103]; + A[691] = 0.0; + A[266] = 0.0; + A[337] = A[221]; + A[297] = 0.0; + A[749] = A[748]; + A[436] = 0.0; + A[360] = A[14]; + A[316] = 0.0; + A[774] = A[309]; + A[471] = A[270] + 0.778835978835986*G0_0_0_0_0_0_0_0_0 + 0.778835978835986*G0_0_0_0_0_0_0_0_1 - 0.778835978835986*G0_0_0_0_0_0_1_0_0 - 0.778835978835986*G0_0_0_0_0_0_2_0_1 + 0.778835978835986*G0_0_0_0_0_0_3_1_0 + 0.778835978835986*G0_0_0_0_0_0_3_1_1 - 0.778835978835986*G0_0_0_0_0_0_4_1_0 - 0.778835978835986*G0_0_0_0_0_0_5_1_1 + 0.778835978835986*G0_0_0_0_0_1_0_0_0 + 0.778835978835986*G0_0_0_0_0_1_0_0_1 - 0.778835978835986*G0_0_0_0_0_1_1_0_0 - 0.778835978835986*G0_0_0_0_0_1_2_0_1 + 0.778835978835986*G0_0_0_0_0_1_3_1_0 + 0.778835978835986*G0_0_0_0_0_1_3_1_1 - 0.778835978835986*G0_0_0_0_0_1_4_1_0 - 0.778835978835986*G0_0_0_0_0_1_5_1_1 - 0.778835978835986*G0_0_0_1_0_0_0_0_0 - 0.778835978835986*G0_0_0_1_0_0_0_0_1 + 0.778835978835986*G0_0_0_1_0_0_1_0_0 + 0.778835978835986*G0_0_0_1_0_0_2_0_1 - 0.778835978835986*G0_0_0_1_0_0_3_1_0 - 0.778835978835986*G0_0_0_1_0_0_3_1_1 + 0.778835978835986*G0_0_0_1_0_0_4_1_0 + 0.778835978835986*G0_0_0_1_0_0_5_1_1 - 0.778835978835986*G0_0_0_2_0_1_0_0_0 - 0.778835978835986*G0_0_0_2_0_1_0_0_1 + 0.778835978835986*G0_0_0_2_0_1_1_0_0 + 0.778835978835986*G0_0_0_2_0_1_2_0_1 - 0.778835978835986*G0_0_0_2_0_1_3_1_0 - 0.778835978835986*G0_0_0_2_0_1_3_1_1 + 0.778835978835986*G0_0_0_2_0_1_4_1_0 + 0.778835978835986*G0_0_0_2_0_1_5_1_1 + 0.778835978835986*G0_0_0_3_1_0_0_0_0 + 0.778835978835986*G0_0_0_3_1_0_0_0_1 - 0.778835978835986*G0_0_0_3_1_0_1_0_0 - 0.778835978835986*G0_0_0_3_1_0_2_0_1 + 0.778835978835986*G0_0_0_3_1_0_3_1_0 + 0.778835978835986*G0_0_0_3_1_0_3_1_1 - 0.778835978835986*G0_0_0_3_1_0_4_1_0 - 0.778835978835986*G0_0_0_3_1_0_5_1_1 + 0.778835978835986*G0_0_0_3_1_1_0_0_0 + 0.778835978835986*G0_0_0_3_1_1_0_0_1 - 0.778835978835986*G0_0_0_3_1_1_1_0_0 - 0.778835978835986*G0_0_0_3_1_1_2_0_1 + 0.778835978835986*G0_0_0_3_1_1_3_1_0 + 0.778835978835986*G0_0_0_3_1_1_3_1_1 - 0.778835978835986*G0_0_0_3_1_1_4_1_0 - 0.778835978835986*G0_0_0_3_1_1_5_1_1 - 0.778835978835986*G0_0_0_4_1_0_0_0_0 - 0.778835978835986*G0_0_0_4_1_0_0_0_1 + 0.778835978835986*G0_0_0_4_1_0_1_0_0 + 0.778835978835986*G0_0_0_4_1_0_2_0_1 - 0.778835978835986*G0_0_0_4_1_0_3_1_0 - 0.778835978835986*G0_0_0_4_1_0_3_1_1 + 0.778835978835986*G0_0_0_4_1_0_4_1_0 + 0.778835978835986*G0_0_0_4_1_0_5_1_1 - 0.778835978835986*G0_0_0_5_1_1_0_0_0 - 0.778835978835986*G0_0_0_5_1_1_0_0_1 + 0.778835978835986*G0_0_0_5_1_1_1_0_0 + 0.778835978835986*G0_0_0_5_1_1_2_0_1 - 0.778835978835986*G0_0_0_5_1_1_3_1_0 - 0.778835978835986*G0_0_0_5_1_1_3_1_1 + 0.778835978835986*G0_0_0_5_1_1_4_1_0 + 0.778835978835986*G0_0_0_5_1_1_5_1_1 - 0.778835978835986*G0_1_1_0_0_0_0_0_0 - 0.778835978835986*G0_1_1_0_0_0_0_0_1 + 0.778835978835986*G0_1_1_0_0_0_1_0_0 + 0.778835978835986*G0_1_1_0_0_0_2_0_1 - 0.778835978835986*G0_1_1_0_0_0_3_1_0 - 0.778835978835986*G0_1_1_0_0_0_3_1_1 + 0.778835978835986*G0_1_1_0_0_0_4_1_0 + 0.778835978835986*G0_1_1_0_0_0_5_1_1 - 0.778835978835986*G0_1_1_0_0_1_0_0_0 - 0.778835978835986*G0_1_1_0_0_1_0_0_1 + 0.778835978835986*G0_1_1_0_0_1_1_0_0 + 0.778835978835986*G0_1_1_0_0_1_2_0_1 - 0.778835978835986*G0_1_1_0_0_1_3_1_0 - 0.778835978835986*G0_1_1_0_0_1_3_1_1 + 0.778835978835986*G0_1_1_0_0_1_4_1_0 + 0.778835978835986*G0_1_1_0_0_1_5_1_1 + 0.778835978835986*G0_1_1_1_0_0_0_0_0 + 0.778835978835986*G0_1_1_1_0_0_0_0_1 - 0.778835978835986*G0_1_1_1_0_0_1_0_0 - 0.778835978835986*G0_1_1_1_0_0_2_0_1 + 0.778835978835986*G0_1_1_1_0_0_3_1_0 + 0.778835978835986*G0_1_1_1_0_0_3_1_1 - 0.778835978835986*G0_1_1_1_0_0_4_1_0 - 0.778835978835986*G0_1_1_1_0_0_5_1_1 + 0.778835978835986*G0_1_1_2_0_1_0_0_0 + 0.778835978835986*G0_1_1_2_0_1_0_0_1 - 0.778835978835986*G0_1_1_2_0_1_1_0_0 - 0.778835978835986*G0_1_1_2_0_1_2_0_1 + 0.778835978835986*G0_1_1_2_0_1_3_1_0 + 0.778835978835986*G0_1_1_2_0_1_3_1_1 - 0.778835978835986*G0_1_1_2_0_1_4_1_0 - 0.778835978835986*G0_1_1_2_0_1_5_1_1 - 0.778835978835986*G0_1_1_3_1_0_0_0_0 - 0.778835978835986*G0_1_1_3_1_0_0_0_1 + 0.778835978835986*G0_1_1_3_1_0_1_0_0 + 0.778835978835986*G0_1_1_3_1_0_2_0_1 - 0.778835978835986*G0_1_1_3_1_0_3_1_0 - 0.778835978835986*G0_1_1_3_1_0_3_1_1 + 0.778835978835986*G0_1_1_3_1_0_4_1_0 + 0.778835978835986*G0_1_1_3_1_0_5_1_1 - 0.778835978835986*G0_1_1_3_1_1_0_0_0 - 0.778835978835986*G0_1_1_3_1_1_0_0_1 + 0.778835978835986*G0_1_1_3_1_1_1_0_0 + 0.778835978835986*G0_1_1_3_1_1_2_0_1 - 0.778835978835986*G0_1_1_3_1_1_3_1_0 - 0.778835978835986*G0_1_1_3_1_1_3_1_1 + 0.778835978835986*G0_1_1_3_1_1_4_1_0 + 0.778835978835986*G0_1_1_3_1_1_5_1_1 + 0.778835978835986*G0_1_1_4_1_0_0_0_0 + 0.778835978835986*G0_1_1_4_1_0_0_0_1 - 0.778835978835986*G0_1_1_4_1_0_1_0_0 - 0.778835978835986*G0_1_1_4_1_0_2_0_1 + 0.778835978835986*G0_1_1_4_1_0_3_1_0 + 0.778835978835986*G0_1_1_4_1_0_3_1_1 - 0.778835978835986*G0_1_1_4_1_0_4_1_0 - 0.778835978835986*G0_1_1_4_1_0_5_1_1 + 0.778835978835986*G0_1_1_5_1_1_0_0_0 + 0.778835978835986*G0_1_1_5_1_1_0_0_1 - 0.778835978835986*G0_1_1_5_1_1_1_0_0 - 0.778835978835986*G0_1_1_5_1_1_2_0_1 + 0.778835978835986*G0_1_1_5_1_1_3_1_0 + 0.778835978835986*G0_1_1_5_1_1_3_1_1 - 0.778835978835986*G0_1_1_5_1_1_4_1_0 - 0.778835978835986*G0_1_1_5_1_1_5_1_1; + A[395] = A[628]; + A[359] = 0.0; + A[6] = A[471]; + A[723] = 0.0; + A[37] = A[181]; + A[752] = 0.0; + A[865] = A[892] + 2.74285714285719*G0_0_0_0_0_0_0_0_0 + 2.74285714285719*G0_0_0_0_0_0_0_0_1 - 2.74285714285719*G0_0_0_0_0_0_1_0_0 - 2.74285714285719*G0_0_0_0_0_0_2_0_1 + 2.74285714285719*G0_0_0_0_0_0_3_1_0 + 2.74285714285719*G0_0_0_0_0_0_3_1_1 - 2.74285714285719*G0_0_0_0_0_0_4_1_0 - 2.74285714285719*G0_0_0_0_0_0_5_1_1 + 2.74285714285719*G0_0_0_0_0_1_0_0_0 + 2.74285714285719*G0_0_0_0_0_1_0_0_1 - 2.74285714285719*G0_0_0_0_0_1_1_0_0 - 2.74285714285719*G0_0_0_0_0_1_2_0_1 + 2.74285714285719*G0_0_0_0_0_1_3_1_0 + 2.74285714285719*G0_0_0_0_0_1_3_1_1 - 2.74285714285719*G0_0_0_0_0_1_4_1_0 - 2.74285714285719*G0_0_0_0_0_1_5_1_1 - 2.74285714285719*G0_0_0_1_0_0_0_0_0 - 2.74285714285719*G0_0_0_1_0_0_0_0_1 + 2.74285714285719*G0_0_0_1_0_0_1_0_0 + 2.74285714285719*G0_0_0_1_0_0_2_0_1 - 2.74285714285719*G0_0_0_1_0_0_3_1_0 - 2.74285714285719*G0_0_0_1_0_0_3_1_1 + 2.74285714285719*G0_0_0_1_0_0_4_1_0 + 2.74285714285719*G0_0_0_1_0_0_5_1_1 - 2.74285714285719*G0_0_0_2_0_1_0_0_0 - 2.74285714285719*G0_0_0_2_0_1_0_0_1 + 2.74285714285719*G0_0_0_2_0_1_1_0_0 + 2.74285714285719*G0_0_0_2_0_1_2_0_1 - 2.74285714285719*G0_0_0_2_0_1_3_1_0 - 2.74285714285719*G0_0_0_2_0_1_3_1_1 + 2.74285714285719*G0_0_0_2_0_1_4_1_0 + 2.74285714285719*G0_0_0_2_0_1_5_1_1 + 2.74285714285719*G0_0_0_3_1_0_0_0_0 + 2.74285714285719*G0_0_0_3_1_0_0_0_1 - 2.74285714285719*G0_0_0_3_1_0_1_0_0 - 2.74285714285719*G0_0_0_3_1_0_2_0_1 + 2.74285714285719*G0_0_0_3_1_0_3_1_0 + 2.74285714285719*G0_0_0_3_1_0_3_1_1 - 2.74285714285719*G0_0_0_3_1_0_4_1_0 - 2.74285714285719*G0_0_0_3_1_0_5_1_1 + 2.74285714285719*G0_0_0_3_1_1_0_0_0 + 2.74285714285719*G0_0_0_3_1_1_0_0_1 - 2.74285714285719*G0_0_0_3_1_1_1_0_0 - 2.74285714285719*G0_0_0_3_1_1_2_0_1 + 2.74285714285719*G0_0_0_3_1_1_3_1_0 + 2.74285714285719*G0_0_0_3_1_1_3_1_1 - 2.74285714285719*G0_0_0_3_1_1_4_1_0 - 2.74285714285719*G0_0_0_3_1_1_5_1_1 - 2.74285714285719*G0_0_0_4_1_0_0_0_0 - 2.74285714285719*G0_0_0_4_1_0_0_0_1 + 2.74285714285719*G0_0_0_4_1_0_1_0_0 + 2.74285714285719*G0_0_0_4_1_0_2_0_1 - 2.74285714285719*G0_0_0_4_1_0_3_1_0 - 2.74285714285719*G0_0_0_4_1_0_3_1_1 + 2.74285714285719*G0_0_0_4_1_0_4_1_0 + 2.74285714285719*G0_0_0_4_1_0_5_1_1 - 2.74285714285719*G0_0_0_5_1_1_0_0_0 - 2.74285714285719*G0_0_0_5_1_1_0_0_1 + 2.74285714285719*G0_0_0_5_1_1_1_0_0 + 2.74285714285719*G0_0_0_5_1_1_2_0_1 - 2.74285714285719*G0_0_0_5_1_1_3_1_0 - 2.74285714285719*G0_0_0_5_1_1_3_1_1 + 2.74285714285719*G0_0_0_5_1_1_4_1_0 + 2.74285714285719*G0_0_0_5_1_1_5_1_1 - 2.74285714285719*G0_1_1_0_0_0_0_0_0 - 2.74285714285719*G0_1_1_0_0_0_0_0_1 + 2.74285714285719*G0_1_1_0_0_0_1_0_0 + 2.74285714285719*G0_1_1_0_0_0_2_0_1 - 2.74285714285719*G0_1_1_0_0_0_3_1_0 - 2.74285714285719*G0_1_1_0_0_0_3_1_1 + 2.74285714285719*G0_1_1_0_0_0_4_1_0 + 2.74285714285719*G0_1_1_0_0_0_5_1_1 - 2.74285714285719*G0_1_1_0_0_1_0_0_0 - 2.74285714285719*G0_1_1_0_0_1_0_0_1 + 2.74285714285719*G0_1_1_0_0_1_1_0_0 + 2.74285714285719*G0_1_1_0_0_1_2_0_1 - 2.74285714285719*G0_1_1_0_0_1_3_1_0 - 2.74285714285719*G0_1_1_0_0_1_3_1_1 + 2.74285714285719*G0_1_1_0_0_1_4_1_0 + 2.74285714285719*G0_1_1_0_0_1_5_1_1 + 2.74285714285719*G0_1_1_1_0_0_0_0_0 + 2.74285714285719*G0_1_1_1_0_0_0_0_1 - 2.74285714285719*G0_1_1_1_0_0_1_0_0 - 2.74285714285719*G0_1_1_1_0_0_2_0_1 + 2.74285714285719*G0_1_1_1_0_0_3_1_0 + 2.74285714285719*G0_1_1_1_0_0_3_1_1 - 2.74285714285719*G0_1_1_1_0_0_4_1_0 - 2.74285714285719*G0_1_1_1_0_0_5_1_1 + 2.74285714285719*G0_1_1_2_0_1_0_0_0 + 2.74285714285719*G0_1_1_2_0_1_0_0_1 - 2.74285714285719*G0_1_1_2_0_1_1_0_0 - 2.74285714285719*G0_1_1_2_0_1_2_0_1 + 2.74285714285719*G0_1_1_2_0_1_3_1_0 + 2.74285714285719*G0_1_1_2_0_1_3_1_1 - 2.74285714285719*G0_1_1_2_0_1_4_1_0 - 2.74285714285719*G0_1_1_2_0_1_5_1_1 - 2.74285714285719*G0_1_1_3_1_0_0_0_0 - 2.74285714285719*G0_1_1_3_1_0_0_0_1 + 2.74285714285719*G0_1_1_3_1_0_1_0_0 + 2.74285714285719*G0_1_1_3_1_0_2_0_1 - 2.74285714285719*G0_1_1_3_1_0_3_1_0 - 2.74285714285719*G0_1_1_3_1_0_3_1_1 + 2.74285714285719*G0_1_1_3_1_0_4_1_0 + 2.74285714285719*G0_1_1_3_1_0_5_1_1 - 2.74285714285719*G0_1_1_3_1_1_0_0_0 - 2.74285714285719*G0_1_1_3_1_1_0_0_1 + 2.74285714285719*G0_1_1_3_1_1_1_0_0 + 2.74285714285719*G0_1_1_3_1_1_2_0_1 - 2.74285714285719*G0_1_1_3_1_1_3_1_0 - 2.74285714285719*G0_1_1_3_1_1_3_1_1 + 2.74285714285719*G0_1_1_3_1_1_4_1_0 + 2.74285714285719*G0_1_1_3_1_1_5_1_1 + 2.74285714285719*G0_1_1_4_1_0_0_0_0 + 2.74285714285719*G0_1_1_4_1_0_0_0_1 - 2.74285714285719*G0_1_1_4_1_0_1_0_0 - 2.74285714285719*G0_1_1_4_1_0_2_0_1 + 2.74285714285719*G0_1_1_4_1_0_3_1_0 + 2.74285714285719*G0_1_1_4_1_0_3_1_1 - 2.74285714285719*G0_1_1_4_1_0_4_1_0 - 2.74285714285719*G0_1_1_4_1_0_5_1_1 + 2.74285714285719*G0_1_1_5_1_1_0_0_0 + 2.74285714285719*G0_1_1_5_1_1_0_0_1 - 2.74285714285719*G0_1_1_5_1_1_1_0_0 - 2.74285714285719*G0_1_1_5_1_1_2_0_1 + 2.74285714285719*G0_1_1_5_1_1_3_1_0 + 2.74285714285719*G0_1_1_5_1_1_3_1_1 - 2.74285714285719*G0_1_1_5_1_1_4_1_0 - 2.74285714285719*G0_1_1_5_1_1_5_1_1; + A[64] = A[534] - 0.42539682539683*G0_1_0_0_0_0_0_0_0 - 0.42539682539683*G0_1_0_0_0_0_0_0_1 + 0.42539682539683*G0_1_0_0_0_0_1_0_0 + 0.42539682539683*G0_1_0_0_0_0_2_0_1 - 0.42539682539683*G0_1_0_0_0_0_3_1_0 - 0.42539682539683*G0_1_0_0_0_0_3_1_1 + 0.42539682539683*G0_1_0_0_0_0_4_1_0 + 0.42539682539683*G0_1_0_0_0_0_5_1_1 - 0.42539682539683*G0_1_0_0_0_1_0_0_0 - 0.42539682539683*G0_1_0_0_0_1_0_0_1 + 0.42539682539683*G0_1_0_0_0_1_1_0_0 + 0.42539682539683*G0_1_0_0_0_1_2_0_1 - 0.42539682539683*G0_1_0_0_0_1_3_1_0 - 0.42539682539683*G0_1_0_0_0_1_3_1_1 + 0.42539682539683*G0_1_0_0_0_1_4_1_0 + 0.42539682539683*G0_1_0_0_0_1_5_1_1 + 0.42539682539683*G0_1_0_1_0_0_0_0_0 + 0.42539682539683*G0_1_0_1_0_0_0_0_1 - 0.42539682539683*G0_1_0_1_0_0_1_0_0 - 0.42539682539683*G0_1_0_1_0_0_2_0_1 + 0.42539682539683*G0_1_0_1_0_0_3_1_0 + 0.42539682539683*G0_1_0_1_0_0_3_1_1 - 0.42539682539683*G0_1_0_1_0_0_4_1_0 - 0.42539682539683*G0_1_0_1_0_0_5_1_1 + 0.42539682539683*G0_1_0_2_0_1_0_0_0 + 0.42539682539683*G0_1_0_2_0_1_0_0_1 - 0.42539682539683*G0_1_0_2_0_1_1_0_0 - 0.42539682539683*G0_1_0_2_0_1_2_0_1 + 0.42539682539683*G0_1_0_2_0_1_3_1_0 + 0.42539682539683*G0_1_0_2_0_1_3_1_1 - 0.42539682539683*G0_1_0_2_0_1_4_1_0 - 0.42539682539683*G0_1_0_2_0_1_5_1_1 - 0.42539682539683*G0_1_0_3_1_0_0_0_0 - 0.42539682539683*G0_1_0_3_1_0_0_0_1 + 0.42539682539683*G0_1_0_3_1_0_1_0_0 + 0.42539682539683*G0_1_0_3_1_0_2_0_1 - 0.42539682539683*G0_1_0_3_1_0_3_1_0 - 0.42539682539683*G0_1_0_3_1_0_3_1_1 + 0.42539682539683*G0_1_0_3_1_0_4_1_0 + 0.42539682539683*G0_1_0_3_1_0_5_1_1 - 0.42539682539683*G0_1_0_3_1_1_0_0_0 - 0.42539682539683*G0_1_0_3_1_1_0_0_1 + 0.42539682539683*G0_1_0_3_1_1_1_0_0 + 0.42539682539683*G0_1_0_3_1_1_2_0_1 - 0.42539682539683*G0_1_0_3_1_1_3_1_0 - 0.42539682539683*G0_1_0_3_1_1_3_1_1 + 0.42539682539683*G0_1_0_3_1_1_4_1_0 + 0.42539682539683*G0_1_0_3_1_1_5_1_1 + 0.42539682539683*G0_1_0_4_1_0_0_0_0 + 0.42539682539683*G0_1_0_4_1_0_0_0_1 - 0.42539682539683*G0_1_0_4_1_0_1_0_0 - 0.42539682539683*G0_1_0_4_1_0_2_0_1 + 0.42539682539683*G0_1_0_4_1_0_3_1_0 + 0.42539682539683*G0_1_0_4_1_0_3_1_1 - 0.42539682539683*G0_1_0_4_1_0_4_1_0 - 0.42539682539683*G0_1_0_4_1_0_5_1_1 + 0.42539682539683*G0_1_0_5_1_1_0_0_0 + 0.42539682539683*G0_1_0_5_1_1_0_0_1 - 0.42539682539683*G0_1_0_5_1_1_1_0_0 - 0.42539682539683*G0_1_0_5_1_1_2_0_1 + 0.42539682539683*G0_1_0_5_1_1_3_1_0 + 0.42539682539683*G0_1_0_5_1_1_3_1_1 - 0.42539682539683*G0_1_0_5_1_1_4_1_0 - 0.42539682539683*G0_1_0_5_1_1_5_1_1; + A[67] = -A[64] + 0.510052910052918*G0_1_1_0_0_0_0_0_0 + 0.510052910052918*G0_1_1_0_0_0_0_0_1 - 0.510052910052918*G0_1_1_0_0_0_1_0_0 - 0.510052910052918*G0_1_1_0_0_0_2_0_1 + 0.510052910052918*G0_1_1_0_0_0_3_1_0 + 0.510052910052918*G0_1_1_0_0_0_3_1_1 - 0.510052910052918*G0_1_1_0_0_0_4_1_0 - 0.510052910052918*G0_1_1_0_0_0_5_1_1 + 0.510052910052918*G0_1_1_0_0_1_0_0_0 + 0.510052910052918*G0_1_1_0_0_1_0_0_1 - 0.510052910052918*G0_1_1_0_0_1_1_0_0 - 0.510052910052918*G0_1_1_0_0_1_2_0_1 + 0.510052910052918*G0_1_1_0_0_1_3_1_0 + 0.510052910052918*G0_1_1_0_0_1_3_1_1 - 0.510052910052918*G0_1_1_0_0_1_4_1_0 - 0.510052910052918*G0_1_1_0_0_1_5_1_1 - 0.510052910052918*G0_1_1_1_0_0_0_0_0 - 0.510052910052918*G0_1_1_1_0_0_0_0_1 + 0.510052910052918*G0_1_1_1_0_0_1_0_0 + 0.510052910052918*G0_1_1_1_0_0_2_0_1 - 0.510052910052918*G0_1_1_1_0_0_3_1_0 - 0.510052910052918*G0_1_1_1_0_0_3_1_1 + 0.510052910052918*G0_1_1_1_0_0_4_1_0 + 0.510052910052918*G0_1_1_1_0_0_5_1_1 - 0.510052910052918*G0_1_1_2_0_1_0_0_0 - 0.510052910052918*G0_1_1_2_0_1_0_0_1 + 0.510052910052918*G0_1_1_2_0_1_1_0_0 + 0.510052910052918*G0_1_1_2_0_1_2_0_1 - 0.510052910052918*G0_1_1_2_0_1_3_1_0 - 0.510052910052918*G0_1_1_2_0_1_3_1_1 + 0.510052910052918*G0_1_1_2_0_1_4_1_0 + 0.510052910052918*G0_1_1_2_0_1_5_1_1 + 0.510052910052918*G0_1_1_3_1_0_0_0_0 + 0.510052910052918*G0_1_1_3_1_0_0_0_1 - 0.510052910052918*G0_1_1_3_1_0_1_0_0 - 0.510052910052918*G0_1_1_3_1_0_2_0_1 + 0.510052910052918*G0_1_1_3_1_0_3_1_0 + 0.510052910052918*G0_1_1_3_1_0_3_1_1 - 0.510052910052918*G0_1_1_3_1_0_4_1_0 - 0.510052910052918*G0_1_1_3_1_0_5_1_1 + 0.510052910052918*G0_1_1_3_1_1_0_0_0 + 0.510052910052918*G0_1_1_3_1_1_0_0_1 - 0.510052910052918*G0_1_1_3_1_1_1_0_0 - 0.510052910052918*G0_1_1_3_1_1_2_0_1 + 0.510052910052918*G0_1_1_3_1_1_3_1_0 + 0.510052910052918*G0_1_1_3_1_1_3_1_1 - 0.510052910052918*G0_1_1_3_1_1_4_1_0 - 0.510052910052918*G0_1_1_3_1_1_5_1_1 - 0.510052910052918*G0_1_1_4_1_0_0_0_0 - 0.510052910052918*G0_1_1_4_1_0_0_0_1 + 0.510052910052918*G0_1_1_4_1_0_1_0_0 + 0.510052910052918*G0_1_1_4_1_0_2_0_1 - 0.510052910052918*G0_1_1_4_1_0_3_1_0 - 0.510052910052918*G0_1_1_4_1_0_3_1_1 + 0.510052910052918*G0_1_1_4_1_0_4_1_0 + 0.510052910052918*G0_1_1_4_1_0_5_1_1 - 0.510052910052918*G0_1_1_5_1_1_0_0_0 - 0.510052910052918*G0_1_1_5_1_1_0_0_1 + 0.510052910052918*G0_1_1_5_1_1_1_0_0 + 0.510052910052918*G0_1_1_5_1_1_2_0_1 - 0.510052910052918*G0_1_1_5_1_1_3_1_0 - 0.510052910052918*G0_1_1_5_1_1_3_1_1 + 0.510052910052918*G0_1_1_5_1_1_4_1_0 + 0.510052910052918*G0_1_1_5_1_1_5_1_1; + A[159] = A[624]; + A[898] = A[869]; + A[115] = 0.0; + A[186] = A[279]; + A[138] = 0.0; + A[596] = A[334]; + A[217] = A[775] - 0.507936507936508*G0_0_0_0_0_0_0_0_0 - 0.507936507936508*G0_0_0_0_0_0_0_0_1 + 0.507936507936508*G0_0_0_0_0_0_1_0_0 + 0.507936507936508*G0_0_0_0_0_0_2_0_1 - 0.507936507936508*G0_0_0_0_0_0_3_1_0 - 0.507936507936508*G0_0_0_0_0_0_3_1_1 + 0.507936507936508*G0_0_0_0_0_0_4_1_0 + 0.507936507936508*G0_0_0_0_0_0_5_1_1 - 0.507936507936508*G0_0_0_0_0_1_0_0_0 - 0.507936507936508*G0_0_0_0_0_1_0_0_1 + 0.507936507936508*G0_0_0_0_0_1_1_0_0 + 0.507936507936508*G0_0_0_0_0_1_2_0_1 - 0.507936507936508*G0_0_0_0_0_1_3_1_0 - 0.507936507936508*G0_0_0_0_0_1_3_1_1 + 0.507936507936508*G0_0_0_0_0_1_4_1_0 + 0.507936507936508*G0_0_0_0_0_1_5_1_1 + 0.507936507936508*G0_0_0_1_0_0_0_0_0 + 0.507936507936508*G0_0_0_1_0_0_0_0_1 - 0.507936507936508*G0_0_0_1_0_0_1_0_0 - 0.507936507936508*G0_0_0_1_0_0_2_0_1 + 0.507936507936508*G0_0_0_1_0_0_3_1_0 + 0.507936507936508*G0_0_0_1_0_0_3_1_1 - 0.507936507936508*G0_0_0_1_0_0_4_1_0 - 0.507936507936508*G0_0_0_1_0_0_5_1_1 + 0.507936507936508*G0_0_0_2_0_1_0_0_0 + 0.507936507936508*G0_0_0_2_0_1_0_0_1 - 0.507936507936508*G0_0_0_2_0_1_1_0_0 - 0.507936507936508*G0_0_0_2_0_1_2_0_1 + 0.507936507936508*G0_0_0_2_0_1_3_1_0 + 0.507936507936508*G0_0_0_2_0_1_3_1_1 - 0.507936507936508*G0_0_0_2_0_1_4_1_0 - 0.507936507936508*G0_0_0_2_0_1_5_1_1 - 0.507936507936508*G0_0_0_3_1_0_0_0_0 - 0.507936507936508*G0_0_0_3_1_0_0_0_1 + 0.507936507936508*G0_0_0_3_1_0_1_0_0 + 0.507936507936508*G0_0_0_3_1_0_2_0_1 - 0.507936507936508*G0_0_0_3_1_0_3_1_0 - 0.507936507936508*G0_0_0_3_1_0_3_1_1 + 0.507936507936508*G0_0_0_3_1_0_4_1_0 + 0.507936507936508*G0_0_0_3_1_0_5_1_1 - 0.507936507936508*G0_0_0_3_1_1_0_0_0 - 0.507936507936508*G0_0_0_3_1_1_0_0_1 + 0.507936507936508*G0_0_0_3_1_1_1_0_0 + 0.507936507936508*G0_0_0_3_1_1_2_0_1 - 0.507936507936508*G0_0_0_3_1_1_3_1_0 - 0.507936507936508*G0_0_0_3_1_1_3_1_1 + 0.507936507936508*G0_0_0_3_1_1_4_1_0 + 0.507936507936508*G0_0_0_3_1_1_5_1_1 + 0.507936507936508*G0_0_0_4_1_0_0_0_0 + 0.507936507936508*G0_0_0_4_1_0_0_0_1 - 0.507936507936508*G0_0_0_4_1_0_1_0_0 - 0.507936507936508*G0_0_0_4_1_0_2_0_1 + 0.507936507936508*G0_0_0_4_1_0_3_1_0 + 0.507936507936508*G0_0_0_4_1_0_3_1_1 - 0.507936507936508*G0_0_0_4_1_0_4_1_0 - 0.507936507936508*G0_0_0_4_1_0_5_1_1 + 0.507936507936508*G0_0_0_5_1_1_0_0_0 + 0.507936507936508*G0_0_0_5_1_1_0_0_1 - 0.507936507936508*G0_0_0_5_1_1_1_0_0 - 0.507936507936508*G0_0_0_5_1_1_2_0_1 + 0.507936507936508*G0_0_0_5_1_1_3_1_0 + 0.507936507936508*G0_0_0_5_1_1_3_1_1 - 0.507936507936508*G0_0_0_5_1_1_4_1_0 - 0.507936507936508*G0_0_0_5_1_1_5_1_1 + 0.507936507936511*G0_1_1_0_0_0_0_0_0 + 0.507936507936511*G0_1_1_0_0_0_0_0_1 - 0.507936507936511*G0_1_1_0_0_0_1_0_0 - 0.507936507936511*G0_1_1_0_0_0_2_0_1 + 0.507936507936511*G0_1_1_0_0_0_3_1_0 + 0.507936507936511*G0_1_1_0_0_0_3_1_1 - 0.507936507936511*G0_1_1_0_0_0_4_1_0 - 0.507936507936511*G0_1_1_0_0_0_5_1_1 + 0.507936507936511*G0_1_1_0_0_1_0_0_0 + 0.507936507936511*G0_1_1_0_0_1_0_0_1 - 0.507936507936511*G0_1_1_0_0_1_1_0_0 - 0.507936507936511*G0_1_1_0_0_1_2_0_1 + 0.507936507936511*G0_1_1_0_0_1_3_1_0 + 0.507936507936511*G0_1_1_0_0_1_3_1_1 - 0.507936507936511*G0_1_1_0_0_1_4_1_0 - 0.507936507936511*G0_1_1_0_0_1_5_1_1 - 0.507936507936511*G0_1_1_1_0_0_0_0_0 - 0.507936507936511*G0_1_1_1_0_0_0_0_1 + 0.507936507936511*G0_1_1_1_0_0_1_0_0 + 0.507936507936511*G0_1_1_1_0_0_2_0_1 - 0.507936507936511*G0_1_1_1_0_0_3_1_0 - 0.507936507936511*G0_1_1_1_0_0_3_1_1 + 0.507936507936511*G0_1_1_1_0_0_4_1_0 + 0.507936507936511*G0_1_1_1_0_0_5_1_1 - 0.507936507936511*G0_1_1_2_0_1_0_0_0 - 0.507936507936511*G0_1_1_2_0_1_0_0_1 + 0.507936507936511*G0_1_1_2_0_1_1_0_0 + 0.507936507936511*G0_1_1_2_0_1_2_0_1 - 0.507936507936511*G0_1_1_2_0_1_3_1_0 - 0.507936507936511*G0_1_1_2_0_1_3_1_1 + 0.507936507936511*G0_1_1_2_0_1_4_1_0 + 0.507936507936511*G0_1_1_2_0_1_5_1_1 + 0.507936507936511*G0_1_1_3_1_0_0_0_0 + 0.507936507936511*G0_1_1_3_1_0_0_0_1 - 0.507936507936511*G0_1_1_3_1_0_1_0_0 - 0.507936507936511*G0_1_1_3_1_0_2_0_1 + 0.507936507936511*G0_1_1_3_1_0_3_1_0 + 0.507936507936511*G0_1_1_3_1_0_3_1_1 - 0.507936507936511*G0_1_1_3_1_0_4_1_0 - 0.507936507936511*G0_1_1_3_1_0_5_1_1 + 0.507936507936511*G0_1_1_3_1_1_0_0_0 + 0.507936507936511*G0_1_1_3_1_1_0_0_1 - 0.507936507936511*G0_1_1_3_1_1_1_0_0 - 0.507936507936511*G0_1_1_3_1_1_2_0_1 + 0.507936507936511*G0_1_1_3_1_1_3_1_0 + 0.507936507936511*G0_1_1_3_1_1_3_1_1 - 0.507936507936511*G0_1_1_3_1_1_4_1_0 - 0.507936507936511*G0_1_1_3_1_1_5_1_1 - 0.507936507936511*G0_1_1_4_1_0_0_0_0 - 0.507936507936511*G0_1_1_4_1_0_0_0_1 + 0.507936507936511*G0_1_1_4_1_0_1_0_0 + 0.507936507936511*G0_1_1_4_1_0_2_0_1 - 0.507936507936511*G0_1_1_4_1_0_3_1_0 - 0.507936507936511*G0_1_1_4_1_0_3_1_1 + 0.507936507936511*G0_1_1_4_1_0_4_1_0 + 0.507936507936511*G0_1_1_4_1_0_5_1_1 - 0.507936507936511*G0_1_1_5_1_1_0_0_0 - 0.507936507936511*G0_1_1_5_1_1_0_0_1 + 0.507936507936511*G0_1_1_5_1_1_1_0_0 + 0.507936507936511*G0_1_1_5_1_1_2_0_1 - 0.507936507936511*G0_1_1_5_1_1_3_1_0 - 0.507936507936511*G0_1_1_5_1_1_3_1_1 + 0.507936507936511*G0_1_1_5_1_1_4_1_0 + 0.507936507936511*G0_1_1_5_1_1_5_1_1; + A[169] = 0.0; + A[629] = A[890]; + A[501] = A[181]; + A[204] = 0.0; + A[646] = A[181]; + A[570] = 0.0; + A[526] = A[61]; + A[239] = 0.0; + A[563] = A[98]; + A[241] = A[181]; + A[298] = 0.0; + A[447] = 0.0; + A[327] = 0.0; + A[468] = A[5]; + A[348] = 0.0; + A[29] = 0.0; + A[730] = 0.0; + A[381] = 0.0; + A[833] = A[252]; + A[54] = 0.0; + A[761] = 0.0; + A[414] = 0.0; + A[856] = A[421]; + A[780] = 0.0; + A[891] = A[658]; + A[823] = 0.0; + A[145] = 0.0; + A[854] = 0.0; + A[178] = 0.0; + A[885] = A[14]; + A[492] = 0.0; + A[199] = 0.0; + A[655] = A[306]; + A[579] = 0.0; + A[519] = 0.0; + A[236] = 0.0; + A[682] = A[217]; + A[602] = 0.0; + A[554] = 0.0; + A[713] = A[620]; + A[633] = 0.0; + A[248] = A[620]; + A[668] = 0.0; + A[275] = A[624]; + A[703] = 0.0; + A[302] = A[534]; + A[477] = A[14]; + A[341] = A[806]; + A[20] = 0.0; + A[737] = A[534]; + A[424] = A[134]; + A[372] = A[403]; + A[47] = 0.0; + A[762] = 0.0; + A[451] = 0.0; + A[407] = 0.0; + A[82] = 0.0; + A[791] = 0.0; + A[10] = A[475]; + A[97] = A[213]; + A[812] = 0.0; + A[41] = A[506]; + A[120] = A[5]; + A[845] = 0.0; + A[155] = A[620]; + A[878] = 0.0; + A[483] = 0.0; + A[190] = A[306]; + A[584] = 0.0; + A[512] = 0.0; + A[229] = 0.0; + A[609] = 0.0; + A[549] = 0.0; + A[505] = A[40]; + A[642] = 0.0; + A[255] = 0.0; + A[663] = 0.0; + A[284] = A[748]; + A[700] = 0.0; + A[313] = A[865]; + A[261] = 0.0; + A[330] = A[795]; + A[286] = 0.0; + A[744] = A[279]; + A[435] = 0.0; + A[371] = A[836]; + A[323] = 0.0; + A[771] = A[306]; + A[464] = 0.0; + A[400] = A[865]; + A[77] = 0.0; + A[798] = A[101]; + A[1] = A[466]; + A[102] = A[569]; + A[837] = A[403]; + A[42] = A[421]; + A[135] = 0.0; + A[868] = A[403]; + A[71] = A[534]; + A[164] = A[890]; + A[871] = 0.0; + A[108] = 0.0; + A[193] = A[658]; + A[141] = 0.0; + A[593] = A[709]; + A[218] = A[683]; + A[616] = A[151]; + A[540] = 0.0; + A[496] = A[31]; + A[651] = A[279]; + A[539] = A[887]; + A[686] = A[221]; + A[566] = A[101]; + A[693] = 0.0; + A[268] = 0.0; + A[295] = 0.0; + A[442] = 0.0; + A[362] = A[887]; + A[473] = A[8]; + A[393] = A[103]; + A[809] = A[836]; + A[24] = 0.0; + A[725] = 0.0; + A[384] = 0.0; + A[826] = A[421]; + A[35] = A[500]; + A[750] = 0.0; + A[419] = 0.0; + A[867] = A[373]; + A[62] = A[527]; + A[787] = 0.0; + A[896] = A[836]; + A[117] = 0.0; + A[184] = A[126]; + A[148] = 0.0; + A[598] = A[394]; + A[211] = A[181]; + A[167] = 0.0; + A[503] = A[181]; + A[572] = 0.0; + A[532] = A[67]; + A[689] = A[892]; + A[605] = 0.0; + A[561] = A[96]; + A[714] = A[743]; + A[243] = A[98]; + A[272] = A[534]; + A[445] = 0.0; + A[325] = 0.0; + A[478] = A[14]; + A[350] = 0.0; + A[732] = 0.0; + A[423] = A[569]; + A[383] = 0.0; + A[759] = 0.0; + A[412] = 0.0; + A[858] = A[103]; + A[89] = 0.0; + A[794] = 0.0; + A[889] = A[134]; + A[90] = A[5]; + A[825] = A[14]; + A[147] = 0.0; + A[848] = 0.0; + A[176] = 0.0; + A[883] = 0.0; + A[494] = 0.0; + A[197] = 0.0; + A[581] = 0.0; + A[525] = -A[61] + 0.0566137566137576*G0_1_1_0_0_0_0_0_0 + 0.0566137566137576*G0_1_1_0_0_0_0_0_1 - 0.0566137566137576*G0_1_1_0_0_0_1_0_0 - 0.0566137566137576*G0_1_1_0_0_0_2_0_1 + 0.0566137566137576*G0_1_1_0_0_0_3_1_0 + 0.0566137566137576*G0_1_1_0_0_0_3_1_1 - 0.0566137566137576*G0_1_1_0_0_0_4_1_0 - 0.0566137566137576*G0_1_1_0_0_0_5_1_1 + 0.0566137566137576*G0_1_1_0_0_1_0_0_0 + 0.0566137566137576*G0_1_1_0_0_1_0_0_1 - 0.0566137566137576*G0_1_1_0_0_1_1_0_0 - 0.0566137566137576*G0_1_1_0_0_1_2_0_1 + 0.0566137566137576*G0_1_1_0_0_1_3_1_0 + 0.0566137566137576*G0_1_1_0_0_1_3_1_1 - 0.0566137566137576*G0_1_1_0_0_1_4_1_0 - 0.0566137566137576*G0_1_1_0_0_1_5_1_1 - 0.0566137566137576*G0_1_1_1_0_0_0_0_0 - 0.0566137566137576*G0_1_1_1_0_0_0_0_1 + 0.0566137566137576*G0_1_1_1_0_0_1_0_0 + 0.0566137566137576*G0_1_1_1_0_0_2_0_1 - 0.0566137566137576*G0_1_1_1_0_0_3_1_0 - 0.0566137566137576*G0_1_1_1_0_0_3_1_1 + 0.0566137566137576*G0_1_1_1_0_0_4_1_0 + 0.0566137566137576*G0_1_1_1_0_0_5_1_1 - 0.0566137566137576*G0_1_1_2_0_1_0_0_0 - 0.0566137566137576*G0_1_1_2_0_1_0_0_1 + 0.0566137566137576*G0_1_1_2_0_1_1_0_0 + 0.0566137566137576*G0_1_1_2_0_1_2_0_1 - 0.0566137566137576*G0_1_1_2_0_1_3_1_0 - 0.0566137566137576*G0_1_1_2_0_1_3_1_1 + 0.0566137566137576*G0_1_1_2_0_1_4_1_0 + 0.0566137566137576*G0_1_1_2_0_1_5_1_1 + 0.0566137566137576*G0_1_1_3_1_0_0_0_0 + 0.0566137566137576*G0_1_1_3_1_0_0_0_1 - 0.0566137566137576*G0_1_1_3_1_0_1_0_0 - 0.0566137566137576*G0_1_1_3_1_0_2_0_1 + 0.0566137566137576*G0_1_1_3_1_0_3_1_0 + 0.0566137566137576*G0_1_1_3_1_0_3_1_1 - 0.0566137566137576*G0_1_1_3_1_0_4_1_0 - 0.0566137566137576*G0_1_1_3_1_0_5_1_1 + 0.0566137566137576*G0_1_1_3_1_1_0_0_0 + 0.0566137566137576*G0_1_1_3_1_1_0_0_1 - 0.0566137566137576*G0_1_1_3_1_1_1_0_0 - 0.0566137566137576*G0_1_1_3_1_1_2_0_1 + 0.0566137566137576*G0_1_1_3_1_1_3_1_0 + 0.0566137566137576*G0_1_1_3_1_1_3_1_1 - 0.0566137566137576*G0_1_1_3_1_1_4_1_0 - 0.0566137566137576*G0_1_1_3_1_1_5_1_1 - 0.0566137566137576*G0_1_1_4_1_0_0_0_0 - 0.0566137566137576*G0_1_1_4_1_0_0_0_1 + 0.0566137566137576*G0_1_1_4_1_0_1_0_0 + 0.0566137566137576*G0_1_1_4_1_0_2_0_1 - 0.0566137566137576*G0_1_1_4_1_0_3_1_0 - 0.0566137566137576*G0_1_1_4_1_0_3_1_1 + 0.0566137566137576*G0_1_1_4_1_0_4_1_0 + 0.0566137566137576*G0_1_1_4_1_0_5_1_1 - 0.0566137566137576*G0_1_1_5_1_1_0_0_0 - 0.0566137566137576*G0_1_1_5_1_1_0_0_1 + 0.0566137566137576*G0_1_1_5_1_1_1_0_0 + 0.0566137566137576*G0_1_1_5_1_1_2_0_1 - 0.0566137566137576*G0_1_1_5_1_1_3_1_0 - 0.0566137566137576*G0_1_1_5_1_1_3_1_1 + 0.0566137566137576*G0_1_1_5_1_1_4_1_0 + 0.0566137566137576*G0_1_1_5_1_1_5_1_1; + A[230] = 0.0; + A[680] = A[215]; + A[612] = 0.0; + A[552] = 0.0; + A[707] = A[242]; + A[631] = 0.0; + A[250] = A[715]; + A[674] = 0.0; + A[281] = -A[273] + 0.880423280423283*G0_0_0_0_0_0_0_0_0 + 0.880423280423283*G0_0_0_0_0_0_0_0_1 - 0.880423280423283*G0_0_0_0_0_0_1_0_0 - 0.880423280423283*G0_0_0_0_0_0_2_0_1 + 0.880423280423283*G0_0_0_0_0_0_3_1_0 + 0.880423280423283*G0_0_0_0_0_0_3_1_1 - 0.880423280423283*G0_0_0_0_0_0_4_1_0 - 0.880423280423283*G0_0_0_0_0_0_5_1_1 + 0.880423280423283*G0_0_0_0_0_1_0_0_0 + 0.880423280423283*G0_0_0_0_0_1_0_0_1 - 0.880423280423283*G0_0_0_0_0_1_1_0_0 - 0.880423280423283*G0_0_0_0_0_1_2_0_1 + 0.880423280423283*G0_0_0_0_0_1_3_1_0 + 0.880423280423283*G0_0_0_0_0_1_3_1_1 - 0.880423280423283*G0_0_0_0_0_1_4_1_0 - 0.880423280423283*G0_0_0_0_0_1_5_1_1 - 0.880423280423283*G0_0_0_1_0_0_0_0_0 - 0.880423280423283*G0_0_0_1_0_0_0_0_1 + 0.880423280423283*G0_0_0_1_0_0_1_0_0 + 0.880423280423283*G0_0_0_1_0_0_2_0_1 - 0.880423280423283*G0_0_0_1_0_0_3_1_0 - 0.880423280423283*G0_0_0_1_0_0_3_1_1 + 0.880423280423283*G0_0_0_1_0_0_4_1_0 + 0.880423280423283*G0_0_0_1_0_0_5_1_1 - 0.880423280423283*G0_0_0_2_0_1_0_0_0 - 0.880423280423283*G0_0_0_2_0_1_0_0_1 + 0.880423280423283*G0_0_0_2_0_1_1_0_0 + 0.880423280423283*G0_0_0_2_0_1_2_0_1 - 0.880423280423283*G0_0_0_2_0_1_3_1_0 - 0.880423280423283*G0_0_0_2_0_1_3_1_1 + 0.880423280423283*G0_0_0_2_0_1_4_1_0 + 0.880423280423283*G0_0_0_2_0_1_5_1_1 + 0.880423280423283*G0_0_0_3_1_0_0_0_0 + 0.880423280423283*G0_0_0_3_1_0_0_0_1 - 0.880423280423283*G0_0_0_3_1_0_1_0_0 - 0.880423280423283*G0_0_0_3_1_0_2_0_1 + 0.880423280423283*G0_0_0_3_1_0_3_1_0 + 0.880423280423283*G0_0_0_3_1_0_3_1_1 - 0.880423280423283*G0_0_0_3_1_0_4_1_0 - 0.880423280423283*G0_0_0_3_1_0_5_1_1 + 0.880423280423283*G0_0_0_3_1_1_0_0_0 + 0.880423280423283*G0_0_0_3_1_1_0_0_1 - 0.880423280423283*G0_0_0_3_1_1_1_0_0 - 0.880423280423283*G0_0_0_3_1_1_2_0_1 + 0.880423280423283*G0_0_0_3_1_1_3_1_0 + 0.880423280423283*G0_0_0_3_1_1_3_1_1 - 0.880423280423283*G0_0_0_3_1_1_4_1_0 - 0.880423280423283*G0_0_0_3_1_1_5_1_1 - 0.880423280423283*G0_0_0_4_1_0_0_0_0 - 0.880423280423283*G0_0_0_4_1_0_0_0_1 + 0.880423280423283*G0_0_0_4_1_0_1_0_0 + 0.880423280423283*G0_0_0_4_1_0_2_0_1 - 0.880423280423283*G0_0_0_4_1_0_3_1_0 - 0.880423280423283*G0_0_0_4_1_0_3_1_1 + 0.880423280423283*G0_0_0_4_1_0_4_1_0 + 0.880423280423283*G0_0_0_4_1_0_5_1_1 - 0.880423280423283*G0_0_0_5_1_1_0_0_0 - 0.880423280423283*G0_0_0_5_1_1_0_0_1 + 0.880423280423283*G0_0_0_5_1_1_1_0_0 + 0.880423280423283*G0_0_0_5_1_1_2_0_1 - 0.880423280423283*G0_0_0_5_1_1_3_1_0 - 0.880423280423283*G0_0_0_5_1_1_3_1_1 + 0.880423280423283*G0_0_0_5_1_1_4_1_0 + 0.880423280423283*G0_0_0_5_1_1_5_1_1 + 0.541798941798937*G0_1_0_0_0_0_0_0_0 + 0.541798941798937*G0_1_0_0_0_0_0_0_1 - 0.541798941798937*G0_1_0_0_0_0_1_0_0 - 0.541798941798937*G0_1_0_0_0_0_2_0_1 + 0.541798941798937*G0_1_0_0_0_0_3_1_0 + 0.541798941798937*G0_1_0_0_0_0_3_1_1 - 0.541798941798937*G0_1_0_0_0_0_4_1_0 - 0.541798941798937*G0_1_0_0_0_0_5_1_1 + 0.541798941798937*G0_1_0_0_0_1_0_0_0 + 0.541798941798937*G0_1_0_0_0_1_0_0_1 - 0.541798941798937*G0_1_0_0_0_1_1_0_0 - 0.541798941798937*G0_1_0_0_0_1_2_0_1 + 0.541798941798937*G0_1_0_0_0_1_3_1_0 + 0.541798941798937*G0_1_0_0_0_1_3_1_1 - 0.541798941798937*G0_1_0_0_0_1_4_1_0 - 0.541798941798937*G0_1_0_0_0_1_5_1_1 - 0.541798941798937*G0_1_0_1_0_0_0_0_0 - 0.541798941798937*G0_1_0_1_0_0_0_0_1 + 0.541798941798937*G0_1_0_1_0_0_1_0_0 + 0.541798941798937*G0_1_0_1_0_0_2_0_1 - 0.541798941798937*G0_1_0_1_0_0_3_1_0 - 0.541798941798937*G0_1_0_1_0_0_3_1_1 + 0.541798941798937*G0_1_0_1_0_0_4_1_0 + 0.541798941798937*G0_1_0_1_0_0_5_1_1 - 0.541798941798937*G0_1_0_2_0_1_0_0_0 - 0.541798941798937*G0_1_0_2_0_1_0_0_1 + 0.541798941798937*G0_1_0_2_0_1_1_0_0 + 0.541798941798937*G0_1_0_2_0_1_2_0_1 - 0.541798941798937*G0_1_0_2_0_1_3_1_0 - 0.541798941798937*G0_1_0_2_0_1_3_1_1 + 0.541798941798937*G0_1_0_2_0_1_4_1_0 + 0.541798941798937*G0_1_0_2_0_1_5_1_1 + 0.541798941798937*G0_1_0_3_1_0_0_0_0 + 0.541798941798937*G0_1_0_3_1_0_0_0_1 - 0.541798941798937*G0_1_0_3_1_0_1_0_0 - 0.541798941798937*G0_1_0_3_1_0_2_0_1 + 0.541798941798937*G0_1_0_3_1_0_3_1_0 + 0.541798941798937*G0_1_0_3_1_0_3_1_1 - 0.541798941798937*G0_1_0_3_1_0_4_1_0 - 0.541798941798937*G0_1_0_3_1_0_5_1_1 + 0.541798941798937*G0_1_0_3_1_1_0_0_0 + 0.541798941798937*G0_1_0_3_1_1_0_0_1 - 0.541798941798937*G0_1_0_3_1_1_1_0_0 - 0.541798941798937*G0_1_0_3_1_1_2_0_1 + 0.541798941798937*G0_1_0_3_1_1_3_1_0 + 0.541798941798937*G0_1_0_3_1_1_3_1_1 - 0.541798941798937*G0_1_0_3_1_1_4_1_0 - 0.541798941798937*G0_1_0_3_1_1_5_1_1 - 0.541798941798937*G0_1_0_4_1_0_0_0_0 - 0.541798941798937*G0_1_0_4_1_0_0_0_1 + 0.541798941798937*G0_1_0_4_1_0_1_0_0 + 0.541798941798937*G0_1_0_4_1_0_2_0_1 - 0.541798941798937*G0_1_0_4_1_0_3_1_0 - 0.541798941798937*G0_1_0_4_1_0_3_1_1 + 0.541798941798937*G0_1_0_4_1_0_4_1_0 + 0.541798941798937*G0_1_0_4_1_0_5_1_1 - 0.541798941798937*G0_1_0_5_1_1_0_0_0 - 0.541798941798937*G0_1_0_5_1_1_0_0_1 + 0.541798941798937*G0_1_0_5_1_1_1_0_0 + 0.541798941798937*G0_1_0_5_1_1_2_0_1 - 0.541798941798937*G0_1_0_5_1_1_3_1_0 - 0.541798941798937*G0_1_0_5_1_1_3_1_1 + 0.541798941798937*G0_1_0_5_1_1_4_1_0 + 0.541798941798937*G0_1_0_5_1_1_5_1_1; + A[705] = A[240]; + A[300] = A[765]; + A[256] = 0.0; + A[343] = A[401]; + A[22] = 0.0; + A[739] = A[274]; + A[430] = A[314]; + A[374] = A[897]; + A[53] = 0.0; + A[768] = A[303]; + A[453] = 0.0; + A[405] = 0.0; + A[80] = 0.0; + A[789] = 0.0; + A[12] = A[14]; + A[99] = A[273]; + A[814] = 0.0; + A[39] = A[504]; + A[122] = A[587]; + A[847] = 0.0; + A[74] = A[887]; + A[153] = -A[98] - 0.54179894179894*G0_1_0_0_0_0_0_0_0 - 0.54179894179894*G0_1_0_0_0_0_0_0_1 + 0.54179894179894*G0_1_0_0_0_0_1_0_0 + 0.54179894179894*G0_1_0_0_0_0_2_0_1 - 0.54179894179894*G0_1_0_0_0_0_3_1_0 - 0.54179894179894*G0_1_0_0_0_0_3_1_1 + 0.54179894179894*G0_1_0_0_0_0_4_1_0 + 0.54179894179894*G0_1_0_0_0_0_5_1_1 - 0.54179894179894*G0_1_0_0_0_1_0_0_0 - 0.54179894179894*G0_1_0_0_0_1_0_0_1 + 0.54179894179894*G0_1_0_0_0_1_1_0_0 + 0.54179894179894*G0_1_0_0_0_1_2_0_1 - 0.54179894179894*G0_1_0_0_0_1_3_1_0 - 0.54179894179894*G0_1_0_0_0_1_3_1_1 + 0.54179894179894*G0_1_0_0_0_1_4_1_0 + 0.54179894179894*G0_1_0_0_0_1_5_1_1 + 0.54179894179894*G0_1_0_1_0_0_0_0_0 + 0.54179894179894*G0_1_0_1_0_0_0_0_1 - 0.54179894179894*G0_1_0_1_0_0_1_0_0 - 0.54179894179894*G0_1_0_1_0_0_2_0_1 + 0.54179894179894*G0_1_0_1_0_0_3_1_0 + 0.54179894179894*G0_1_0_1_0_0_3_1_1 - 0.54179894179894*G0_1_0_1_0_0_4_1_0 - 0.54179894179894*G0_1_0_1_0_0_5_1_1 + 0.54179894179894*G0_1_0_2_0_1_0_0_0 + 0.54179894179894*G0_1_0_2_0_1_0_0_1 - 0.54179894179894*G0_1_0_2_0_1_1_0_0 - 0.54179894179894*G0_1_0_2_0_1_2_0_1 + 0.54179894179894*G0_1_0_2_0_1_3_1_0 + 0.54179894179894*G0_1_0_2_0_1_3_1_1 - 0.54179894179894*G0_1_0_2_0_1_4_1_0 - 0.54179894179894*G0_1_0_2_0_1_5_1_1 - 0.54179894179894*G0_1_0_3_1_0_0_0_0 - 0.54179894179894*G0_1_0_3_1_0_0_0_1 + 0.54179894179894*G0_1_0_3_1_0_1_0_0 + 0.54179894179894*G0_1_0_3_1_0_2_0_1 - 0.54179894179894*G0_1_0_3_1_0_3_1_0 - 0.54179894179894*G0_1_0_3_1_0_3_1_1 + 0.54179894179894*G0_1_0_3_1_0_4_1_0 + 0.54179894179894*G0_1_0_3_1_0_5_1_1 - 0.54179894179894*G0_1_0_3_1_1_0_0_0 - 0.54179894179894*G0_1_0_3_1_1_0_0_1 + 0.54179894179894*G0_1_0_3_1_1_1_0_0 + 0.54179894179894*G0_1_0_3_1_1_2_0_1 - 0.54179894179894*G0_1_0_3_1_1_3_1_0 - 0.54179894179894*G0_1_0_3_1_1_3_1_1 + 0.54179894179894*G0_1_0_3_1_1_4_1_0 + 0.54179894179894*G0_1_0_3_1_1_5_1_1 + 0.54179894179894*G0_1_0_4_1_0_0_0_0 + 0.54179894179894*G0_1_0_4_1_0_0_0_1 - 0.54179894179894*G0_1_0_4_1_0_1_0_0 - 0.54179894179894*G0_1_0_4_1_0_2_0_1 + 0.54179894179894*G0_1_0_4_1_0_3_1_0 + 0.54179894179894*G0_1_0_4_1_0_3_1_1 - 0.54179894179894*G0_1_0_4_1_0_4_1_0 - 0.54179894179894*G0_1_0_4_1_0_5_1_1 + 0.54179894179894*G0_1_0_5_1_1_0_0_0 + 0.54179894179894*G0_1_0_5_1_1_0_0_1 - 0.54179894179894*G0_1_0_5_1_1_1_0_0 - 0.54179894179894*G0_1_0_5_1_1_2_0_1 + 0.54179894179894*G0_1_0_5_1_1_3_1_0 + 0.54179894179894*G0_1_0_5_1_1_3_1_1 - 0.54179894179894*G0_1_0_5_1_1_4_1_0 - 0.54179894179894*G0_1_0_5_1_1_5_1_1 + 0.338624338624348*G0_1_1_0_0_0_0_0_0 + 0.338624338624348*G0_1_1_0_0_0_0_0_1 - 0.338624338624348*G0_1_1_0_0_0_1_0_0 - 0.338624338624348*G0_1_1_0_0_0_2_0_1 + 0.338624338624348*G0_1_1_0_0_0_3_1_0 + 0.338624338624348*G0_1_1_0_0_0_3_1_1 - 0.338624338624348*G0_1_1_0_0_0_4_1_0 - 0.338624338624348*G0_1_1_0_0_0_5_1_1 + 0.338624338624348*G0_1_1_0_0_1_0_0_0 + 0.338624338624348*G0_1_1_0_0_1_0_0_1 - 0.338624338624348*G0_1_1_0_0_1_1_0_0 - 0.338624338624348*G0_1_1_0_0_1_2_0_1 + 0.338624338624348*G0_1_1_0_0_1_3_1_0 + 0.338624338624348*G0_1_1_0_0_1_3_1_1 - 0.338624338624348*G0_1_1_0_0_1_4_1_0 - 0.338624338624348*G0_1_1_0_0_1_5_1_1 - 0.338624338624348*G0_1_1_1_0_0_0_0_0 - 0.338624338624348*G0_1_1_1_0_0_0_0_1 + 0.338624338624348*G0_1_1_1_0_0_1_0_0 + 0.338624338624348*G0_1_1_1_0_0_2_0_1 - 0.338624338624348*G0_1_1_1_0_0_3_1_0 - 0.338624338624348*G0_1_1_1_0_0_3_1_1 + 0.338624338624348*G0_1_1_1_0_0_4_1_0 + 0.338624338624348*G0_1_1_1_0_0_5_1_1 - 0.338624338624348*G0_1_1_2_0_1_0_0_0 - 0.338624338624348*G0_1_1_2_0_1_0_0_1 + 0.338624338624348*G0_1_1_2_0_1_1_0_0 + 0.338624338624348*G0_1_1_2_0_1_2_0_1 - 0.338624338624348*G0_1_1_2_0_1_3_1_0 - 0.338624338624348*G0_1_1_2_0_1_3_1_1 + 0.338624338624348*G0_1_1_2_0_1_4_1_0 + 0.338624338624348*G0_1_1_2_0_1_5_1_1 + 0.338624338624348*G0_1_1_3_1_0_0_0_0 + 0.338624338624348*G0_1_1_3_1_0_0_0_1 - 0.338624338624348*G0_1_1_3_1_0_1_0_0 - 0.338624338624348*G0_1_1_3_1_0_2_0_1 + 0.338624338624348*G0_1_1_3_1_0_3_1_0 + 0.338624338624348*G0_1_1_3_1_0_3_1_1 - 0.338624338624348*G0_1_1_3_1_0_4_1_0 - 0.338624338624348*G0_1_1_3_1_0_5_1_1 + 0.338624338624348*G0_1_1_3_1_1_0_0_0 + 0.338624338624348*G0_1_1_3_1_1_0_0_1 - 0.338624338624348*G0_1_1_3_1_1_1_0_0 - 0.338624338624348*G0_1_1_3_1_1_2_0_1 + 0.338624338624348*G0_1_1_3_1_1_3_1_0 + 0.338624338624348*G0_1_1_3_1_1_3_1_1 - 0.338624338624348*G0_1_1_3_1_1_4_1_0 - 0.338624338624348*G0_1_1_3_1_1_5_1_1 - 0.338624338624348*G0_1_1_4_1_0_0_0_0 - 0.338624338624348*G0_1_1_4_1_0_0_0_1 + 0.338624338624348*G0_1_1_4_1_0_1_0_0 + 0.338624338624348*G0_1_1_4_1_0_2_0_1 - 0.338624338624348*G0_1_1_4_1_0_3_1_0 - 0.338624338624348*G0_1_1_4_1_0_3_1_1 + 0.338624338624348*G0_1_1_4_1_0_4_1_0 + 0.338624338624348*G0_1_1_4_1_0_5_1_1 - 0.338624338624348*G0_1_1_5_1_1_0_0_0 - 0.338624338624348*G0_1_1_5_1_1_0_0_1 + 0.338624338624348*G0_1_1_5_1_1_1_0_0 + 0.338624338624348*G0_1_1_5_1_1_2_0_1 - 0.338624338624348*G0_1_1_5_1_1_3_1_0 - 0.338624338624348*G0_1_1_5_1_1_3_1_1 + 0.338624338624348*G0_1_1_5_1_1_4_1_0 + 0.338624338624348*G0_1_1_5_1_1_5_1_1; + A[876] = 0.0; + A[485] = 0.0; + A[188] = A[653]; + A[586] = A[121]; + A[510] = 0.0; + A[223] = A[688]; + A[611] = 0.0; + A[547] = 0.0; + A[507] = A[421]; + A[640] = 0.0; + A[536] = A[534]; + A[661] = 0.0; + A[282] = A[834]; + A[694] = 0.0; + A[311] = A[776]; + A[263] = 0.0; + A[332] = A[534]; + A[292] = 0.0; + A[746] = A[281]; + A[433] = A[869]; + A[365] = A[628]; + A[321] = 0.0; + A[777] = A[312]; + A[458] = 0.0; + A[398] = A[252]; + A[354] = 0.0; + A[796] = A[331]; + A[3] = A[5]; + A[720] = 0.0; + A[104] = A[569]; + A[839] = A[897]; + A[32] = A[497]; + A[129] = A[274]; + A[69] = A[534]; + A[162] = A[628]; + A[110] = 0.0; + A[183] = A[96]; + A[143] = 0.0; + A[595] = A[769]; + A[220] = A[307]; + A[172] = 0.0; + A[618] = A[153]; + A[498] = A[33]; + A[649] = A[126]; + A[529] = A[64]; + A[684] = A[219]; + A[564] = A[273]; + A[719] = A[428]; + A[440] = 0.0; + A[328] = 0.0; + A[778] = A[865]; + A[467] = A[2]; + A[391] = A[421]; + A[347] = 0.0; + A[807] = A[836]; + A[26] = 0.0; + A[727] = 0.0; + A[386] = 0.0; + A[828] = A[569]; + A[57] = 0.0; + A[756] = 0.0; + A[417] = 0.0; + A[861] = A[658]; + A[60] = A[525]; + A[785] = 0.0; + A[894] = A[748]; + A[119] = 0.0; + A[818] = 0.0; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f2_p1_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f2_p1_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p1_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 4, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), Product(IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 2; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q4_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p1_q4_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p1_q4_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f2_p2_q1_excafe.h b/vector_laplacian_2d/vector_laplacian_f2_p2_q1_excafe.h new file mode 100644 index 0000000..c0d7384 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p2_q1_excafe.h @@ -0,0 +1,309 @@ +#include +#include +#include + +// Common sub-expression elimination pass took 5 minutes and 42.41 seconds (wall clock). + +class ExcafeCellIntegral_0 : public ufc::cell_integral +{ +public: + void tabulate_tensor(double* const A, const double* const* w, const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + const double var_0 = w[0][10]*w[1][4] + w[0][9]*w[1][3] + w[0][11]*w[1][5] + w[0][5]*w[1][11] + w[0][3]*w[1][9] + w[0][4]*w[1][10]; + const double var_1 = w[0][10]*w[1][5] + w[0][5]*w[1][10] + w[0][4]*w[1][11] + w[0][11]*w[1][4]; + const double var_2 = 2.0000000000000000000000000*var_0 + var_1; + const double var_3 = -x[0][1]; + const double var_4 = x[1][1] + var_3; + const double var_5 = -x[0][0]; + const double var_6 = x[2][0] + var_5; + const double var_7 = var_6*w[1][7]; + const double var_8 = var_4*w[1][2] + var_7; + const double var_9 = var_6*w[0][7]; + const double var_10 = var_4*w[0][2] + var_9; + const double var_11 = var_8*w[0][6] + var_10*w[1][6]; + const double var_12 = x[2][1] + var_3; + const double var_13 = x[1][0] + var_5; + const double var_14 = var_13*w[1][8]; + const double var_15 = var_12*w[1][1] + var_14; + const double var_16 = var_13*w[0][8]; + const double var_17 = var_12*w[0][1] + var_16; + const double var_18 = var_17*w[1][6] + var_15*w[0][6]; + const double var_19 = -var_18 + var_11; + const double var_20 = -var_4 + var_12; + const double var_21 = w[0][1] + w[0][0]; + const double var_22 = w[0][3]*w[1][4] + w[0][4]*w[1][3]; + const double var_23 = w[1][0] + w[1][1]; + const double var_24 = 2.0000000000000000000000000*var_22 + var_21*w[1][5] + var_23*w[0][5]; + const double var_25 = w[0][0]*w[1][10] + w[0][10]*w[1][0] + w[0][8]*w[1][4] + w[0][4]*w[1][8]; + const double var_26 = var_12*var_24 + var_13*var_25; + const double var_27 = var_4*w[1][4] + var_6*w[1][11]; + const double var_28 = var_4*w[0][4] + var_6*w[0][11]; + const double var_29 = w[0][5]*w[1][3] + w[0][3]*w[1][5]; + const double var_30 = w[0][2]*w[1][4] + w[0][4]*w[1][2] + 2.0000000000000000000000000*var_29; + const double var_31 = w[0][5]*w[1][7] + w[0][7]*w[1][5]; + const double var_32 = var_30*var_4 + var_27*w[0][0] + var_28*w[1][0] + var_31*var_6; + const double var_33 = -var_26 + var_32; + const double var_34 = w[0][6]*w[1][0] + w[0][0]*w[1][6]; + const double var_35 = 0.5000000000000000000000000*var_34; + const double var_36 = 1.3333333333333332593184650*var_0 + var_35; + const double var_37 = -var_36; + const double var_38 = w[0][1] + w[0][2]; + const double var_39 = w[1][7] + w[1][8]; + const double var_40 = w[0][10]*w[1][11] + w[0][11]*w[1][10]; + const double var_41 = w[0][8] + w[0][7]; + const double var_42 = 2.0000000000000000000000000*var_40 + var_39*w[0][9] + var_41*w[1][9]; + const double var_43 = w[1][2] + w[1][1]; + const double var_44 = w[0][5]*w[1][4] + w[0][4]*w[1][5]; + const double var_45 = var_38*w[1][3] + var_43*w[0][3] + 2.0000000000000000000000000*var_44; + const double var_46 = var_13*var_42*var_6 + var_12*var_4*var_45; + const double var_47 = 0.3333333333333333148296163*var_13*w[0][8] + var_9; + const double var_48 = 0.3333333333333333148296163*var_13*w[1][8] + var_7; + const double var_49 = var_47*w[1][1] + var_48*w[0][1]; + const double var_50 = 0.3333333333333333148296163*var_6*w[0][7] + var_16; + const double var_51 = 0.3333333333333333148296163*var_6*w[1][7] + var_14; + const double var_52 = var_50*w[1][2] + var_51*w[0][2]; + const double var_53 = var_12*var_49 + var_4*var_52; + const double var_54 = 0.6666666666666666296592325*var_46 + 0.5000000000000000000000000*var_53; + const double var_55 = var_13*var_50*w[1][8] + var_4*var_4*w[0][2]*w[1][2] + var_47*var_6*w[1][7]; + const double var_56 = w[0][9]*w[1][2] + w[0][3]*w[1][7] + w[0][2]*w[1][9] + w[0][7]*w[1][3]; + const double var_57 = w[0][8]*w[1][3] + w[0][1]*w[1][9] + w[0][3]*w[1][8] + w[0][9]*w[1][1]; + const double var_58 = w[0][2]*w[1][1] + w[0][1]*w[1][2]; + const double var_59 = var_12*w[0][1]*w[1][1]; + const double var_60 = 0.6666666666666666296592325*var_13*var_57 + 0.5000000000000000000000000*var_59 + 0.1666666666666666574148081*var_4*var_58; + const double var_61 = 0.6666666666666666296592325*var_4*var_56*var_6 + 0.5000000000000000000000000*var_55 + var_12*var_60; + const double var_62 = -var_61 + var_54; + A[19] = 0.0000000000000000000000000; + const double var_63 = -var_13; + const double var_64 = var_6 + var_63; + const double var_65 = w[0][3]*w[1][3] + w[0][5]*w[1][5] + w[0][4]*w[1][4]; + const double var_66 = 1.3333333333333332593184650*var_65; + const double var_67 = 0.5000000000000000000000000*w[0][0]*w[1][0] + var_66; + const double var_68 = w[0][10]*w[1][3] + w[0][3]*w[1][10] + w[0][4]*w[1][9] + w[0][9]*w[1][4]; + const double var_69 = -var_68; + const double var_70 = var_1 + var_69; + const double var_71 = var_26 + -var_32; + const double var_72 = var_8*w[0][0] + var_10*w[1][0]; + const double var_73 = var_15*w[0][0] + var_17*w[1][0]; + const double var_74 = var_72 + -var_73; + const double var_75 = 2.0000000000000000000000000*var_71 + 0.5000000000000000000000000*var_74; + const double var_76 = 0.3333333333333333148296163*var_75; + const double var_77 = 0.6666666666666666296592325*var_6*var_70 + var_76; + const double var_78 = w[0][11]*w[1][3] + w[0][5]*w[1][9] + w[0][3]*w[1][11] + w[0][9]*w[1][5]; + const double var_79 = -var_0; + const double var_80 = var_78 + var_79; + const double var_81 = 0.5000000000000000000000000*var_34*var_64 + 1.3333333333333332593184650*var_13*var_80 + var_4*var_67 + var_77; + const double var_82 = var_12*var_13 + -var_4*var_6; + const double var_83 = var_82; + const double var_84 = std::abs(var_83); + const double var_85 = var_82; + const double var_86 = var_4*var_4; + const double var_87 = var_12*var_12; + const double var_88 = var_86 + var_87; + const double var_89 = -var_72 + var_73; + const double var_90 = 0.5000000000000000000000000*var_89 + 2.0000000000000000000000000*var_33; + const double var_91 = 0.3333333333333333148296163*var_90; + const double var_92 = -var_54 + var_61; + const double var_93 = -var_11 + var_18; + const double var_94 = w[0][10]*w[1][9] + w[0][9]*w[1][10]; + const double var_95 = w[0][7]*w[1][11] + w[0][11]*w[1][7] + 2.0000000000000000000000000*var_94; + const double var_96 = w[0][2]*w[1][10] + w[0][10]*w[1][2]; + const double var_97 = var_6*var_95 + var_27*w[0][6] + var_28*w[1][6] + var_4*var_96; + const double var_98 = w[0][1]*w[1][11] + w[0][6]*w[1][5] + w[0][5]*w[1][6] + w[0][11]*w[1][1]; + const double var_99 = w[0][8] + w[0][6]; + const double var_100 = w[0][9]*w[1][11] + w[0][11]*w[1][9]; + const double var_101 = w[1][8] + w[1][6]; + const double var_102 = 2.0000000000000000000000000*var_100 + var_101*w[0][10] + var_99*w[1][10]; + const double var_103 = var_102*var_13; + const double var_104 = var_12*var_98 + var_103; + const double var_105 = -var_104 + var_97; + const double var_106 = var_12*var_70 + var_105; + const double var_107 = w[0][10]*w[1][10] + w[0][9]*w[1][9] + w[0][11]*w[1][11]; + const double var_108 = 1.3333333333333332593184650*var_107; + const double var_109 = 0.5000000000000000000000000*w[0][6]*w[1][6] + var_108; + const double var_110 = var_109*var_13; + const double var_111 = 0.1666666666666666574148081*var_93 + 0.6666666666666666296592325*var_106 + var_110; + const double var_112 = var_92 + var_111*var_13; + const double var_113 = -var_78; + const double var_114 = var_0 + var_113; + const double var_115 = 0.6666666666666666296592325*var_114 + var_35; + const double var_116 = var_112 + var_115*var_12*var_13; + const double var_117 = w[0][0]*w[1][0]; + const double var_118 = var_117 + var_66; + const double var_119 = 1.3333333333333332593184650*var_78 + var_37; + const double var_120 = var_77 + -var_118*var_12 + var_119*var_13; + const double var_121 = var_116 + var_67*var_88 + var_12*var_91 + var_120*var_4; + const double var_122 = 0.5000000000000000000000000*var_6 + var_63; + const double var_123 = -var_97; + const double var_124 = var_123 + var_104; + const double var_125 = 0.5000000000000000000000000*var_19 + 2.0000000000000000000000000*var_124; + const double var_126 = 0.3333333333333333148296163*var_125; + const double var_127 = 1.3333333333333332593184650*var_107*var_64 + var_126; + const double var_128 = var_122*w[0][6]*w[1][6] + 0.6666666666666666296592325*var_114*var_4 + var_127; + const double var_129 = 1.3333333333333332593184650*var_68 + var_37; + const double var_130 = var_128 + 0.5000000000000000000000000*var_34*var_4 + var_12*var_129; + const double var_131 = var_121 + var_130*var_6; + const double var_132 = var_6*var_6 + var_87; + A[7] = var_131*var_132*var_84/(var_85*var_85*var_85*var_85); + A[28] = A[7]; + const double var_133 = 1.3333333333333332593184650*var_46 + -var_55; + const double var_134 = w[0][6]*w[1][6]; + const double var_135 = var_134 + var_108; + const double var_136 = 2.6666666666666665186369300*var_65; + const double var_137 = var_117 + var_135 + var_136; + const double var_138 = 0.3333333333333333148296163*var_74 + 1.3333333333333332593184650*var_71; + const double var_139 = -var_12*var_137 + var_138; + const double var_140 = w[0][6]*w[1][8] + w[0][8]*w[1][6]; + const double var_141 = var_103 + var_123; + const double var_142 = 8.0000000000000000000000000*var_107*var_64 + -var_13*var_140 + var_11 + 4.0000000000000000000000000*var_141; + const double var_143 = var_13*var_6 + var_12*var_4; + const double var_144 = var_13*var_13 + var_86; + const double var_145 = 1.3333333333333332593184650*var_6*var_68 + var_12*var_67; + const double var_146 = var_91 + -var_36*var_6 + var_145; + const double var_147 = var_109*var_6 + var_126; + const double var_148 = var_1 + var_113; + const double var_149 = -var_6*var_78 + var_1*var_64; + const double var_150 = var_149*var_4 + var_12*var_13*var_148; + const double var_151 = var_12*var_146 + var_92 + var_147*var_6 + 0.6666666666666666296592325*var_150; + const double var_152 = var_0 + var_69; + const double var_153 = 2.0000000000000000000000000*var_152 + var_34; + const double var_154 = -2.0000000000000000000000000*var_107*var_6 + var_105; + const double var_155 = 2.0000000000000000000000000*var_154 + 0.5000000000000000000000000*var_93; + const double var_156 = 0.3333333333333333148296163*var_155; + const double var_157 = var_156 + -0.5000000000000000000000000*var_6*w[0][6]*w[1][6]; + const double var_158 = var_62 + var_157*var_6; + const double var_159 = -var_1; + const double var_160 = var_68 + var_80 + var_159; + const double var_161 = -var_35 + 0.6666666666666666296592325*var_160; + const double var_162 = var_91 + var_161*var_6 + -var_4*var_67; + const double var_163 = var_158 + var_162*var_4; + const double var_164 = 1.5000000000000000000000000*w[0][0]*w[1][0] + var_136; + const double var_165 = -var_12 + var_4; + const double var_166 = var_138 + var_164*var_165; + const double var_167 = var_12*var_166 + var_163; + const double var_168 = var_118 + var_134; + const double var_169 = -var_168*var_6; + const double var_170 = var_110 + var_169 + var_156; + const double var_171 = -var_34; + const double var_172 = 2.0000000000000000000000000*var_80 + 0.6666666666666666296592325*var_68 + var_171; + const double var_173 = var_6 + -0.5000000000000000000000000*var_13; + const double var_174 = var_127 + var_173*w[0][6]*w[1][6]; + const double var_175 = 1.3333333333333332593184650*var_114 + var_35; + const double var_176 = var_175*var_4; + const double var_177 = var_176 + var_64*var_67 + var_174; + const double var_178 = var_35 + 0.6666666666666666296592325*var_152; + const double var_179 = var_177*var_4 + var_132*var_178 + var_13*var_91 + var_143*var_172 + var_12*var_170 + var_6*var_76; + const double var_180 = var_12*var_161; + const double var_181 = var_176 + var_180 + var_126 + -var_109*var_13; + const double var_182 = var_76 + var_118*var_4 + -var_12*var_67; + const double var_183 = var_13*var_181 + var_12*var_182; + const double var_184 = 2.6666666666666665186369300*var_107*var_13*var_6; + const double var_185 = 1.3333333333333332593184650*var_154 + 0.3333333333333333148296163*var_93; + const double var_186 = -var_6 + var_13; + const double var_187 = var_185 + 1.5000000000000000000000000*var_186*w[0][6]*w[1][6]; + const double var_188 = var_183 + var_62 + var_184 + var_187*var_6; + const double var_189 = var_13*var_188 + var_179*var_4; + const double var_190 = var_167*var_4*var_4 + var_143*var_151 + var_13*var_189 + var_12*var_144*var_153*var_6; + A[2] = var_190*var_84/(var_85*var_85*var_85*var_85); + const double var_191 = 1.3333333333333332593184650*var_143*var_2; + const double var_192 = -2.6666666666666665186369300*var_13*var_65 + var_122*w[0][0]*w[1][0]; + const double var_193 = var_115*var_6 + var_77; + const double var_194 = w[0][2]*w[1][7] + -4.0000000000000000000000000*var_56 + w[0][7]*w[1][2]; + const double var_195 = 4.0000000000000000000000000*var_33 + var_89; + const double var_196 = var_13*var_195 + var_143*var_194; + const double var_197 = -1.5000000000000000000000000*var_143*var_34 + -var_191 + var_193*var_6 + var_192*var_4 + 0.3333333333333333148296163*var_196; + const double var_198 = 3.0000000000000000000000000*w[0][0]*w[1][0] + 5.3333333333333330372738601*var_65; + const double var_199 = 2.0000000000000000000000000*var_65 + var_117; + const double var_200 = var_79 + var_68; + const double var_201 = w[0][2]*w[1][8] + 1.5000000000000000000000000*var_34 + w[0][8]*w[1][2] + 3.3333333333333330372738601*var_114; + const double var_202 = var_128 + 1.3333333333333332593184650*var_6*var_65; + const double var_203 = var_4*var_81 + var_112 + var_202*var_6; + const double var_204 = 2.0000000000000000000000000*var_114 + var_34; + const double var_205 = 0.3333333333333333148296163*var_195 + var_13*var_204 + var_164*var_20; + const double var_206 = var_180 + var_174; + const double var_207 = var_205*var_4 + var_158 + var_13*var_206; + const double var_208 = var_159 + var_78; + const double var_209 = 2.0000000000000000000000000*var_200 + 0.6666666666666666296592325*var_208 + var_171; + const double var_210 = -w[0][1]*w[1][6] + -w[0][6]*w[1][1] + 4.0000000000000000000000000*var_98; + const double var_211 = 0.3333333333333333148296163*var_13*var_210; + const double var_212 = var_4*w[0][0]*w[1][0] + var_211; + const double var_213 = var_132*var_36 + var_143*var_209 + var_212*var_6; + const double var_214 = var_76 + -var_145; + const double var_215 = var_213*var_6 + var_203*var_4 + var_12*var_207 + var_132*var_214; + const double var_216 = 1.5000000000000000000000000*var_64*w[0][6]*w[1][6] + var_204*var_4 + 0.3333333333333333148296163*var_142; + const double var_217 = var_216*var_6 + var_121; + const double var_218 = var_163*var_6 + var_13*var_217; + const double var_219 = var_12*var_215 + var_218*var_6; + A[1] = var_219*var_84/(var_85*var_85*var_85*var_85); + A[22] = A[1]; + A[27] = A[1]; + const double var_220 = -var_13*var_13*w[0][6]*w[1][6]; + const double var_221 = var_211 + var_75 + var_198*var_4; + const double var_222 = 2.0000000000000000000000000*var_13*var_168 + var_185 + var_169; + const double var_223 = var_13*var_142 + -var_143*var_58; + const double var_224 = -2.0000000000000000000000000*var_199*var_88 + var_12*var_221 + var_220 + var_4*var_90 + var_222*var_6 + 0.3333333333333333148296163*var_223; + const double var_225 = 2.0000000000000000000000000*var_68 + var_78; + const double var_226 = 5.0000000000000000000000000*var_152 + var_148; + const double var_227 = var_13*var_139 + 1.3333333333333332593184650*var_144*var_225 + 0.6666666666666666296592325*var_143*var_226; + const double var_228 = var_49 + 1.5000000000000000000000000*var_34*var_64 + -1.3333333333333332593184650*var_13*var_57 + -var_59; + const double var_229 = var_116*var_12 + -var_13*var_191 + var_143*var_228 + var_227*var_6 + var_224*var_4 + var_132*var_146; + const double var_230 = var_184 + var_220; + const double var_231 = 3.0000000000000000000000000*var_13 + -2.0000000000000000000000000*var_6; + const double var_232 = var_155 + var_231*w[0][6]*w[1][6]; + const double var_233 = -4.0000000000000000000000000*var_107*var_13 + var_125; + const double var_234 = var_232*var_6 + 2.0000000000000000000000000*var_230 + var_13*var_233; + const double var_235 = var_13*var_234 + var_6*var_92 + var_132*var_147 + var_197*var_4; + const double var_236 = 2.0000000000000000000000000*var_78 + var_68; + const double var_237 = var_143*var_201 + 1.3333333333333332593184650*var_132*var_236; + const double var_238 = var_237*var_4 + var_121*var_13; + const double var_239 = var_13*var_238 + var_12*var_229 + var_203*var_4*var_4 + var_235*var_6 + var_133*var_143; + A[31] = 0.0000000000000000000000000; + const double var_240 = var_36 + -1.3333333333333332593184650*var_68; + const double var_241 = var_12*var_240 + var_13*var_135; + const double var_242 = var_163 + var_183 + var_241*var_6; + A[8] = var_143*var_242*var_84/(var_85*var_85*var_85*var_85); + A[34] = A[8]; + A[16] = 0.0000000000000000000000000; + A[6] = A[1]; + A[15] = 0.0000000000000000000000000; + A[0] = var_239*var_84/(var_85*var_85*var_85*var_85); + A[26] = 0.0000000000000000000000000; + A[30] = 0.0000000000000000000000000; + A[25] = 0.0000000000000000000000000; + A[5] = 0.0000000000000000000000000; + A[10] = 0.0000000000000000000000000; + A[21] = A[0]; + A[12] = A[2]; + A[13] = A[8]; + A[9] = 0.0000000000000000000000000; + A[32] = 0.0000000000000000000000000; + A[14] = var_131*var_144*var_84/(var_85*var_85*var_85*var_85); + A[35] = A[14]; + A[4] = 0.0000000000000000000000000; + A[11] = 0.0000000000000000000000000; + A[24] = 0.0000000000000000000000000; + A[29] = A[8]; + A[3] = 0.0000000000000000000000000; + A[20] = 0.0000000000000000000000000; + A[17] = 0.0000000000000000000000000; + A[23] = A[2]; + A[18] = 0.0000000000000000000000000; + A[33] = A[2]; + } + + void tabulate_tensor(double* const A, + const double* const* w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double* const* quadrature_points, + const double* quadrature_weights) const + { + assert(0 && "This function is not implemented!"); + } +}; + +extern "C" ufc::cell_integral* newExcafeCellIntegral_0() +{ + return new ExcafeCellIntegral_0(); +} diff --git a/vector_laplacian_2d/vector_laplacian_f2_p2_q1_quadrature.h b/vector_laplacian_2d/vector_laplacian_f2_p2_q1_quadrature.h new file mode 100644 index 0000000..5877739 --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p2_q1_quadrature.h @@ -0,0 +1,8500 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'quadrature' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F2_P2_Q1_QUADRATURE_H +#define __VECTOR_LAPLACIAN_F2_P2_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p2_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_quadrature_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p2_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_quadrature_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p2_q1_quadrature_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_quadrature_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_quadrature_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p2_q1_quadrature_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_quadrature_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_quadrature_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p2_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p2_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_quadrature_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p2_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p2_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_quadrature_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p2_q1_quadrature_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p2_q1_quadrature_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_quadrature_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p2_q1_quadrature_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p2_q1_quadrature_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_quadrature_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f2_p2_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_quadrature_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Facet Area. + + // Array of quadrature weights. + static const double W3[3] = {0.166666666666667, 0.166666666666667, 0.166666666666667}; + // Quadrature points on the UFC reference element: (0.166666666666667, 0.166666666666667), (0.166666666666667, 0.666666666666667), (0.666666666666667, 0.166666666666667) + + // Value of basis functions at quadrature points. + static const double FE0_C0_D01[3][2] = \ + {{-1.0, 1.0}, + {-1.0, 1.0}, + {-1.0, 1.0}}; + + // Array of non-zero columns + static const unsigned int nzc4[2] = {3, 5}; + + // Array of non-zero columns + static const unsigned int nzc5[2] = {3, 4}; + + // Array of non-zero columns + static const unsigned int nzc2[2] = {0, 1}; + + // Array of non-zero columns + static const unsigned int nzc1[2] = {0, 2}; + + static const double FE1_C0_D01[3][5] = \ + {{-1.66666666666667, -0.333333333333333, 0.666666666666666, 2.0, -0.666666666666666}, + {0.333333333333333, 1.66666666666667, 0.666666666666666, -2, -0.666666666666666}, + {0.333333333333333, -0.333333333333333, 2.66666666666666, 0.0, -2.66666666666667}}; + + // Array of non-zero columns + static const unsigned int nzc10[5] = {6, 8, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc7[5] = {0, 2, 3, 4, 5}; + + static const double FE1_C0_D10[3][5] = \ + {{-1.66666666666667, -0.333333333333334, 0.666666666666666, -0.666666666666666, 2.0}, + {0.333333333333334, -0.333333333333334, 2.66666666666667, -2.66666666666667, 0.0}, + {0.333333333333333, 1.66666666666667, 0.666666666666666, -0.666666666666666, -2.0}}; + + // Array of non-zero columns + static const unsigned int nzc11[5] = {6, 7, 9, 10, 11}; + + // Array of non-zero columns + static const unsigned int nzc8[5] = {0, 1, 3, 4, 5}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + // Number of operations to compute geometry constants: 180. + double G[30]; + G[0] = K_00*K_00*det*(K_10*K_10 + K_11*K_11); + G[1] = K_00*K_10*det*(K_10*K_10 + K_11*K_11); + G[2] = K_00*K_01*det*(K_10*K_10 + K_11*K_11); + G[3] = K_00*K_11*det*(K_10*K_10 + K_11*K_11); + G[4] = K_10*K_10*det*(K_10*K_10 + K_11*K_11); + G[5] = K_01*K_10*det*(K_10*K_10 + K_11*K_11); + G[6] = K_10*K_11*det*(K_10*K_10 + K_11*K_11); + G[7] = K_01*K_01*det*(K_10*K_10 + K_11*K_11); + G[8] = K_01*K_11*det*(K_10*K_10 + K_11*K_11); + G[9] = K_11*K_11*det*(K_10*K_10 + K_11*K_11); + G[10] = K_00*K_00*det*(K_00*K_10 + K_01*K_11); + G[11] = K_00*K_10*det*(K_00*K_10 + K_01*K_11); + G[12] = K_00*K_01*det*(K_00*K_10 + K_01*K_11); + G[13] = K_00*K_11*det*(K_00*K_10 + K_01*K_11); + G[14] = K_10*K_10*det*(K_00*K_10 + K_01*K_11); + G[15] = K_01*K_10*det*(K_00*K_10 + K_01*K_11); + G[16] = K_10*K_11*det*(K_00*K_10 + K_01*K_11); + G[17] = K_01*K_01*det*(K_00*K_10 + K_01*K_11); + G[18] = K_01*K_11*det*(K_00*K_10 + K_01*K_11); + G[19] = K_11*K_11*det*(K_00*K_10 + K_01*K_11); + G[20] = K_00*K_00*det*(K_00*K_00 + K_01*K_01); + G[21] = K_00*K_10*det*(K_00*K_00 + K_01*K_01); + G[22] = K_00*K_01*det*(K_00*K_00 + K_01*K_01); + G[23] = K_00*K_11*det*(K_00*K_00 + K_01*K_01); + G[24] = K_10*K_10*det*(K_00*K_00 + K_01*K_01); + G[25] = K_01*K_10*det*(K_00*K_00 + K_01*K_01); + G[26] = K_10*K_11*det*(K_00*K_00 + K_01*K_01); + G[27] = K_01*K_01*det*(K_00*K_00 + K_01*K_01); + G[28] = K_01*K_11*det*(K_00*K_00 + K_01*K_01); + G[29] = K_11*K_11*det*(K_00*K_00 + K_01*K_01); + + // Compute element tensor using UFL quadrature representation + // Optimisations: ('eliminate zeros', True), ('ignore ones', True), ('ignore zero tables', True), ('optimisation', 'simplify_expressions'), ('remove zero terms', True) + + // Loop quadrature points for integral. + // Number of operations to compute element tensor for following IP loop = 852 + for (unsigned int ip = 0; ip < 3; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + double F3 = 0.0; + double F4 = 0.0; + double F5 = 0.0; + double F6 = 0.0; + double F7 = 0.0; + + // Total number of operations to compute function values = 80 + for (unsigned int r = 0; r < 5; r++) + { + F0 += FE1_C0_D10[ip][r]*w[0][nzc8[r]]; + F1 += FE1_C0_D01[ip][r]*w[0][nzc7[r]]; + F2 += FE1_C0_D10[ip][r]*w[0][nzc11[r]]; + F3 += FE1_C0_D01[ip][r]*w[0][nzc10[r]]; + F4 += FE1_C0_D10[ip][r]*w[1][nzc8[r]]; + F5 += FE1_C0_D01[ip][r]*w[1][nzc7[r]]; + F6 += FE1_C0_D10[ip][r]*w[1][nzc11[r]]; + F7 += FE1_C0_D01[ip][r]*w[1][nzc10[r]]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 108 + double I[3]; + // Number of operations: 36 + I[0] = W3[ip]*(F4*(F0*G[0] + F1*G[1] + F2*G[2] + F3*G[3]) + F5*(F0*G[1] + F1*G[4] + F2*G[5] + F3*G[6]) + F6*(F0*G[2] + F1*G[5] + F2*G[7] + F3*G[8]) + F7*(F0*G[3] + F1*G[6] + F2*G[8] + F3*G[9])); + + // Number of operations: 36 + I[1] = W3[ip]*(F4*(F0*G[10] + F1*G[11] + F2*G[12] + F3*G[13]) + F5*(F0*G[11] + F1*G[14] + F2*G[15] + F3*G[16]) + F6*(F0*G[12] + F1*G[15] + F2*G[17] + F3*G[18]) + F7*(F0*G[13] + F1*G[16] + F2*G[18] + F3*G[19])); + + // Number of operations: 36 + I[2] = W3[ip]*(F4*(F0*G[20] + F1*G[21] + F2*G[22] + F3*G[23]) + F5*(F0*G[21] + F1*G[24] + F2*G[25] + F3*G[26]) + F6*(F0*G[22] + F1*G[25] + F2*G[27] + F3*G[28]) + F7*(F0*G[23] + F1*G[26] + F2*G[28] + F3*G[29])); + + + // Number of operations for primary indices: 96 + for (unsigned int j = 0; j < 2; j++) + { + for (unsigned int k = 0; k < 2; k++) + { + // Number of operations to compute entry: 3 + A[nzc1[j]*6 + nzc1[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc1[j]*6 + nzc2[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*6 + nzc1[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc2[j]*6 + nzc2[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[2]; + // Number of operations to compute entry: 3 + A[nzc4[j]*6 + nzc4[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[0]; + // Number of operations to compute entry: 3 + A[nzc4[j]*6 + nzc5[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*6 + nzc4[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[1]; + // Number of operations to compute entry: 3 + A[nzc5[j]*6 + nzc5[k]] += FE0_C0_D01[ip][j]*FE0_C0_D01[ip][k]*I[2]; + }// end loop over 'k' + }// end loop over 'j' + }// end loop over 'ip' + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f2_p2_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), Product(IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 1), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 2; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p2_q1_quadrature_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p2_q1_quadrature_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_quadrature_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif diff --git a/vector_laplacian_2d/vector_laplacian_f2_p2_q1_tensor.h b/vector_laplacian_2d/vector_laplacian_f2_p2_q1_tensor.h new file mode 100644 index 0000000..2f46aef --- /dev/null +++ b/vector_laplacian_2d/vector_laplacian_f2_p2_q1_tensor.h @@ -0,0 +1,9412 @@ +// This code conforms with the UFC specification version 2.0.5 +// and was automatically generated by FFC version 1.0.0. +// +// This code was generated with the following parameters: +// +// cache_dir: '' +// convert_exceptions_to_warnings: False +// cpp_optimize: False +// cpp_optimize_flags: '-O2' +// epsilon: 1e-14 +// error_control: False +// form_postfix: True +// format: 'ufc' +// log_level: 20 +// log_prefix: '' +// optimize: True +// output_dir: '.' +// precision: 15 +// quadrature_degree: 'auto' +// quadrature_rule: 'auto' +// representation: 'tensor' +// split: False +// swig_binary: 'swig' +// swig_path: '' + +#ifndef __VECTOR_LAPLACIAN_F2_P2_Q1_TENSOR_H +#define __VECTOR_LAPLACIAN_F2_P2_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p2_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_tensor_finite_element_0() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p2_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_tensor_finite_element_1() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 12; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Compute value(s). + for (unsigned int r = 0; r < 6; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 1: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 2: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 4: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 5: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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 6: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 7: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 8: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.0, 0.0, 0.2, 0.0, 0.0, 0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 9: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.23094010767585, 0.133333333333333, 0.0, 0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 10: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, -0.23094010767585, 0.133333333333333, 0.0, -0.188561808316413, -0.163299316185545}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 11: + { + + // Array of basisvalues. + double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + double tmp1 = (1.0 - Y)/2.0; + double tmp2 = tmp1*tmp1; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y); + basisvalues[5] = basisvalues[2]*(0.111111111111111 + Y*1.66666666666667) - basisvalues[0]*0.555555555555556; + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[5] *= std::sqrt(1.5); + basisvalues[1] *= std::sqrt(3.0); + basisvalues[4] *= std::sqrt(4.5); + basisvalues[3] *= std::sqrt(7.5); + + // Table(s) of coefficients. + static const double coefficients0[6] = \ + {0.471404520791032, 0.0, -0.266666666666667, -0.243432247780074, 0.0, 0.0544331053951817}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.89897948556635, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 9.48683298050514, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175277, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; 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 < 6; s++) + { + for (unsigned int t = 0; t < 6; 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[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 12; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 4: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 5: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 6: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 7: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 8: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 9: + { + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 10: + { + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 11: + { + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[3] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[4] = vals[0]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[5] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[6] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[7] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[8] = vals[1]; + y[0] = 0.5*x[1][0] + 0.5*x[2][0]; + y[1] = 0.5*x[1][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[9] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[2][0]; + y[1] = 0.5*x[0][1] + 0.5*x[2][1]; + f.evaluate(vals, y, c); + values[10] = vals[1]; + y[0] = 0.5*x[0][0] + 0.5*x[1][0]; + y[1] = 0.5*x[0][1] + 0.5*x[1][1]; + f.evaluate(vals, y, c); + values[11] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[6]; + vertex_values[3] = dof_values[7]; + vertex_values[5] = dof_values[8]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p2_q1_tensor_finite_element_2: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_tensor_finite_element_2() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_tensor_finite_element_2() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 3; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 0; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + return 1; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + *values = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + *values += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values = 0.0; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis(r, &dof_values, coordinates, c); + values[r] = dof_values; + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 3; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[1]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[1] = dof_values[1]; + vertex_values[2] = dof_values[2]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 0; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_2(); + } + +}; + +/// This class defines the interface for a finite element. + +class vector_laplacian_f2_p2_q1_tensor_finite_element_3: public ufc::finite_element +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_tensor_finite_element_3() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_tensor_finite_element_3() + { + // Do nothing + } + + /// Return a string identifying the finite element + virtual const char* signature() const + { + return "VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return the cell shape + virtual ufc::shape cell_shape() const + { + return ufc::triangle; + } + + /// Return the topological dimension of the cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the finite element function space + virtual unsigned int space_dimension() const + { + return 6; + } + + /// Return the rank of the value space + virtual unsigned int value_rank() const + { + return 1; + } + + /// Return the dimension of the value space for axis i + virtual unsigned int value_dimension(unsigned int i) const + { + switch (i) + { + case 0: + { + return 2; + break; + } + } + + return 0; + } + + /// Evaluate basis function i at given point in cell + virtual void evaluate_basis(unsigned int i, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Reset values. + values[0] = 0.0; + values[1] = 0.0; + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[0] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 3: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Compute value(s). + for (unsigned int r = 0; r < 3; r++) + { + values[1] += coefficients0[r]*basisvalues[r]; + }// end loop over 'r' + break; + } + } + + } + + /// Evaluate all basis functions at given point in cell + virtual void evaluate_basis_all(double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Helper variable to hold values of a single dof. + double dof_values[2] = {0.0, 0.0}; + + // Loop dofs and call evaluate_basis. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis(r, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2; s++) + { + values[r*2 + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + } + + /// Evaluate order n derivatives of basis function i at given point in cell + virtual void evaluate_basis_derivatives(unsigned int i, + unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Compute constants + const double C0 = x[1][0] + x[2][0]; + const double C1 = x[1][1] + x[2][1]; + + // Get coordinates and map to the reference (FIAT) element + double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ; + double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ; + + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Declare pointer to two dimensional array that holds combinations of derivatives and initialise + unsigned int **combinations = new unsigned int *[num_derivatives]; + for (unsigned int row = 0; row < num_derivatives; row++) + { + combinations[row] = new unsigned int [n]; + for (unsigned int col = 0; col < n; col++) + combinations[row][col] = 0; + } + + // Generate combinations of derivatives + for (unsigned int row = 1; row < num_derivatives; row++) + { + for (unsigned int num = 0; num < row; num++) + { + for (unsigned int col = n-1; col+1 > 0; col--) + { + if (combinations[row][col] + 1 > 1) + combinations[row][col] = 0; + else + { + combinations[row][col] += 1; + break; + } + } + } + } + + // Compute inverse of Jacobian + const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}}; + + // Declare transformation matrix + // Declare pointer to two dimensional array and initialise + double **transform = new double *[num_derivatives]; + + for (unsigned int j = 0; j < num_derivatives; j++) + { + transform[j] = new double [num_derivatives]; + for (unsigned int k = 0; k < num_derivatives; k++) + transform[j][k] = 1; + } + + // Construct transformation matrix + for (unsigned int row = 0; row < num_derivatives; row++) + { + for (unsigned int col = 0; col < num_derivatives; col++) + { + for (unsigned int k = 0; k < n; k++) + transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]]; + } + } + + // Reset values. Assuming that values is always an array. + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + values[r] = 0.0; + }// end loop over 'r' + + switch (i) + { + case 0: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 1: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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 2: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[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[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, -0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 4: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.288675134594813, -0.166666666666667}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + case 5: + { + + // Array of basisvalues. + double basisvalues[3] = {0.0, 0.0, 0.0}; + + // Declare helper variables. + double tmp0 = (1.0 + Y + 2.0*X)/2.0; + + // Compute basisvalues. + basisvalues[0] = 1.0; + basisvalues[1] = tmp0; + basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y); + basisvalues[0] *= std::sqrt(0.5); + basisvalues[2] *= std::sqrt(1.0); + basisvalues[1] *= std::sqrt(3.0); + + // Table(s) of coefficients. + static const double coefficients0[3] = \ + {0.471404520791032, 0.0, 0.333333333333333}; + + // Tables of derivatives of the polynomial base (transpose). + static const double dmats0[3][3] = \ + {{0.0, 0.0, 0.0}, + {4.89897948556636, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + + static const double dmats1[3][3] = \ + {{0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0}}; + + // 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.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[3][3] = \ + {{1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; + + // 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.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// 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.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 3; t++) + { + for (unsigned int u = 0; u < 3; u++) + { + for (unsigned int tu = 0; tu < 3; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 3; s++) + { + for (unsigned int t = 0; t < 3; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[num_derivatives + r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop over 'r' + delete [] combinations; + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] transform[r]; + }// end loop over 'r' + delete [] transform; + break; + } + } + + } + + /// Evaluate order n derivatives of all basis functions at given point in cell + virtual void evaluate_basis_derivatives_all(unsigned int n, + double* values, + const double* coordinates, + const ufc::cell& c) const + { + // Compute number of derivatives. + unsigned int num_derivatives = 1; + for (unsigned int r = 0; r < n; r++) + { + num_derivatives *= 2; + }// end loop over 'r' + + // Helper variable to hold values of a single dof. + double *dof_values = new double[2*num_derivatives]; + for (unsigned int r = 0; r < 2*num_derivatives; r++) + { + dof_values[r] = 0.0; + }// end loop over 'r' + + // Loop dofs and call evaluate_basis_derivatives. + for (unsigned int r = 0; r < 6; r++) + { + evaluate_basis_derivatives(r, n, dof_values, coordinates, c); + for (unsigned int s = 0; s < 2*num_derivatives; s++) + { + values[r*2*num_derivatives + s] = dof_values[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer. + delete [] dof_values; + } + + /// Evaluate linear functional for dof i on the function f + virtual double evaluate_dof(unsigned int i, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + switch (i) + { + case 0: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 1: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 2: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[0]; + break; + } + case 3: + { + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 4: + { + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + case 5: + { + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + return vals[1]; + break; + } + } + + return 0.0; + } + + /// Evaluate linear functionals for all dofs on the function f + virtual void evaluate_dofs(double* values, + const ufc::function& f, + const ufc::cell& c) const + { + // Declare variables for result of evaluation. + double vals[2]; + + // Declare variable for physical coordinates. + double y[2]; + const double * const * x = c.coordinates; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[0] = vals[0]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[1] = vals[0]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[2] = vals[0]; + y[0] = x[0][0]; + y[1] = x[0][1]; + f.evaluate(vals, y, c); + values[3] = vals[1]; + y[0] = x[1][0]; + y[1] = x[1][1]; + f.evaluate(vals, y, c); + values[4] = vals[1]; + y[0] = x[2][0]; + y[1] = x[2][1]; + f.evaluate(vals, y, c); + values[5] = vals[1]; + } + + /// Interpolate vertex values from dof values + virtual void interpolate_vertex_values(double* vertex_values, + const double* dof_values, + const ufc::cell& c) const + { + // Evaluate function and change variables + vertex_values[0] = dof_values[0]; + vertex_values[2] = dof_values[1]; + vertex_values[4] = dof_values[2]; + // Evaluate function and change variables + vertex_values[1] = dof_values[3]; + vertex_values[3] = dof_values[4]; + vertex_values[5] = dof_values[5]; + } + + /// Map coordinate xhat from reference cell to coordinate x in cell + virtual void map_from_reference_cell(double* x, + const double* xhat, + const ufc::cell& c) const + { + throw std::runtime_error("map_from_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Map from coordinate x in cell to coordinate xhat in reference cell + virtual void map_to_reference_cell(double* xhat, + const double* x, + const ufc::cell& c) const + { + throw std::runtime_error("map_to_reference_cell not yet implemented (introduced in UFC 2.0)."); + } + + /// Return the number of sub elements (for a mixed element) + virtual unsigned int num_sub_elements() const + { + return 2; + } + + /// Create a new finite element for sub element i (for a mixed element) + virtual ufc::finite_element* create_sub_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::finite_element* create() const + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_3(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p2_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p2_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_tensor_dofmap_0() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0] + m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 3; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 1; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + break; + } + case 1: + { + dofs[0] = 4; + break; + } + case 2: + { + dofs[0] = 5; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p2_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p2_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_tensor_dofmap_1() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return true; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 12; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 12; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 6; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 2; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + 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 += 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 += 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]; + offset += m.num_entities[1]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + 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) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 6; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 7; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 8; + break; + } + } + + break; + } + case 1: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 3; + dofs[1] = 9; + break; + } + case 1: + { + dofs[0] = 4; + dofs[1] = 10; + break; + } + case 2: + { + dofs[0] = 5; + dofs[1] = 11; + break; + } + } + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + 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 dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_0(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p2_q1_tensor_dofmap_2: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p2_q1_tensor_dofmap_2() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_tensor_dofmap_2() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 3; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 3; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 2; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 1; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + dofs[0] = c.entity_indices[0][0]; + dofs[1] = c.entity_indices[0][1]; + dofs[2] = c.entity_indices[0][2]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + break; + } + case 1: + { + dofs[0] = 1; + break; + } + case 2: + { + dofs[0] = 2; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 0; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_2(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class vector_laplacian_f2_p2_q1_tensor_dofmap_3: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + vector_laplacian_f2_p2_q1_tensor_dofmap_3() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_tensor_dofmap_3() + { + // Do nothing + } + + /// Return a string identifying the dofmap + virtual const char* signature() const + { + return "FFC dofmap for VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None)"; + } + + /// Return true iff mesh entities of topological dimension d are needed + virtual bool needs_mesh_entities(unsigned int d) const + { + switch (d) + { + case 0: + { + return true; + break; + } + case 1: + { + return false; + break; + } + case 2: + { + return false; + break; + } + } + + return false; + } + + /// Initialize dofmap for mesh (return true iff init_cell() is needed) + virtual bool init_mesh(const ufc::mesh& m) + { + _global_dimension = 2*m.num_entities[0]; + return false; + } + + /// Initialize dofmap for given cell + virtual void init_cell(const ufc::mesh& m, + const ufc::cell& c) + { + // Do nothing + } + + /// Finish initialization of dofmap for cells + virtual void init_cell_finalize() + { + // Do nothing + } + + /// Return the topological dimension of the associated cell shape + virtual unsigned int topological_dimension() const + { + return 2; + } + + /// Return the geometric dimension of the associated cell shape + virtual unsigned int geometric_dimension() const + { + return 2; + } + + /// Return the dimension of the global finite element function space + virtual unsigned int global_dimension() const + { + return _global_dimension; + } + + /// Return the dimension of the local finite element function space for a cell + virtual unsigned int local_dimension(const ufc::cell& c) const + { + return 6; + } + + /// Return the maximum dimension of the local finite element function space + virtual unsigned int max_local_dimension() const + { + return 6; + } + + /// Return the number of dofs on each cell facet + virtual unsigned int num_facet_dofs() const + { + return 4; + } + + /// Return the number of dofs associated with each cell entity of dimension d + virtual unsigned int num_entity_dofs(unsigned int d) const + { + switch (d) + { + case 0: + { + return 2; + break; + } + case 1: + { + return 0; + break; + } + case 2: + { + return 0; + break; + } + } + + return 0; + } + + /// Tabulate the local-to-global mapping of dofs on a cell + virtual void tabulate_dofs(unsigned int* dofs, + const ufc::mesh& m, + const ufc::cell& c) const + { + unsigned int offset = 0; + dofs[0] = offset + c.entity_indices[0][0]; + dofs[1] = offset + c.entity_indices[0][1]; + dofs[2] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + dofs[3] = offset + c.entity_indices[0][0]; + dofs[4] = offset + c.entity_indices[0][1]; + dofs[5] = offset + c.entity_indices[0][2]; + offset += m.num_entities[0]; + } + + /// Tabulate the local-to-local mapping from facet dofs to cell dofs + virtual void tabulate_facet_dofs(unsigned int* dofs, + unsigned int facet) const + { + switch (facet) + { + case 0: + { + dofs[0] = 1; + dofs[1] = 2; + dofs[2] = 4; + dofs[3] = 5; + break; + } + case 1: + { + dofs[0] = 0; + dofs[1] = 2; + dofs[2] = 3; + dofs[3] = 5; + break; + } + case 2: + { + dofs[0] = 0; + dofs[1] = 1; + dofs[2] = 3; + dofs[3] = 4; + break; + } + } + + } + + /// Tabulate the local-to-local mapping of dofs on entity (d, i) + virtual void tabulate_entity_dofs(unsigned int* dofs, + unsigned int d, unsigned int i) const + { + if (d > 2) + { + throw std::runtime_error("d is larger than dimension (2)"); + } + + switch (d) + { + case 0: + { + if (i > 2) + { + throw std::runtime_error("i is larger than number of entities (2)"); + } + + switch (i) + { + case 0: + { + dofs[0] = 0; + dofs[1] = 3; + break; + } + case 1: + { + dofs[0] = 1; + dofs[1] = 4; + break; + } + case 2: + { + dofs[0] = 2; + dofs[1] = 5; + break; + } + } + + break; + } + case 1: + { + + break; + } + case 2: + { + + break; + } + } + + } + + /// Tabulate the coordinates of all dofs on a cell + virtual void tabulate_coordinates(double** coordinates, + const ufc::cell& c) const + { + const double * const * x = c.coordinates; + + coordinates[0][0] = x[0][0]; + coordinates[0][1] = x[0][1]; + coordinates[1][0] = x[1][0]; + coordinates[1][1] = x[1][1]; + coordinates[2][0] = x[2][0]; + coordinates[2][1] = x[2][1]; + coordinates[3][0] = x[0][0]; + coordinates[3][1] = x[0][1]; + coordinates[4][0] = x[1][0]; + coordinates[4][1] = x[1][1]; + coordinates[5][0] = x[2][0]; + coordinates[5][1] = x[2][1]; + } + + /// Return the number of sub dofmaps (for a mixed element) + virtual unsigned int num_sub_dofmaps() const + { + return 2; + } + + /// Create a new dofmap for sub dofmap i (for a mixed element) + virtual ufc::dofmap* create_sub_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_2(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_2(); + break; + } + } + + return 0; + } + + /// Create a new class instance + virtual ufc::dofmap* create() const + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_3(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class vector_laplacian_f2_p2_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_tensor_cell_integral_0_0() + { + // Do nothing + } + + /// Tabulate the tensor for the contribution from a local cell + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c) const + { + // Number of operations (multiply-add pairs) for Jacobian data: 11 + // Number of operations (multiply-add pairs) for geometry tensor: 4096 + // Number of operations (multiply-add pairs) for tensor contraction: 2558 + // Total number of operations (multiply-add pairs): 6665 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + const double K_00 = J_11 / detJ; + const double K_01 = -J_01 / detJ; + const double K_10 = -J_10 / detJ; + const double K_11 = J_00 / detJ; + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_4_0_1 = det*(w[0][0]*w[1][4]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_5_0_0 = det*(w[0][0]*w[1][5]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_6_1_0 = det*(w[0][0]*w[1][6]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_6_1_1 = det*(w[0][0]*w[1][6]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_7_1_0 = det*(w[0][0]*w[1][7]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_8_1_1 = det*(w[0][0]*w[1][8]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_10_1_1 = det*(w[0][0]*w[1][10]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_0_11_1_0 = det*(w[0][0]*w[1][11]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_4_0_1 = det*(w[0][0]*w[1][4]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_5_0_0 = det*(w[0][0]*w[1][5]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_6_1_0 = det*(w[0][0]*w[1][6]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_6_1_1 = det*(w[0][0]*w[1][6]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_7_1_0 = det*(w[0][0]*w[1][7]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_8_1_1 = det*(w[0][0]*w[1][8]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_10_1_1 = det*(w[0][0]*w[1][10]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_0_0_1_11_1_0 = det*(w[0][0]*w[1][11]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_3_0_1 = det*(w[0][1]*w[1][3]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_5_0_0 = det*(w[0][1]*w[1][5]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_5_0_1 = det*(w[0][1]*w[1][5]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_6_1_0 = det*(w[0][1]*w[1][6]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_6_1_1 = det*(w[0][1]*w[1][6]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_7_1_0 = det*(w[0][1]*w[1][7]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_8_1_1 = det*(w[0][1]*w[1][8]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_9_1_1 = det*(w[0][1]*w[1][9]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_11_1_0 = det*(w[0][1]*w[1][11]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_1_0_0_11_1_1 = det*(w[0][1]*w[1][11]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_3_0_0 = det*(w[0][2]*w[1][3]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_4_0_0 = det*(w[0][2]*w[1][4]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_4_0_1 = det*(w[0][2]*w[1][4]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_6_1_0 = det*(w[0][2]*w[1][6]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_6_1_1 = det*(w[0][2]*w[1][6]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_7_1_0 = det*(w[0][2]*w[1][7]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_8_1_1 = det*(w[0][2]*w[1][8]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_9_1_0 = det*(w[0][2]*w[1][9]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_10_1_0 = det*(w[0][2]*w[1][10]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_2_0_1_10_1_1 = det*(w[0][2]*w[1][10]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_2_0_1 = det*(w[0][3]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_3_0_0 = det*(w[0][3]*w[1][3]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_3_0_1 = det*(w[0][3]*w[1][3]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_4_0_0 = det*(w[0][3]*w[1][4]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_4_0_1 = det*(w[0][3]*w[1][4]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_5_0_1 = det*(w[0][3]*w[1][5]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_8_1_1 = det*(w[0][3]*w[1][8]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_9_1_0 = det*(w[0][3]*w[1][9]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_9_1_1 = det*(w[0][3]*w[1][9]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_10_1_0 = det*(w[0][3]*w[1][10]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_10_1_1 = det*(w[0][3]*w[1][10]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_0_11_1_1 = det*(w[0][3]*w[1][11]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_1_0_0 = det*(w[0][3]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_3_0_0 = det*(w[0][3]*w[1][3]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_3_0_1 = det*(w[0][3]*w[1][3]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_4_0_0 = det*(w[0][3]*w[1][4]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_5_0_0 = det*(w[0][3]*w[1][5]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_5_0_1 = det*(w[0][3]*w[1][5]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_7_1_0 = det*(w[0][3]*w[1][7]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_9_1_0 = det*(w[0][3]*w[1][9]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_9_1_1 = det*(w[0][3]*w[1][9]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_10_1_0 = det*(w[0][3]*w[1][10]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_11_1_0 = det*(w[0][3]*w[1][11]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_3_0_1_11_1_1 = det*(w[0][3]*w[1][11]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_2_0_1 = det*(w[0][4]*w[1][2]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_3_0_0 = det*(w[0][4]*w[1][3]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_3_0_1 = det*(w[0][4]*w[1][3]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_4_0_0 = det*(w[0][4]*w[1][4]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_4_0_1 = det*(w[0][4]*w[1][4]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_5_0_1 = det*(w[0][4]*w[1][5]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_8_1_1 = det*(w[0][4]*w[1][8]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_9_1_0 = det*(w[0][4]*w[1][9]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_9_1_1 = det*(w[0][4]*w[1][9]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_10_1_0 = det*(w[0][4]*w[1][10]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_10_1_1 = det*(w[0][4]*w[1][10]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_0_11_1_1 = det*(w[0][4]*w[1][11]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_0_0_0 = det*(w[0][4]*w[1][0]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_0_0_1 = det*(w[0][4]*w[1][0]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_2_0_1 = det*(w[0][4]*w[1][2]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_3_0_0 = det*(w[0][4]*w[1][3]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_4_0_0 = det*(w[0][4]*w[1][4]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_4_0_1 = det*(w[0][4]*w[1][4]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_5_0_0 = det*(w[0][4]*w[1][5]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_6_1_0 = det*(w[0][4]*w[1][6]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_6_1_1 = det*(w[0][4]*w[1][6]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_8_1_1 = det*(w[0][4]*w[1][8]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_9_1_0 = det*(w[0][4]*w[1][9]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_10_1_0 = det*(w[0][4]*w[1][10]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_10_1_1 = det*(w[0][4]*w[1][10]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_4_0_1_11_1_0 = det*(w[0][4]*w[1][11]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_0_0_0 = det*(w[0][5]*w[1][0]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_0_0_1 = det*(w[0][5]*w[1][0]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_1_0_0 = det*(w[0][5]*w[1][1]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_3_0_1 = det*(w[0][5]*w[1][3]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_4_0_1 = det*(w[0][5]*w[1][4]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_5_0_0 = det*(w[0][5]*w[1][5]*K_00*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_5_0_1 = det*(w[0][5]*w[1][5]*K_00*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_6_1_0 = det*(w[0][5]*w[1][6]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_6_1_1 = det*(w[0][5]*w[1][6]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_7_1_0 = det*(w[0][5]*w[1][7]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_9_1_1 = det*(w[0][5]*w[1][9]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_10_1_1 = det*(w[0][5]*w[1][10]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_11_1_0 = det*(w[0][5]*w[1][11]*K_00*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_0_11_1_1 = det*(w[0][5]*w[1][11]*K_00*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_1_0_0 = det*(w[0][5]*w[1][1]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_3_0_0 = det*(w[0][5]*w[1][3]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_3_0_1 = det*(w[0][5]*w[1][3]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_4_0_0 = det*(w[0][5]*w[1][4]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_5_0_0 = det*(w[0][5]*w[1][5]*K_10*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_5_0_1 = det*(w[0][5]*w[1][5]*K_10*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_7_1_0 = det*(w[0][5]*w[1][7]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_9_1_0 = det*(w[0][5]*w[1][9]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_9_1_1 = det*(w[0][5]*w[1][9]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_10_1_0 = det*(w[0][5]*w[1][10]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_11_1_0 = det*(w[0][5]*w[1][11]*K_10*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_5_0_1_11_1_1 = det*(w[0][5]*w[1][11]*K_10*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_0_0_0 = det*(w[0][6]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_0_0_1 = det*(w[0][6]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_1_0_0 = det*(w[0][6]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_2_0_1 = det*(w[0][6]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_4_0_1 = det*(w[0][6]*w[1][4]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_5_0_0 = det*(w[0][6]*w[1][5]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_6_1_0 = det*(w[0][6]*w[1][6]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_6_1_1 = det*(w[0][6]*w[1][6]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_7_1_0 = det*(w[0][6]*w[1][7]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_8_1_1 = det*(w[0][6]*w[1][8]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_10_1_1 = det*(w[0][6]*w[1][10]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_0_11_1_0 = det*(w[0][6]*w[1][11]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_0_0_0 = det*(w[0][6]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_0_0_1 = det*(w[0][6]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_1_0_0 = det*(w[0][6]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_2_0_1 = det*(w[0][6]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_4_0_1 = det*(w[0][6]*w[1][4]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_5_0_0 = det*(w[0][6]*w[1][5]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_6_1_0 = det*(w[0][6]*w[1][6]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_6_1_1 = det*(w[0][6]*w[1][6]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_7_1_0 = det*(w[0][6]*w[1][7]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_8_1_1 = det*(w[0][6]*w[1][8]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_10_1_1 = det*(w[0][6]*w[1][10]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_6_1_1_11_1_0 = det*(w[0][6]*w[1][11]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_0_0_0 = det*(w[0][7]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_0_0_1 = det*(w[0][7]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_1_0_0 = det*(w[0][7]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_2_0_1 = det*(w[0][7]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_3_0_1 = det*(w[0][7]*w[1][3]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_5_0_0 = det*(w[0][7]*w[1][5]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_5_0_1 = det*(w[0][7]*w[1][5]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_6_1_0 = det*(w[0][7]*w[1][6]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_6_1_1 = det*(w[0][7]*w[1][6]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_7_1_0 = det*(w[0][7]*w[1][7]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_8_1_1 = det*(w[0][7]*w[1][8]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_9_1_1 = det*(w[0][7]*w[1][9]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_11_1_0 = det*(w[0][7]*w[1][11]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_7_1_0_11_1_1 = det*(w[0][7]*w[1][11]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_0_0_0 = det*(w[0][8]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_0_0_1 = det*(w[0][8]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_1_0_0 = det*(w[0][8]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_2_0_1 = det*(w[0][8]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_3_0_0 = det*(w[0][8]*w[1][3]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_4_0_0 = det*(w[0][8]*w[1][4]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_4_0_1 = det*(w[0][8]*w[1][4]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_6_1_0 = det*(w[0][8]*w[1][6]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_6_1_1 = det*(w[0][8]*w[1][6]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_7_1_0 = det*(w[0][8]*w[1][7]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_8_1_1 = det*(w[0][8]*w[1][8]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_9_1_0 = det*(w[0][8]*w[1][9]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_10_1_0 = det*(w[0][8]*w[1][10]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_8_1_1_10_1_1 = det*(w[0][8]*w[1][10]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_2_0_1 = det*(w[0][9]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_3_0_0 = det*(w[0][9]*w[1][3]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_3_0_1 = det*(w[0][9]*w[1][3]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_4_0_0 = det*(w[0][9]*w[1][4]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_4_0_1 = det*(w[0][9]*w[1][4]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_5_0_1 = det*(w[0][9]*w[1][5]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_8_1_1 = det*(w[0][9]*w[1][8]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_9_1_0 = det*(w[0][9]*w[1][9]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_9_1_1 = det*(w[0][9]*w[1][9]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_10_1_0 = det*(w[0][9]*w[1][10]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_10_1_1 = det*(w[0][9]*w[1][10]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_0_11_1_1 = det*(w[0][9]*w[1][11]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_1_0_0 = det*(w[0][9]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_3_0_0 = det*(w[0][9]*w[1][3]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_3_0_1 = det*(w[0][9]*w[1][3]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_4_0_0 = det*(w[0][9]*w[1][4]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_5_0_0 = det*(w[0][9]*w[1][5]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_5_0_1 = det*(w[0][9]*w[1][5]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_7_1_0 = det*(w[0][9]*w[1][7]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_9_1_0 = det*(w[0][9]*w[1][9]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_9_1_1 = det*(w[0][9]*w[1][9]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_10_1_0 = det*(w[0][9]*w[1][10]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_11_1_0 = det*(w[0][9]*w[1][11]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_9_1_1_11_1_1 = det*(w[0][9]*w[1][11]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_2_0_1 = det*(w[0][10]*w[1][2]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_3_0_0 = det*(w[0][10]*w[1][3]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_3_0_1 = det*(w[0][10]*w[1][3]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_4_0_0 = det*(w[0][10]*w[1][4]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_4_0_1 = det*(w[0][10]*w[1][4]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_5_0_1 = det*(w[0][10]*w[1][5]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_8_1_1 = det*(w[0][10]*w[1][8]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_9_1_0 = det*(w[0][10]*w[1][9]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_9_1_1 = det*(w[0][10]*w[1][9]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_10_1_0 = det*(w[0][10]*w[1][10]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_10_1_1 = det*(w[0][10]*w[1][10]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_0_11_1_1 = det*(w[0][10]*w[1][11]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_0_0_0 = det*(w[0][10]*w[1][0]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_0_0_1 = det*(w[0][10]*w[1][0]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_2_0_1 = det*(w[0][10]*w[1][2]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_3_0_0 = det*(w[0][10]*w[1][3]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_4_0_0 = det*(w[0][10]*w[1][4]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_4_0_1 = det*(w[0][10]*w[1][4]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_5_0_0 = det*(w[0][10]*w[1][5]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_6_1_0 = det*(w[0][10]*w[1][6]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_6_1_1 = det*(w[0][10]*w[1][6]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_8_1_1 = det*(w[0][10]*w[1][8]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_9_1_0 = det*(w[0][10]*w[1][9]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_10_1_0 = det*(w[0][10]*w[1][10]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_10_1_1 = det*(w[0][10]*w[1][10]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_10_1_1_11_1_0 = det*(w[0][10]*w[1][11]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_0_0_0 = det*(w[0][11]*w[1][0]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_0_0_1 = det*(w[0][11]*w[1][0]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_1_0_0 = det*(w[0][11]*w[1][1]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_3_0_1 = det*(w[0][11]*w[1][3]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_4_0_1 = det*(w[0][11]*w[1][4]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_5_0_0 = det*(w[0][11]*w[1][5]*K_01*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_5_0_1 = det*(w[0][11]*w[1][5]*K_01*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_6_1_0 = det*(w[0][11]*w[1][6]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_6_1_1 = det*(w[0][11]*w[1][6]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_7_1_0 = det*(w[0][11]*w[1][7]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_9_1_1 = det*(w[0][11]*w[1][9]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_10_1_1 = det*(w[0][11]*w[1][10]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_11_1_0 = det*(w[0][11]*w[1][11]*K_01*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_0_11_1_1 = det*(w[0][11]*w[1][11]*K_01*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_1_0_0 = det*(w[0][11]*w[1][1]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_3_0_0 = det*(w[0][11]*w[1][3]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_3_0_1 = det*(w[0][11]*w[1][3]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_4_0_0 = det*(w[0][11]*w[1][4]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_5_0_0 = det*(w[0][11]*w[1][5]*K_11*K_00*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_5_0_1 = det*(w[0][11]*w[1][5]*K_11*K_10*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_7_1_0 = det*(w[0][11]*w[1][7]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_9_1_0 = det*(w[0][11]*w[1][9]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_9_1_1 = det*(w[0][11]*w[1][9]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_10_1_0 = det*(w[0][11]*w[1][10]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_11_1_0 = det*(w[0][11]*w[1][11]*K_11*K_01*((K_00*K_00 + K_01*K_01))); + const double G0_0_0_11_1_1_11_1_1 = det*(w[0][11]*w[1][11]*K_11*K_11*((K_00*K_00 + K_01*K_01))); + const double G0_0_1_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_4_0_1 = det*(w[0][0]*w[1][4]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_5_0_0 = det*(w[0][0]*w[1][5]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_6_1_0 = det*(w[0][0]*w[1][6]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_6_1_1 = det*(w[0][0]*w[1][6]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_7_1_0 = det*(w[0][0]*w[1][7]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_8_1_1 = det*(w[0][0]*w[1][8]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_10_1_1 = det*(w[0][0]*w[1][10]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_0_11_1_0 = det*(w[0][0]*w[1][11]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_4_0_1 = det*(w[0][0]*w[1][4]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_5_0_0 = det*(w[0][0]*w[1][5]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_6_1_0 = det*(w[0][0]*w[1][6]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_6_1_1 = det*(w[0][0]*w[1][6]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_7_1_0 = det*(w[0][0]*w[1][7]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_8_1_1 = det*(w[0][0]*w[1][8]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_10_1_1 = det*(w[0][0]*w[1][10]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_0_0_1_11_1_0 = det*(w[0][0]*w[1][11]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_3_0_1 = det*(w[0][1]*w[1][3]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_5_0_0 = det*(w[0][1]*w[1][5]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_5_0_1 = det*(w[0][1]*w[1][5]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_6_1_0 = det*(w[0][1]*w[1][6]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_6_1_1 = det*(w[0][1]*w[1][6]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_7_1_0 = det*(w[0][1]*w[1][7]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_8_1_1 = det*(w[0][1]*w[1][8]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_9_1_1 = det*(w[0][1]*w[1][9]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_11_1_0 = det*(w[0][1]*w[1][11]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_1_0_0_11_1_1 = det*(w[0][1]*w[1][11]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_3_0_0 = det*(w[0][2]*w[1][3]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_4_0_0 = det*(w[0][2]*w[1][4]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_4_0_1 = det*(w[0][2]*w[1][4]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_6_1_0 = det*(w[0][2]*w[1][6]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_6_1_1 = det*(w[0][2]*w[1][6]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_7_1_0 = det*(w[0][2]*w[1][7]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_8_1_1 = det*(w[0][2]*w[1][8]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_9_1_0 = det*(w[0][2]*w[1][9]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_10_1_0 = det*(w[0][2]*w[1][10]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_2_0_1_10_1_1 = det*(w[0][2]*w[1][10]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_2_0_1 = det*(w[0][3]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_3_0_0 = det*(w[0][3]*w[1][3]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_3_0_1 = det*(w[0][3]*w[1][3]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_4_0_0 = det*(w[0][3]*w[1][4]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_4_0_1 = det*(w[0][3]*w[1][4]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_5_0_1 = det*(w[0][3]*w[1][5]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_8_1_1 = det*(w[0][3]*w[1][8]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_9_1_0 = det*(w[0][3]*w[1][9]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_9_1_1 = det*(w[0][3]*w[1][9]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_10_1_0 = det*(w[0][3]*w[1][10]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_10_1_1 = det*(w[0][3]*w[1][10]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_0_11_1_1 = det*(w[0][3]*w[1][11]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_1_0_0 = det*(w[0][3]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_3_0_0 = det*(w[0][3]*w[1][3]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_3_0_1 = det*(w[0][3]*w[1][3]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_4_0_0 = det*(w[0][3]*w[1][4]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_5_0_0 = det*(w[0][3]*w[1][5]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_5_0_1 = det*(w[0][3]*w[1][5]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_7_1_0 = det*(w[0][3]*w[1][7]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_9_1_0 = det*(w[0][3]*w[1][9]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_9_1_1 = det*(w[0][3]*w[1][9]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_10_1_0 = det*(w[0][3]*w[1][10]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_11_1_0 = det*(w[0][3]*w[1][11]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_3_0_1_11_1_1 = det*(w[0][3]*w[1][11]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_2_0_1 = det*(w[0][4]*w[1][2]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_3_0_0 = det*(w[0][4]*w[1][3]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_3_0_1 = det*(w[0][4]*w[1][3]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_4_0_0 = det*(w[0][4]*w[1][4]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_4_0_1 = det*(w[0][4]*w[1][4]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_5_0_1 = det*(w[0][4]*w[1][5]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_8_1_1 = det*(w[0][4]*w[1][8]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_9_1_0 = det*(w[0][4]*w[1][9]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_9_1_1 = det*(w[0][4]*w[1][9]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_10_1_0 = det*(w[0][4]*w[1][10]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_10_1_1 = det*(w[0][4]*w[1][10]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_0_11_1_1 = det*(w[0][4]*w[1][11]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_0_0_0 = det*(w[0][4]*w[1][0]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_0_0_1 = det*(w[0][4]*w[1][0]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_2_0_1 = det*(w[0][4]*w[1][2]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_3_0_0 = det*(w[0][4]*w[1][3]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_4_0_0 = det*(w[0][4]*w[1][4]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_4_0_1 = det*(w[0][4]*w[1][4]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_5_0_0 = det*(w[0][4]*w[1][5]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_6_1_0 = det*(w[0][4]*w[1][6]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_6_1_1 = det*(w[0][4]*w[1][6]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_8_1_1 = det*(w[0][4]*w[1][8]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_9_1_0 = det*(w[0][4]*w[1][9]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_10_1_0 = det*(w[0][4]*w[1][10]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_10_1_1 = det*(w[0][4]*w[1][10]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_4_0_1_11_1_0 = det*(w[0][4]*w[1][11]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_0_0_0 = det*(w[0][5]*w[1][0]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_0_0_1 = det*(w[0][5]*w[1][0]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_1_0_0 = det*(w[0][5]*w[1][1]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_3_0_1 = det*(w[0][5]*w[1][3]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_4_0_1 = det*(w[0][5]*w[1][4]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_5_0_0 = det*(w[0][5]*w[1][5]*K_00*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_5_0_1 = det*(w[0][5]*w[1][5]*K_00*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_6_1_0 = det*(w[0][5]*w[1][6]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_6_1_1 = det*(w[0][5]*w[1][6]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_7_1_0 = det*(w[0][5]*w[1][7]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_9_1_1 = det*(w[0][5]*w[1][9]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_10_1_1 = det*(w[0][5]*w[1][10]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_11_1_0 = det*(w[0][5]*w[1][11]*K_00*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_0_11_1_1 = det*(w[0][5]*w[1][11]*K_00*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_1_0_0 = det*(w[0][5]*w[1][1]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_3_0_0 = det*(w[0][5]*w[1][3]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_3_0_1 = det*(w[0][5]*w[1][3]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_4_0_0 = det*(w[0][5]*w[1][4]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_5_0_0 = det*(w[0][5]*w[1][5]*K_10*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_5_0_1 = det*(w[0][5]*w[1][5]*K_10*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_7_1_0 = det*(w[0][5]*w[1][7]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_9_1_0 = det*(w[0][5]*w[1][9]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_9_1_1 = det*(w[0][5]*w[1][9]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_10_1_0 = det*(w[0][5]*w[1][10]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_11_1_0 = det*(w[0][5]*w[1][11]*K_10*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_5_0_1_11_1_1 = det*(w[0][5]*w[1][11]*K_10*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_0_0_0 = det*(w[0][6]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_0_0_1 = det*(w[0][6]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_1_0_0 = det*(w[0][6]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_2_0_1 = det*(w[0][6]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_4_0_1 = det*(w[0][6]*w[1][4]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_5_0_0 = det*(w[0][6]*w[1][5]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_6_1_0 = det*(w[0][6]*w[1][6]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_6_1_1 = det*(w[0][6]*w[1][6]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_7_1_0 = det*(w[0][6]*w[1][7]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_8_1_1 = det*(w[0][6]*w[1][8]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_10_1_1 = det*(w[0][6]*w[1][10]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_0_11_1_0 = det*(w[0][6]*w[1][11]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_0_0_0 = det*(w[0][6]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_0_0_1 = det*(w[0][6]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_1_0_0 = det*(w[0][6]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_2_0_1 = det*(w[0][6]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_4_0_1 = det*(w[0][6]*w[1][4]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_5_0_0 = det*(w[0][6]*w[1][5]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_6_1_0 = det*(w[0][6]*w[1][6]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_6_1_1 = det*(w[0][6]*w[1][6]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_7_1_0 = det*(w[0][6]*w[1][7]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_8_1_1 = det*(w[0][6]*w[1][8]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_10_1_1 = det*(w[0][6]*w[1][10]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_6_1_1_11_1_0 = det*(w[0][6]*w[1][11]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_0_0_0 = det*(w[0][7]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_0_0_1 = det*(w[0][7]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_1_0_0 = det*(w[0][7]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_2_0_1 = det*(w[0][7]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_3_0_1 = det*(w[0][7]*w[1][3]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_5_0_0 = det*(w[0][7]*w[1][5]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_5_0_1 = det*(w[0][7]*w[1][5]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_6_1_0 = det*(w[0][7]*w[1][6]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_6_1_1 = det*(w[0][7]*w[1][6]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_7_1_0 = det*(w[0][7]*w[1][7]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_8_1_1 = det*(w[0][7]*w[1][8]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_9_1_1 = det*(w[0][7]*w[1][9]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_11_1_0 = det*(w[0][7]*w[1][11]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_7_1_0_11_1_1 = det*(w[0][7]*w[1][11]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_0_0_0 = det*(w[0][8]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_0_0_1 = det*(w[0][8]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_1_0_0 = det*(w[0][8]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_2_0_1 = det*(w[0][8]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_3_0_0 = det*(w[0][8]*w[1][3]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_4_0_0 = det*(w[0][8]*w[1][4]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_4_0_1 = det*(w[0][8]*w[1][4]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_6_1_0 = det*(w[0][8]*w[1][6]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_6_1_1 = det*(w[0][8]*w[1][6]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_7_1_0 = det*(w[0][8]*w[1][7]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_8_1_1 = det*(w[0][8]*w[1][8]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_9_1_0 = det*(w[0][8]*w[1][9]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_10_1_0 = det*(w[0][8]*w[1][10]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_8_1_1_10_1_1 = det*(w[0][8]*w[1][10]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_2_0_1 = det*(w[0][9]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_3_0_0 = det*(w[0][9]*w[1][3]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_3_0_1 = det*(w[0][9]*w[1][3]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_4_0_0 = det*(w[0][9]*w[1][4]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_4_0_1 = det*(w[0][9]*w[1][4]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_5_0_1 = det*(w[0][9]*w[1][5]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_8_1_1 = det*(w[0][9]*w[1][8]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_9_1_0 = det*(w[0][9]*w[1][9]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_9_1_1 = det*(w[0][9]*w[1][9]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_10_1_0 = det*(w[0][9]*w[1][10]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_10_1_1 = det*(w[0][9]*w[1][10]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_0_11_1_1 = det*(w[0][9]*w[1][11]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_1_0_0 = det*(w[0][9]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_3_0_0 = det*(w[0][9]*w[1][3]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_3_0_1 = det*(w[0][9]*w[1][3]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_4_0_0 = det*(w[0][9]*w[1][4]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_5_0_0 = det*(w[0][9]*w[1][5]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_5_0_1 = det*(w[0][9]*w[1][5]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_7_1_0 = det*(w[0][9]*w[1][7]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_9_1_0 = det*(w[0][9]*w[1][9]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_9_1_1 = det*(w[0][9]*w[1][9]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_10_1_0 = det*(w[0][9]*w[1][10]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_11_1_0 = det*(w[0][9]*w[1][11]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_9_1_1_11_1_1 = det*(w[0][9]*w[1][11]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_2_0_1 = det*(w[0][10]*w[1][2]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_3_0_0 = det*(w[0][10]*w[1][3]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_3_0_1 = det*(w[0][10]*w[1][3]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_4_0_0 = det*(w[0][10]*w[1][4]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_4_0_1 = det*(w[0][10]*w[1][4]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_5_0_1 = det*(w[0][10]*w[1][5]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_8_1_1 = det*(w[0][10]*w[1][8]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_9_1_0 = det*(w[0][10]*w[1][9]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_9_1_1 = det*(w[0][10]*w[1][9]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_10_1_0 = det*(w[0][10]*w[1][10]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_10_1_1 = det*(w[0][10]*w[1][10]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_0_11_1_1 = det*(w[0][10]*w[1][11]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_0_0_0 = det*(w[0][10]*w[1][0]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_0_0_1 = det*(w[0][10]*w[1][0]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_2_0_1 = det*(w[0][10]*w[1][2]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_3_0_0 = det*(w[0][10]*w[1][3]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_4_0_0 = det*(w[0][10]*w[1][4]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_4_0_1 = det*(w[0][10]*w[1][4]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_5_0_0 = det*(w[0][10]*w[1][5]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_6_1_0 = det*(w[0][10]*w[1][6]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_6_1_1 = det*(w[0][10]*w[1][6]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_8_1_1 = det*(w[0][10]*w[1][8]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_9_1_0 = det*(w[0][10]*w[1][9]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_10_1_0 = det*(w[0][10]*w[1][10]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_10_1_1 = det*(w[0][10]*w[1][10]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_10_1_1_11_1_0 = det*(w[0][10]*w[1][11]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_0_0_0 = det*(w[0][11]*w[1][0]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_0_0_1 = det*(w[0][11]*w[1][0]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_1_0_0 = det*(w[0][11]*w[1][1]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_3_0_1 = det*(w[0][11]*w[1][3]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_4_0_1 = det*(w[0][11]*w[1][4]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_5_0_0 = det*(w[0][11]*w[1][5]*K_01*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_5_0_1 = det*(w[0][11]*w[1][5]*K_01*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_6_1_0 = det*(w[0][11]*w[1][6]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_6_1_1 = det*(w[0][11]*w[1][6]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_7_1_0 = det*(w[0][11]*w[1][7]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_9_1_1 = det*(w[0][11]*w[1][9]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_10_1_1 = det*(w[0][11]*w[1][10]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_11_1_0 = det*(w[0][11]*w[1][11]*K_01*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_0_11_1_1 = det*(w[0][11]*w[1][11]*K_01*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_1_0_0 = det*(w[0][11]*w[1][1]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_3_0_0 = det*(w[0][11]*w[1][3]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_3_0_1 = det*(w[0][11]*w[1][3]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_4_0_0 = det*(w[0][11]*w[1][4]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_5_0_0 = det*(w[0][11]*w[1][5]*K_11*K_00*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_5_0_1 = det*(w[0][11]*w[1][5]*K_11*K_10*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_7_1_0 = det*(w[0][11]*w[1][7]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_9_1_0 = det*(w[0][11]*w[1][9]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_9_1_1 = det*(w[0][11]*w[1][9]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_10_1_0 = det*(w[0][11]*w[1][10]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_11_1_0 = det*(w[0][11]*w[1][11]*K_11*K_01*((K_00*K_10 + K_01*K_11))); + const double G0_0_1_11_1_1_11_1_1 = det*(w[0][11]*w[1][11]*K_11*K_11*((K_00*K_10 + K_01*K_11))); + const double G0_1_0_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_4_0_1 = det*(w[0][0]*w[1][4]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_5_0_0 = det*(w[0][0]*w[1][5]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_6_1_0 = det*(w[0][0]*w[1][6]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_6_1_1 = det*(w[0][0]*w[1][6]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_7_1_0 = det*(w[0][0]*w[1][7]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_8_1_1 = det*(w[0][0]*w[1][8]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_10_1_1 = det*(w[0][0]*w[1][10]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_0_11_1_0 = det*(w[0][0]*w[1][11]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_4_0_1 = det*(w[0][0]*w[1][4]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_5_0_0 = det*(w[0][0]*w[1][5]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_6_1_0 = det*(w[0][0]*w[1][6]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_6_1_1 = det*(w[0][0]*w[1][6]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_7_1_0 = det*(w[0][0]*w[1][7]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_8_1_1 = det*(w[0][0]*w[1][8]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_10_1_1 = det*(w[0][0]*w[1][10]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_0_0_1_11_1_0 = det*(w[0][0]*w[1][11]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_3_0_1 = det*(w[0][1]*w[1][3]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_5_0_0 = det*(w[0][1]*w[1][5]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_5_0_1 = det*(w[0][1]*w[1][5]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_6_1_0 = det*(w[0][1]*w[1][6]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_6_1_1 = det*(w[0][1]*w[1][6]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_7_1_0 = det*(w[0][1]*w[1][7]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_8_1_1 = det*(w[0][1]*w[1][8]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_9_1_1 = det*(w[0][1]*w[1][9]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_11_1_0 = det*(w[0][1]*w[1][11]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_1_0_0_11_1_1 = det*(w[0][1]*w[1][11]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_3_0_0 = det*(w[0][2]*w[1][3]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_4_0_0 = det*(w[0][2]*w[1][4]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_4_0_1 = det*(w[0][2]*w[1][4]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_6_1_0 = det*(w[0][2]*w[1][6]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_6_1_1 = det*(w[0][2]*w[1][6]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_7_1_0 = det*(w[0][2]*w[1][7]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_8_1_1 = det*(w[0][2]*w[1][8]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_9_1_0 = det*(w[0][2]*w[1][9]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_10_1_0 = det*(w[0][2]*w[1][10]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_2_0_1_10_1_1 = det*(w[0][2]*w[1][10]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_2_0_1 = det*(w[0][3]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_3_0_0 = det*(w[0][3]*w[1][3]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_3_0_1 = det*(w[0][3]*w[1][3]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_4_0_0 = det*(w[0][3]*w[1][4]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_4_0_1 = det*(w[0][3]*w[1][4]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_5_0_1 = det*(w[0][3]*w[1][5]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_8_1_1 = det*(w[0][3]*w[1][8]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_9_1_0 = det*(w[0][3]*w[1][9]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_9_1_1 = det*(w[0][3]*w[1][9]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_10_1_0 = det*(w[0][3]*w[1][10]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_10_1_1 = det*(w[0][3]*w[1][10]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_0_11_1_1 = det*(w[0][3]*w[1][11]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_1_0_0 = det*(w[0][3]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_3_0_0 = det*(w[0][3]*w[1][3]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_3_0_1 = det*(w[0][3]*w[1][3]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_4_0_0 = det*(w[0][3]*w[1][4]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_5_0_0 = det*(w[0][3]*w[1][5]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_5_0_1 = det*(w[0][3]*w[1][5]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_7_1_0 = det*(w[0][3]*w[1][7]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_9_1_0 = det*(w[0][3]*w[1][9]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_9_1_1 = det*(w[0][3]*w[1][9]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_10_1_0 = det*(w[0][3]*w[1][10]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_11_1_0 = det*(w[0][3]*w[1][11]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_3_0_1_11_1_1 = det*(w[0][3]*w[1][11]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_2_0_1 = det*(w[0][4]*w[1][2]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_3_0_0 = det*(w[0][4]*w[1][3]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_3_0_1 = det*(w[0][4]*w[1][3]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_4_0_0 = det*(w[0][4]*w[1][4]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_4_0_1 = det*(w[0][4]*w[1][4]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_5_0_1 = det*(w[0][4]*w[1][5]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_8_1_1 = det*(w[0][4]*w[1][8]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_9_1_0 = det*(w[0][4]*w[1][9]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_9_1_1 = det*(w[0][4]*w[1][9]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_10_1_0 = det*(w[0][4]*w[1][10]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_10_1_1 = det*(w[0][4]*w[1][10]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_0_11_1_1 = det*(w[0][4]*w[1][11]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_0_0_0 = det*(w[0][4]*w[1][0]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_0_0_1 = det*(w[0][4]*w[1][0]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_2_0_1 = det*(w[0][4]*w[1][2]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_3_0_0 = det*(w[0][4]*w[1][3]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_4_0_0 = det*(w[0][4]*w[1][4]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_4_0_1 = det*(w[0][4]*w[1][4]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_5_0_0 = det*(w[0][4]*w[1][5]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_6_1_0 = det*(w[0][4]*w[1][6]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_6_1_1 = det*(w[0][4]*w[1][6]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_8_1_1 = det*(w[0][4]*w[1][8]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_9_1_0 = det*(w[0][4]*w[1][9]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_10_1_0 = det*(w[0][4]*w[1][10]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_10_1_1 = det*(w[0][4]*w[1][10]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_4_0_1_11_1_0 = det*(w[0][4]*w[1][11]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_0_0_0 = det*(w[0][5]*w[1][0]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_0_0_1 = det*(w[0][5]*w[1][0]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_1_0_0 = det*(w[0][5]*w[1][1]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_3_0_1 = det*(w[0][5]*w[1][3]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_4_0_1 = det*(w[0][5]*w[1][4]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_5_0_0 = det*(w[0][5]*w[1][5]*K_00*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_5_0_1 = det*(w[0][5]*w[1][5]*K_00*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_6_1_0 = det*(w[0][5]*w[1][6]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_6_1_1 = det*(w[0][5]*w[1][6]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_7_1_0 = det*(w[0][5]*w[1][7]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_9_1_1 = det*(w[0][5]*w[1][9]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_10_1_1 = det*(w[0][5]*w[1][10]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_11_1_0 = det*(w[0][5]*w[1][11]*K_00*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_0_11_1_1 = det*(w[0][5]*w[1][11]*K_00*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_1_0_0 = det*(w[0][5]*w[1][1]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_3_0_0 = det*(w[0][5]*w[1][3]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_3_0_1 = det*(w[0][5]*w[1][3]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_4_0_0 = det*(w[0][5]*w[1][4]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_5_0_0 = det*(w[0][5]*w[1][5]*K_10*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_5_0_1 = det*(w[0][5]*w[1][5]*K_10*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_7_1_0 = det*(w[0][5]*w[1][7]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_9_1_0 = det*(w[0][5]*w[1][9]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_9_1_1 = det*(w[0][5]*w[1][9]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_10_1_0 = det*(w[0][5]*w[1][10]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_11_1_0 = det*(w[0][5]*w[1][11]*K_10*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_5_0_1_11_1_1 = det*(w[0][5]*w[1][11]*K_10*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_0_0_0 = det*(w[0][6]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_0_0_1 = det*(w[0][6]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_1_0_0 = det*(w[0][6]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_2_0_1 = det*(w[0][6]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_4_0_1 = det*(w[0][6]*w[1][4]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_5_0_0 = det*(w[0][6]*w[1][5]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_6_1_0 = det*(w[0][6]*w[1][6]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_6_1_1 = det*(w[0][6]*w[1][6]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_7_1_0 = det*(w[0][6]*w[1][7]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_8_1_1 = det*(w[0][6]*w[1][8]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_10_1_1 = det*(w[0][6]*w[1][10]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_0_11_1_0 = det*(w[0][6]*w[1][11]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_0_0_0 = det*(w[0][6]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_0_0_1 = det*(w[0][6]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_1_0_0 = det*(w[0][6]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_2_0_1 = det*(w[0][6]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_4_0_1 = det*(w[0][6]*w[1][4]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_5_0_0 = det*(w[0][6]*w[1][5]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_6_1_0 = det*(w[0][6]*w[1][6]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_6_1_1 = det*(w[0][6]*w[1][6]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_7_1_0 = det*(w[0][6]*w[1][7]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_8_1_1 = det*(w[0][6]*w[1][8]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_10_1_1 = det*(w[0][6]*w[1][10]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_6_1_1_11_1_0 = det*(w[0][6]*w[1][11]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_0_0_0 = det*(w[0][7]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_0_0_1 = det*(w[0][7]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_1_0_0 = det*(w[0][7]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_2_0_1 = det*(w[0][7]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_3_0_1 = det*(w[0][7]*w[1][3]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_5_0_0 = det*(w[0][7]*w[1][5]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_5_0_1 = det*(w[0][7]*w[1][5]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_6_1_0 = det*(w[0][7]*w[1][6]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_6_1_1 = det*(w[0][7]*w[1][6]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_7_1_0 = det*(w[0][7]*w[1][7]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_8_1_1 = det*(w[0][7]*w[1][8]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_9_1_1 = det*(w[0][7]*w[1][9]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_11_1_0 = det*(w[0][7]*w[1][11]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_7_1_0_11_1_1 = det*(w[0][7]*w[1][11]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_0_0_0 = det*(w[0][8]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_0_0_1 = det*(w[0][8]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_1_0_0 = det*(w[0][8]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_2_0_1 = det*(w[0][8]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_3_0_0 = det*(w[0][8]*w[1][3]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_4_0_0 = det*(w[0][8]*w[1][4]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_4_0_1 = det*(w[0][8]*w[1][4]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_6_1_0 = det*(w[0][8]*w[1][6]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_6_1_1 = det*(w[0][8]*w[1][6]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_7_1_0 = det*(w[0][8]*w[1][7]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_8_1_1 = det*(w[0][8]*w[1][8]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_9_1_0 = det*(w[0][8]*w[1][9]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_10_1_0 = det*(w[0][8]*w[1][10]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_8_1_1_10_1_1 = det*(w[0][8]*w[1][10]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_2_0_1 = det*(w[0][9]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_3_0_0 = det*(w[0][9]*w[1][3]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_3_0_1 = det*(w[0][9]*w[1][3]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_4_0_0 = det*(w[0][9]*w[1][4]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_4_0_1 = det*(w[0][9]*w[1][4]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_5_0_1 = det*(w[0][9]*w[1][5]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_8_1_1 = det*(w[0][9]*w[1][8]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_9_1_0 = det*(w[0][9]*w[1][9]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_9_1_1 = det*(w[0][9]*w[1][9]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_10_1_0 = det*(w[0][9]*w[1][10]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_10_1_1 = det*(w[0][9]*w[1][10]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_0_11_1_1 = det*(w[0][9]*w[1][11]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_1_0_0 = det*(w[0][9]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_3_0_0 = det*(w[0][9]*w[1][3]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_3_0_1 = det*(w[0][9]*w[1][3]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_4_0_0 = det*(w[0][9]*w[1][4]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_5_0_0 = det*(w[0][9]*w[1][5]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_5_0_1 = det*(w[0][9]*w[1][5]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_7_1_0 = det*(w[0][9]*w[1][7]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_9_1_0 = det*(w[0][9]*w[1][9]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_9_1_1 = det*(w[0][9]*w[1][9]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_10_1_0 = det*(w[0][9]*w[1][10]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_11_1_0 = det*(w[0][9]*w[1][11]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_9_1_1_11_1_1 = det*(w[0][9]*w[1][11]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_2_0_1 = det*(w[0][10]*w[1][2]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_3_0_0 = det*(w[0][10]*w[1][3]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_3_0_1 = det*(w[0][10]*w[1][3]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_4_0_0 = det*(w[0][10]*w[1][4]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_4_0_1 = det*(w[0][10]*w[1][4]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_5_0_1 = det*(w[0][10]*w[1][5]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_8_1_1 = det*(w[0][10]*w[1][8]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_9_1_0 = det*(w[0][10]*w[1][9]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_9_1_1 = det*(w[0][10]*w[1][9]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_10_1_0 = det*(w[0][10]*w[1][10]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_10_1_1 = det*(w[0][10]*w[1][10]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_0_11_1_1 = det*(w[0][10]*w[1][11]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_0_0_0 = det*(w[0][10]*w[1][0]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_0_0_1 = det*(w[0][10]*w[1][0]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_2_0_1 = det*(w[0][10]*w[1][2]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_3_0_0 = det*(w[0][10]*w[1][3]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_4_0_0 = det*(w[0][10]*w[1][4]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_4_0_1 = det*(w[0][10]*w[1][4]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_5_0_0 = det*(w[0][10]*w[1][5]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_6_1_0 = det*(w[0][10]*w[1][6]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_6_1_1 = det*(w[0][10]*w[1][6]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_8_1_1 = det*(w[0][10]*w[1][8]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_9_1_0 = det*(w[0][10]*w[1][9]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_10_1_0 = det*(w[0][10]*w[1][10]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_10_1_1 = det*(w[0][10]*w[1][10]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_10_1_1_11_1_0 = det*(w[0][10]*w[1][11]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_0_0_0 = det*(w[0][11]*w[1][0]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_0_0_1 = det*(w[0][11]*w[1][0]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_1_0_0 = det*(w[0][11]*w[1][1]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_3_0_1 = det*(w[0][11]*w[1][3]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_4_0_1 = det*(w[0][11]*w[1][4]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_5_0_0 = det*(w[0][11]*w[1][5]*K_01*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_5_0_1 = det*(w[0][11]*w[1][5]*K_01*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_6_1_0 = det*(w[0][11]*w[1][6]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_6_1_1 = det*(w[0][11]*w[1][6]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_7_1_0 = det*(w[0][11]*w[1][7]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_9_1_1 = det*(w[0][11]*w[1][9]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_10_1_1 = det*(w[0][11]*w[1][10]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_11_1_0 = det*(w[0][11]*w[1][11]*K_01*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_0_11_1_1 = det*(w[0][11]*w[1][11]*K_01*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_1_0_0 = det*(w[0][11]*w[1][1]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_3_0_0 = det*(w[0][11]*w[1][3]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_3_0_1 = det*(w[0][11]*w[1][3]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_4_0_0 = det*(w[0][11]*w[1][4]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_5_0_0 = det*(w[0][11]*w[1][5]*K_11*K_00*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_5_0_1 = det*(w[0][11]*w[1][5]*K_11*K_10*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_7_1_0 = det*(w[0][11]*w[1][7]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_9_1_0 = det*(w[0][11]*w[1][9]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_9_1_1 = det*(w[0][11]*w[1][9]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_10_1_0 = det*(w[0][11]*w[1][10]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_11_1_0 = det*(w[0][11]*w[1][11]*K_11*K_01*((K_10*K_00 + K_11*K_01))); + const double G0_1_0_11_1_1_11_1_1 = det*(w[0][11]*w[1][11]*K_11*K_11*((K_10*K_00 + K_11*K_01))); + const double G0_1_1_0_0_0_0_0_0 = det*(w[0][0]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_0_0_1 = det*(w[0][0]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_1_0_0 = det*(w[0][0]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_2_0_1 = det*(w[0][0]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_4_0_1 = det*(w[0][0]*w[1][4]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_5_0_0 = det*(w[0][0]*w[1][5]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_6_1_0 = det*(w[0][0]*w[1][6]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_6_1_1 = det*(w[0][0]*w[1][6]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_7_1_0 = det*(w[0][0]*w[1][7]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_8_1_1 = det*(w[0][0]*w[1][8]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_10_1_1 = det*(w[0][0]*w[1][10]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_0_11_1_0 = det*(w[0][0]*w[1][11]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_0_0_0 = det*(w[0][0]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_0_0_1 = det*(w[0][0]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_1_0_0 = det*(w[0][0]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_2_0_1 = det*(w[0][0]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_4_0_1 = det*(w[0][0]*w[1][4]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_5_0_0 = det*(w[0][0]*w[1][5]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_6_1_0 = det*(w[0][0]*w[1][6]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_6_1_1 = det*(w[0][0]*w[1][6]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_7_1_0 = det*(w[0][0]*w[1][7]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_8_1_1 = det*(w[0][0]*w[1][8]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_10_1_1 = det*(w[0][0]*w[1][10]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_0_0_1_11_1_0 = det*(w[0][0]*w[1][11]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_0_0_0 = det*(w[0][1]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_0_0_1 = det*(w[0][1]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_1_0_0 = det*(w[0][1]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_2_0_1 = det*(w[0][1]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_3_0_1 = det*(w[0][1]*w[1][3]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_5_0_0 = det*(w[0][1]*w[1][5]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_5_0_1 = det*(w[0][1]*w[1][5]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_6_1_0 = det*(w[0][1]*w[1][6]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_6_1_1 = det*(w[0][1]*w[1][6]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_7_1_0 = det*(w[0][1]*w[1][7]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_8_1_1 = det*(w[0][1]*w[1][8]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_9_1_1 = det*(w[0][1]*w[1][9]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_11_1_0 = det*(w[0][1]*w[1][11]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_1_0_0_11_1_1 = det*(w[0][1]*w[1][11]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_0_0_0 = det*(w[0][2]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_0_0_1 = det*(w[0][2]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_1_0_0 = det*(w[0][2]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_2_0_1 = det*(w[0][2]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_3_0_0 = det*(w[0][2]*w[1][3]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_4_0_0 = det*(w[0][2]*w[1][4]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_4_0_1 = det*(w[0][2]*w[1][4]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_6_1_0 = det*(w[0][2]*w[1][6]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_6_1_1 = det*(w[0][2]*w[1][6]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_7_1_0 = det*(w[0][2]*w[1][7]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_8_1_1 = det*(w[0][2]*w[1][8]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_9_1_0 = det*(w[0][2]*w[1][9]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_10_1_0 = det*(w[0][2]*w[1][10]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_2_0_1_10_1_1 = det*(w[0][2]*w[1][10]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_2_0_1 = det*(w[0][3]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_3_0_0 = det*(w[0][3]*w[1][3]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_3_0_1 = det*(w[0][3]*w[1][3]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_4_0_0 = det*(w[0][3]*w[1][4]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_4_0_1 = det*(w[0][3]*w[1][4]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_5_0_1 = det*(w[0][3]*w[1][5]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_8_1_1 = det*(w[0][3]*w[1][8]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_9_1_0 = det*(w[0][3]*w[1][9]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_9_1_1 = det*(w[0][3]*w[1][9]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_10_1_0 = det*(w[0][3]*w[1][10]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_10_1_1 = det*(w[0][3]*w[1][10]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_0_11_1_1 = det*(w[0][3]*w[1][11]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_1_0_0 = det*(w[0][3]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_3_0_0 = det*(w[0][3]*w[1][3]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_3_0_1 = det*(w[0][3]*w[1][3]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_4_0_0 = det*(w[0][3]*w[1][4]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_5_0_0 = det*(w[0][3]*w[1][5]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_5_0_1 = det*(w[0][3]*w[1][5]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_7_1_0 = det*(w[0][3]*w[1][7]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_9_1_0 = det*(w[0][3]*w[1][9]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_9_1_1 = det*(w[0][3]*w[1][9]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_10_1_0 = det*(w[0][3]*w[1][10]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_11_1_0 = det*(w[0][3]*w[1][11]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_3_0_1_11_1_1 = det*(w[0][3]*w[1][11]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_2_0_1 = det*(w[0][4]*w[1][2]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_3_0_0 = det*(w[0][4]*w[1][3]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_3_0_1 = det*(w[0][4]*w[1][3]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_4_0_0 = det*(w[0][4]*w[1][4]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_4_0_1 = det*(w[0][4]*w[1][4]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_5_0_1 = det*(w[0][4]*w[1][5]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_8_1_1 = det*(w[0][4]*w[1][8]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_9_1_0 = det*(w[0][4]*w[1][9]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_9_1_1 = det*(w[0][4]*w[1][9]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_10_1_0 = det*(w[0][4]*w[1][10]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_10_1_1 = det*(w[0][4]*w[1][10]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_0_11_1_1 = det*(w[0][4]*w[1][11]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_0_0_0 = det*(w[0][4]*w[1][0]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_0_0_1 = det*(w[0][4]*w[1][0]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_2_0_1 = det*(w[0][4]*w[1][2]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_3_0_0 = det*(w[0][4]*w[1][3]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_4_0_0 = det*(w[0][4]*w[1][4]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_4_0_1 = det*(w[0][4]*w[1][4]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_5_0_0 = det*(w[0][4]*w[1][5]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_6_1_0 = det*(w[0][4]*w[1][6]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_6_1_1 = det*(w[0][4]*w[1][6]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_8_1_1 = det*(w[0][4]*w[1][8]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_9_1_0 = det*(w[0][4]*w[1][9]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_10_1_0 = det*(w[0][4]*w[1][10]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_10_1_1 = det*(w[0][4]*w[1][10]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_4_0_1_11_1_0 = det*(w[0][4]*w[1][11]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_0_0_0 = det*(w[0][5]*w[1][0]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_0_0_1 = det*(w[0][5]*w[1][0]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_1_0_0 = det*(w[0][5]*w[1][1]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_3_0_1 = det*(w[0][5]*w[1][3]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_4_0_1 = det*(w[0][5]*w[1][4]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_5_0_0 = det*(w[0][5]*w[1][5]*K_00*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_5_0_1 = det*(w[0][5]*w[1][5]*K_00*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_6_1_0 = det*(w[0][5]*w[1][6]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_6_1_1 = det*(w[0][5]*w[1][6]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_7_1_0 = det*(w[0][5]*w[1][7]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_9_1_1 = det*(w[0][5]*w[1][9]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_10_1_1 = det*(w[0][5]*w[1][10]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_11_1_0 = det*(w[0][5]*w[1][11]*K_00*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_0_11_1_1 = det*(w[0][5]*w[1][11]*K_00*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_1_0_0 = det*(w[0][5]*w[1][1]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_3_0_0 = det*(w[0][5]*w[1][3]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_3_0_1 = det*(w[0][5]*w[1][3]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_4_0_0 = det*(w[0][5]*w[1][4]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_5_0_0 = det*(w[0][5]*w[1][5]*K_10*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_5_0_1 = det*(w[0][5]*w[1][5]*K_10*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_7_1_0 = det*(w[0][5]*w[1][7]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_9_1_0 = det*(w[0][5]*w[1][9]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_9_1_1 = det*(w[0][5]*w[1][9]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_10_1_0 = det*(w[0][5]*w[1][10]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_11_1_0 = det*(w[0][5]*w[1][11]*K_10*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_5_0_1_11_1_1 = det*(w[0][5]*w[1][11]*K_10*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_0_0_0 = det*(w[0][6]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_0_0_1 = det*(w[0][6]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_1_0_0 = det*(w[0][6]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_2_0_1 = det*(w[0][6]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_4_0_1 = det*(w[0][6]*w[1][4]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_5_0_0 = det*(w[0][6]*w[1][5]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_6_1_0 = det*(w[0][6]*w[1][6]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_6_1_1 = det*(w[0][6]*w[1][6]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_7_1_0 = det*(w[0][6]*w[1][7]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_8_1_1 = det*(w[0][6]*w[1][8]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_10_1_1 = det*(w[0][6]*w[1][10]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_0_11_1_0 = det*(w[0][6]*w[1][11]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_0_0_0 = det*(w[0][6]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_0_0_1 = det*(w[0][6]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_1_0_0 = det*(w[0][6]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_2_0_1 = det*(w[0][6]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_4_0_1 = det*(w[0][6]*w[1][4]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_5_0_0 = det*(w[0][6]*w[1][5]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_6_1_0 = det*(w[0][6]*w[1][6]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_6_1_1 = det*(w[0][6]*w[1][6]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_7_1_0 = det*(w[0][6]*w[1][7]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_8_1_1 = det*(w[0][6]*w[1][8]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_10_1_1 = det*(w[0][6]*w[1][10]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_6_1_1_11_1_0 = det*(w[0][6]*w[1][11]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_0_0_0 = det*(w[0][7]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_0_0_1 = det*(w[0][7]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_1_0_0 = det*(w[0][7]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_2_0_1 = det*(w[0][7]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_3_0_1 = det*(w[0][7]*w[1][3]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_5_0_0 = det*(w[0][7]*w[1][5]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_5_0_1 = det*(w[0][7]*w[1][5]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_6_1_0 = det*(w[0][7]*w[1][6]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_6_1_1 = det*(w[0][7]*w[1][6]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_7_1_0 = det*(w[0][7]*w[1][7]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_8_1_1 = det*(w[0][7]*w[1][8]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_9_1_1 = det*(w[0][7]*w[1][9]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_11_1_0 = det*(w[0][7]*w[1][11]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_7_1_0_11_1_1 = det*(w[0][7]*w[1][11]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_0_0_0 = det*(w[0][8]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_0_0_1 = det*(w[0][8]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_1_0_0 = det*(w[0][8]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_2_0_1 = det*(w[0][8]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_3_0_0 = det*(w[0][8]*w[1][3]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_4_0_0 = det*(w[0][8]*w[1][4]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_4_0_1 = det*(w[0][8]*w[1][4]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_6_1_0 = det*(w[0][8]*w[1][6]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_6_1_1 = det*(w[0][8]*w[1][6]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_7_1_0 = det*(w[0][8]*w[1][7]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_8_1_1 = det*(w[0][8]*w[1][8]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_9_1_0 = det*(w[0][8]*w[1][9]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_10_1_0 = det*(w[0][8]*w[1][10]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_8_1_1_10_1_1 = det*(w[0][8]*w[1][10]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_2_0_1 = det*(w[0][9]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_3_0_0 = det*(w[0][9]*w[1][3]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_3_0_1 = det*(w[0][9]*w[1][3]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_4_0_0 = det*(w[0][9]*w[1][4]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_4_0_1 = det*(w[0][9]*w[1][4]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_5_0_1 = det*(w[0][9]*w[1][5]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_8_1_1 = det*(w[0][9]*w[1][8]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_9_1_0 = det*(w[0][9]*w[1][9]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_9_1_1 = det*(w[0][9]*w[1][9]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_10_1_0 = det*(w[0][9]*w[1][10]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_10_1_1 = det*(w[0][9]*w[1][10]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_0_11_1_1 = det*(w[0][9]*w[1][11]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_1_0_0 = det*(w[0][9]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_3_0_0 = det*(w[0][9]*w[1][3]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_3_0_1 = det*(w[0][9]*w[1][3]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_4_0_0 = det*(w[0][9]*w[1][4]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_5_0_0 = det*(w[0][9]*w[1][5]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_5_0_1 = det*(w[0][9]*w[1][5]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_7_1_0 = det*(w[0][9]*w[1][7]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_9_1_0 = det*(w[0][9]*w[1][9]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_9_1_1 = det*(w[0][9]*w[1][9]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_10_1_0 = det*(w[0][9]*w[1][10]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_11_1_0 = det*(w[0][9]*w[1][11]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_9_1_1_11_1_1 = det*(w[0][9]*w[1][11]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_2_0_1 = det*(w[0][10]*w[1][2]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_3_0_0 = det*(w[0][10]*w[1][3]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_3_0_1 = det*(w[0][10]*w[1][3]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_4_0_0 = det*(w[0][10]*w[1][4]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_4_0_1 = det*(w[0][10]*w[1][4]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_5_0_1 = det*(w[0][10]*w[1][5]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_8_1_1 = det*(w[0][10]*w[1][8]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_9_1_0 = det*(w[0][10]*w[1][9]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_9_1_1 = det*(w[0][10]*w[1][9]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_10_1_0 = det*(w[0][10]*w[1][10]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_10_1_1 = det*(w[0][10]*w[1][10]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_0_11_1_1 = det*(w[0][10]*w[1][11]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_0_0_0 = det*(w[0][10]*w[1][0]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_0_0_1 = det*(w[0][10]*w[1][0]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_2_0_1 = det*(w[0][10]*w[1][2]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_3_0_0 = det*(w[0][10]*w[1][3]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_4_0_0 = det*(w[0][10]*w[1][4]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_4_0_1 = det*(w[0][10]*w[1][4]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_5_0_0 = det*(w[0][10]*w[1][5]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_6_1_0 = det*(w[0][10]*w[1][6]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_6_1_1 = det*(w[0][10]*w[1][6]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_8_1_1 = det*(w[0][10]*w[1][8]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_9_1_0 = det*(w[0][10]*w[1][9]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_10_1_0 = det*(w[0][10]*w[1][10]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_10_1_1 = det*(w[0][10]*w[1][10]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_10_1_1_11_1_0 = det*(w[0][10]*w[1][11]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_0_0_0 = det*(w[0][11]*w[1][0]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_0_0_1 = det*(w[0][11]*w[1][0]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_1_0_0 = det*(w[0][11]*w[1][1]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_3_0_1 = det*(w[0][11]*w[1][3]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_4_0_1 = det*(w[0][11]*w[1][4]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_5_0_0 = det*(w[0][11]*w[1][5]*K_01*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_5_0_1 = det*(w[0][11]*w[1][5]*K_01*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_6_1_0 = det*(w[0][11]*w[1][6]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_6_1_1 = det*(w[0][11]*w[1][6]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_7_1_0 = det*(w[0][11]*w[1][7]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_9_1_1 = det*(w[0][11]*w[1][9]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_10_1_1 = det*(w[0][11]*w[1][10]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_11_1_0 = det*(w[0][11]*w[1][11]*K_01*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_0_11_1_1 = det*(w[0][11]*w[1][11]*K_01*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_1_0_0 = det*(w[0][11]*w[1][1]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_3_0_0 = det*(w[0][11]*w[1][3]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_3_0_1 = det*(w[0][11]*w[1][3]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_4_0_0 = det*(w[0][11]*w[1][4]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_5_0_0 = det*(w[0][11]*w[1][5]*K_11*K_00*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_5_0_1 = det*(w[0][11]*w[1][5]*K_11*K_10*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_7_1_0 = det*(w[0][11]*w[1][7]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_9_1_0 = det*(w[0][11]*w[1][9]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_9_1_1 = det*(w[0][11]*w[1][9]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_10_1_0 = det*(w[0][11]*w[1][10]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_11_1_0 = det*(w[0][11]*w[1][11]*K_11*K_01*((K_10*K_10 + K_11*K_11))); + const double G0_1_1_11_1_1_11_1_1 = det*(w[0][11]*w[1][11]*K_11*K_11*((K_10*K_10 + K_11*K_11))); + + // Compute element tensor + A[9] = 0.0; + A[18] = 0.0; + A[20] = 0.0; + A[31] = 0.0; + A[3] = 0.0; + A[17] = 0.0; + A[24] = 0.0; + A[8] = 0.5*G0_0_1_0_0_0_0_0_0 + 0.5*G0_0_1_0_0_0_0_0_1 + 0.166666666666667*G0_0_1_0_0_0_1_0_0 + 0.166666666666667*G0_0_1_0_0_0_2_0_1 - 0.666666666666667*G0_0_1_0_0_0_4_0_1 - 0.666666666666667*G0_0_1_0_0_0_5_0_0 + 0.5*G0_0_1_0_0_0_6_1_0 + 0.5*G0_0_1_0_0_0_6_1_1 + 0.166666666666667*G0_0_1_0_0_0_7_1_0 + 0.166666666666667*G0_0_1_0_0_0_8_1_1 - 0.666666666666667*G0_0_1_0_0_0_10_1_1 - 0.666666666666667*G0_0_1_0_0_0_11_1_0 + 0.5*G0_0_1_0_0_1_0_0_0 + 0.5*G0_0_1_0_0_1_0_0_1 + 0.166666666666667*G0_0_1_0_0_1_1_0_0 + 0.166666666666667*G0_0_1_0_0_1_2_0_1 - 0.666666666666667*G0_0_1_0_0_1_4_0_1 - 0.666666666666667*G0_0_1_0_0_1_5_0_0 + 0.5*G0_0_1_0_0_1_6_1_0 + 0.5*G0_0_1_0_0_1_6_1_1 + 0.166666666666667*G0_0_1_0_0_1_7_1_0 + 0.166666666666667*G0_0_1_0_0_1_8_1_1 - 0.666666666666667*G0_0_1_0_0_1_10_1_1 - 0.666666666666667*G0_0_1_0_0_1_11_1_0 + 0.166666666666667*G0_0_1_1_0_0_0_0_0 + 0.166666666666667*G0_0_1_1_0_0_0_0_1 + 0.5*G0_0_1_1_0_0_1_0_0 - 0.166666666666667*G0_0_1_1_0_0_2_0_1 + 0.666666666666666*G0_0_1_1_0_0_3_0_1 - 0.666666666666666*G0_0_1_1_0_0_5_0_0 - 0.666666666666666*G0_0_1_1_0_0_5_0_1 + 0.166666666666667*G0_0_1_1_0_0_6_1_0 + 0.166666666666667*G0_0_1_1_0_0_6_1_1 + 0.5*G0_0_1_1_0_0_7_1_0 - 0.166666666666667*G0_0_1_1_0_0_8_1_1 + 0.666666666666666*G0_0_1_1_0_0_9_1_1 - 0.666666666666666*G0_0_1_1_0_0_11_1_0 - 0.666666666666666*G0_0_1_1_0_0_11_1_1 + 0.166666666666667*G0_0_1_2_0_1_0_0_0 + 0.166666666666667*G0_0_1_2_0_1_0_0_1 - 0.166666666666667*G0_0_1_2_0_1_1_0_0 + 0.5*G0_0_1_2_0_1_2_0_1 + 0.666666666666666*G0_0_1_2_0_1_3_0_0 - 0.666666666666666*G0_0_1_2_0_1_4_0_0 - 0.666666666666666*G0_0_1_2_0_1_4_0_1 + 0.166666666666667*G0_0_1_2_0_1_6_1_0 + 0.166666666666667*G0_0_1_2_0_1_6_1_1 - 0.166666666666667*G0_0_1_2_0_1_7_1_0 + 0.5*G0_0_1_2_0_1_8_1_1 + 0.666666666666666*G0_0_1_2_0_1_9_1_0 - 0.666666666666666*G0_0_1_2_0_1_10_1_0 - 0.666666666666666*G0_0_1_2_0_1_10_1_1 + 0.666666666666666*G0_0_1_3_0_0_2_0_1 + 1.33333333333333*G0_0_1_3_0_0_3_0_0 + 0.666666666666665*G0_0_1_3_0_0_3_0_1 - 1.33333333333333*G0_0_1_3_0_0_4_0_0 - 0.666666666666666*G0_0_1_3_0_0_4_0_1 - 0.666666666666665*G0_0_1_3_0_0_5_0_1 + 0.666666666666666*G0_0_1_3_0_0_8_1_1 + 1.33333333333333*G0_0_1_3_0_0_9_1_0 + 0.666666666666665*G0_0_1_3_0_0_9_1_1 - 1.33333333333333*G0_0_1_3_0_0_10_1_0 - 0.666666666666666*G0_0_1_3_0_0_10_1_1 - 0.666666666666665*G0_0_1_3_0_0_11_1_1 + 0.666666666666666*G0_0_1_3_0_1_1_0_0 + 0.666666666666665*G0_0_1_3_0_1_3_0_0 + 1.33333333333333*G0_0_1_3_0_1_3_0_1 - 0.666666666666665*G0_0_1_3_0_1_4_0_0 - 0.666666666666665*G0_0_1_3_0_1_5_0_0 - 1.33333333333333*G0_0_1_3_0_1_5_0_1 + 0.666666666666666*G0_0_1_3_0_1_7_1_0 + 0.666666666666665*G0_0_1_3_0_1_9_1_0 + 1.33333333333333*G0_0_1_3_0_1_9_1_1 - 0.666666666666665*G0_0_1_3_0_1_10_1_0 - 0.666666666666665*G0_0_1_3_0_1_11_1_0 - 1.33333333333333*G0_0_1_3_0_1_11_1_1 - 0.666666666666666*G0_0_1_4_0_0_2_0_1 - 1.33333333333333*G0_0_1_4_0_0_3_0_0 - 0.666666666666665*G0_0_1_4_0_0_3_0_1 + 1.33333333333333*G0_0_1_4_0_0_4_0_0 + 0.666666666666666*G0_0_1_4_0_0_4_0_1 + 0.666666666666665*G0_0_1_4_0_0_5_0_1 - 0.666666666666666*G0_0_1_4_0_0_8_1_1 - 1.33333333333333*G0_0_1_4_0_0_9_1_0 - 0.666666666666665*G0_0_1_4_0_0_9_1_1 + 1.33333333333333*G0_0_1_4_0_0_10_1_0 + 0.666666666666666*G0_0_1_4_0_0_10_1_1 + 0.666666666666665*G0_0_1_4_0_0_11_1_1 - 0.666666666666667*G0_0_1_4_0_1_0_0_0 - 0.666666666666667*G0_0_1_4_0_1_0_0_1 - 0.666666666666666*G0_0_1_4_0_1_2_0_1 - 0.666666666666666*G0_0_1_4_0_1_3_0_0 + 0.666666666666666*G0_0_1_4_0_1_4_0_0 + 1.33333333333333*G0_0_1_4_0_1_4_0_1 + 0.666666666666667*G0_0_1_4_0_1_5_0_0 - 0.666666666666667*G0_0_1_4_0_1_6_1_0 - 0.666666666666667*G0_0_1_4_0_1_6_1_1 - 0.666666666666666*G0_0_1_4_0_1_8_1_1 - 0.666666666666666*G0_0_1_4_0_1_9_1_0 + 0.666666666666666*G0_0_1_4_0_1_10_1_0 + 1.33333333333333*G0_0_1_4_0_1_10_1_1 + 0.666666666666667*G0_0_1_4_0_1_11_1_0 - 0.666666666666667*G0_0_1_5_0_0_0_0_0 - 0.666666666666667*G0_0_1_5_0_0_0_0_1 - 0.666666666666666*G0_0_1_5_0_0_1_0_0 - 0.666666666666665*G0_0_1_5_0_0_3_0_1 + 0.666666666666667*G0_0_1_5_0_0_4_0_1 + 1.33333333333333*G0_0_1_5_0_0_5_0_0 + 0.666666666666666*G0_0_1_5_0_0_5_0_1 - 0.666666666666667*G0_0_1_5_0_0_6_1_0 - 0.666666666666667*G0_0_1_5_0_0_6_1_1 - 0.666666666666666*G0_0_1_5_0_0_7_1_0 - 0.666666666666665*G0_0_1_5_0_0_9_1_1 + 0.666666666666667*G0_0_1_5_0_0_10_1_1 + 1.33333333333333*G0_0_1_5_0_0_11_1_0 + 0.666666666666666*G0_0_1_5_0_0_11_1_1 - 0.666666666666666*G0_0_1_5_0_1_1_0_0 - 0.666666666666666*G0_0_1_5_0_1_3_0_0 - 1.33333333333333*G0_0_1_5_0_1_3_0_1 + 0.666666666666666*G0_0_1_5_0_1_4_0_0 + 0.666666666666666*G0_0_1_5_0_1_5_0_0 + 1.33333333333333*G0_0_1_5_0_1_5_0_1 - 0.666666666666666*G0_0_1_5_0_1_7_1_0 - 0.666666666666666*G0_0_1_5_0_1_9_1_0 - 1.33333333333333*G0_0_1_5_0_1_9_1_1 + 0.666666666666666*G0_0_1_5_0_1_10_1_0 + 0.666666666666666*G0_0_1_5_0_1_11_1_0 + 1.33333333333333*G0_0_1_5_0_1_11_1_1 + 0.5*G0_0_1_6_1_0_0_0_0 + 0.5*G0_0_1_6_1_0_0_0_1 + 0.166666666666667*G0_0_1_6_1_0_1_0_0 + 0.166666666666667*G0_0_1_6_1_0_2_0_1 - 0.666666666666667*G0_0_1_6_1_0_4_0_1 - 0.666666666666667*G0_0_1_6_1_0_5_0_0 + 0.5*G0_0_1_6_1_0_6_1_0 + 0.5*G0_0_1_6_1_0_6_1_1 + 0.166666666666667*G0_0_1_6_1_0_7_1_0 + 0.166666666666667*G0_0_1_6_1_0_8_1_1 - 0.666666666666667*G0_0_1_6_1_0_10_1_1 - 0.666666666666667*G0_0_1_6_1_0_11_1_0 + 0.5*G0_0_1_6_1_1_0_0_0 + 0.5*G0_0_1_6_1_1_0_0_1 + 0.166666666666667*G0_0_1_6_1_1_1_0_0 + 0.166666666666667*G0_0_1_6_1_1_2_0_1 - 0.666666666666667*G0_0_1_6_1_1_4_0_1 - 0.666666666666667*G0_0_1_6_1_1_5_0_0 + 0.5*G0_0_1_6_1_1_6_1_0 + 0.5*G0_0_1_6_1_1_6_1_1 + 0.166666666666667*G0_0_1_6_1_1_7_1_0 + 0.166666666666667*G0_0_1_6_1_1_8_1_1 - 0.666666666666667*G0_0_1_6_1_1_10_1_1 - 0.666666666666667*G0_0_1_6_1_1_11_1_0 + 0.166666666666667*G0_0_1_7_1_0_0_0_0 + 0.166666666666667*G0_0_1_7_1_0_0_0_1 + 0.5*G0_0_1_7_1_0_1_0_0 - 0.166666666666667*G0_0_1_7_1_0_2_0_1 + 0.666666666666666*G0_0_1_7_1_0_3_0_1 - 0.666666666666666*G0_0_1_7_1_0_5_0_0 - 0.666666666666666*G0_0_1_7_1_0_5_0_1 + 0.166666666666667*G0_0_1_7_1_0_6_1_0 + 0.166666666666667*G0_0_1_7_1_0_6_1_1 + 0.5*G0_0_1_7_1_0_7_1_0 - 0.166666666666667*G0_0_1_7_1_0_8_1_1 + 0.666666666666666*G0_0_1_7_1_0_9_1_1 - 0.666666666666666*G0_0_1_7_1_0_11_1_0 - 0.666666666666666*G0_0_1_7_1_0_11_1_1 + 0.166666666666667*G0_0_1_8_1_1_0_0_0 + 0.166666666666667*G0_0_1_8_1_1_0_0_1 - 0.166666666666667*G0_0_1_8_1_1_1_0_0 + 0.5*G0_0_1_8_1_1_2_0_1 + 0.666666666666666*G0_0_1_8_1_1_3_0_0 - 0.666666666666666*G0_0_1_8_1_1_4_0_0 - 0.666666666666666*G0_0_1_8_1_1_4_0_1 + 0.166666666666667*G0_0_1_8_1_1_6_1_0 + 0.166666666666667*G0_0_1_8_1_1_6_1_1 - 0.166666666666667*G0_0_1_8_1_1_7_1_0 + 0.5*G0_0_1_8_1_1_8_1_1 + 0.666666666666666*G0_0_1_8_1_1_9_1_0 - 0.666666666666666*G0_0_1_8_1_1_10_1_0 - 0.666666666666666*G0_0_1_8_1_1_10_1_1 + 0.666666666666666*G0_0_1_9_1_0_2_0_1 + 1.33333333333333*G0_0_1_9_1_0_3_0_0 + 0.666666666666665*G0_0_1_9_1_0_3_0_1 - 1.33333333333333*G0_0_1_9_1_0_4_0_0 - 0.666666666666666*G0_0_1_9_1_0_4_0_1 - 0.666666666666665*G0_0_1_9_1_0_5_0_1 + 0.666666666666666*G0_0_1_9_1_0_8_1_1 + 1.33333333333333*G0_0_1_9_1_0_9_1_0 + 0.666666666666665*G0_0_1_9_1_0_9_1_1 - 1.33333333333333*G0_0_1_9_1_0_10_1_0 - 0.666666666666666*G0_0_1_9_1_0_10_1_1 - 0.666666666666665*G0_0_1_9_1_0_11_1_1 + 0.666666666666666*G0_0_1_9_1_1_1_0_0 + 0.666666666666665*G0_0_1_9_1_1_3_0_0 + 1.33333333333333*G0_0_1_9_1_1_3_0_1 - 0.666666666666665*G0_0_1_9_1_1_4_0_0 - 0.666666666666665*G0_0_1_9_1_1_5_0_0 - 1.33333333333333*G0_0_1_9_1_1_5_0_1 + 0.666666666666666*G0_0_1_9_1_1_7_1_0 + 0.666666666666665*G0_0_1_9_1_1_9_1_0 + 1.33333333333333*G0_0_1_9_1_1_9_1_1 - 0.666666666666665*G0_0_1_9_1_1_10_1_0 - 0.666666666666665*G0_0_1_9_1_1_11_1_0 - 1.33333333333333*G0_0_1_9_1_1_11_1_1 - 0.666666666666666*G0_0_1_10_1_0_2_0_1 - 1.33333333333333*G0_0_1_10_1_0_3_0_0 - 0.666666666666665*G0_0_1_10_1_0_3_0_1 + 1.33333333333333*G0_0_1_10_1_0_4_0_0 + 0.666666666666666*G0_0_1_10_1_0_4_0_1 + 0.666666666666665*G0_0_1_10_1_0_5_0_1 - 0.666666666666666*G0_0_1_10_1_0_8_1_1 - 1.33333333333333*G0_0_1_10_1_0_9_1_0 - 0.666666666666665*G0_0_1_10_1_0_9_1_1 + 1.33333333333333*G0_0_1_10_1_0_10_1_0 + 0.666666666666666*G0_0_1_10_1_0_10_1_1 + 0.666666666666665*G0_0_1_10_1_0_11_1_1 - 0.666666666666667*G0_0_1_10_1_1_0_0_0 - 0.666666666666667*G0_0_1_10_1_1_0_0_1 - 0.666666666666666*G0_0_1_10_1_1_2_0_1 - 0.666666666666666*G0_0_1_10_1_1_3_0_0 + 0.666666666666666*G0_0_1_10_1_1_4_0_0 + 1.33333333333333*G0_0_1_10_1_1_4_0_1 + 0.666666666666667*G0_0_1_10_1_1_5_0_0 - 0.666666666666667*G0_0_1_10_1_1_6_1_0 - 0.666666666666667*G0_0_1_10_1_1_6_1_1 - 0.666666666666666*G0_0_1_10_1_1_8_1_1 - 0.666666666666666*G0_0_1_10_1_1_9_1_0 + 0.666666666666666*G0_0_1_10_1_1_10_1_0 + 1.33333333333333*G0_0_1_10_1_1_10_1_1 + 0.666666666666667*G0_0_1_10_1_1_11_1_0 - 0.666666666666667*G0_0_1_11_1_0_0_0_0 - 0.666666666666667*G0_0_1_11_1_0_0_0_1 - 0.666666666666666*G0_0_1_11_1_0_1_0_0 - 0.666666666666665*G0_0_1_11_1_0_3_0_1 + 0.666666666666667*G0_0_1_11_1_0_4_0_1 + 1.33333333333333*G0_0_1_11_1_0_5_0_0 + 0.666666666666666*G0_0_1_11_1_0_5_0_1 - 0.666666666666667*G0_0_1_11_1_0_6_1_0 - 0.666666666666667*G0_0_1_11_1_0_6_1_1 - 0.666666666666666*G0_0_1_11_1_0_7_1_0 - 0.666666666666665*G0_0_1_11_1_0_9_1_1 + 0.666666666666667*G0_0_1_11_1_0_10_1_1 + 1.33333333333333*G0_0_1_11_1_0_11_1_0 + 0.666666666666666*G0_0_1_11_1_0_11_1_1 - 0.666666666666666*G0_0_1_11_1_1_1_0_0 - 0.666666666666666*G0_0_1_11_1_1_3_0_0 - 1.33333333333333*G0_0_1_11_1_1_3_0_1 + 0.666666666666666*G0_0_1_11_1_1_4_0_0 + 0.666666666666666*G0_0_1_11_1_1_5_0_0 + 1.33333333333333*G0_0_1_11_1_1_5_0_1 - 0.666666666666666*G0_0_1_11_1_1_7_1_0 - 0.666666666666666*G0_0_1_11_1_1_9_1_0 - 1.33333333333333*G0_0_1_11_1_1_9_1_1 + 0.666666666666666*G0_0_1_11_1_1_10_1_0 + 0.666666666666666*G0_0_1_11_1_1_11_1_0 + 1.33333333333333*G0_0_1_11_1_1_11_1_1; + A[28] = 0.5*G0_0_0_0_0_0_0_0_0 + 0.5*G0_0_0_0_0_0_0_0_1 + 0.166666666666667*G0_0_0_0_0_0_1_0_0 + 0.166666666666667*G0_0_0_0_0_0_2_0_1 - 0.666666666666667*G0_0_0_0_0_0_4_0_1 - 0.666666666666667*G0_0_0_0_0_0_5_0_0 + 0.5*G0_0_0_0_0_0_6_1_0 + 0.5*G0_0_0_0_0_0_6_1_1 + 0.166666666666667*G0_0_0_0_0_0_7_1_0 + 0.166666666666667*G0_0_0_0_0_0_8_1_1 - 0.666666666666667*G0_0_0_0_0_0_10_1_1 - 0.666666666666667*G0_0_0_0_0_0_11_1_0 + 0.5*G0_0_0_0_0_1_0_0_0 + 0.5*G0_0_0_0_0_1_0_0_1 + 0.166666666666667*G0_0_0_0_0_1_1_0_0 + 0.166666666666667*G0_0_0_0_0_1_2_0_1 - 0.666666666666667*G0_0_0_0_0_1_4_0_1 - 0.666666666666667*G0_0_0_0_0_1_5_0_0 + 0.5*G0_0_0_0_0_1_6_1_0 + 0.5*G0_0_0_0_0_1_6_1_1 + 0.166666666666667*G0_0_0_0_0_1_7_1_0 + 0.166666666666667*G0_0_0_0_0_1_8_1_1 - 0.666666666666667*G0_0_0_0_0_1_10_1_1 - 0.666666666666667*G0_0_0_0_0_1_11_1_0 + 0.166666666666667*G0_0_0_1_0_0_0_0_0 + 0.166666666666667*G0_0_0_1_0_0_0_0_1 + 0.5*G0_0_0_1_0_0_1_0_0 - 0.166666666666667*G0_0_0_1_0_0_2_0_1 + 0.666666666666666*G0_0_0_1_0_0_3_0_1 - 0.666666666666667*G0_0_0_1_0_0_5_0_0 - 0.666666666666666*G0_0_0_1_0_0_5_0_1 + 0.166666666666667*G0_0_0_1_0_0_6_1_0 + 0.166666666666667*G0_0_0_1_0_0_6_1_1 + 0.5*G0_0_0_1_0_0_7_1_0 - 0.166666666666667*G0_0_0_1_0_0_8_1_1 + 0.666666666666666*G0_0_0_1_0_0_9_1_1 - 0.666666666666667*G0_0_0_1_0_0_11_1_0 - 0.666666666666666*G0_0_0_1_0_0_11_1_1 + 0.166666666666667*G0_0_0_2_0_1_0_0_0 + 0.166666666666667*G0_0_0_2_0_1_0_0_1 - 0.166666666666667*G0_0_0_2_0_1_1_0_0 + 0.5*G0_0_0_2_0_1_2_0_1 + 0.666666666666666*G0_0_0_2_0_1_3_0_0 - 0.666666666666666*G0_0_0_2_0_1_4_0_0 - 0.666666666666666*G0_0_0_2_0_1_4_0_1 + 0.166666666666667*G0_0_0_2_0_1_6_1_0 + 0.166666666666667*G0_0_0_2_0_1_6_1_1 - 0.166666666666667*G0_0_0_2_0_1_7_1_0 + 0.5*G0_0_0_2_0_1_8_1_1 + 0.666666666666666*G0_0_0_2_0_1_9_1_0 - 0.666666666666666*G0_0_0_2_0_1_10_1_0 - 0.666666666666666*G0_0_0_2_0_1_10_1_1 + 0.666666666666666*G0_0_0_3_0_0_2_0_1 + 1.33333333333333*G0_0_0_3_0_0_3_0_0 + 0.666666666666665*G0_0_0_3_0_0_3_0_1 - 1.33333333333333*G0_0_0_3_0_0_4_0_0 - 0.666666666666666*G0_0_0_3_0_0_4_0_1 - 0.666666666666666*G0_0_0_3_0_0_5_0_1 + 0.666666666666666*G0_0_0_3_0_0_8_1_1 + 1.33333333333333*G0_0_0_3_0_0_9_1_0 + 0.666666666666665*G0_0_0_3_0_0_9_1_1 - 1.33333333333333*G0_0_0_3_0_0_10_1_0 - 0.666666666666666*G0_0_0_3_0_0_10_1_1 - 0.666666666666666*G0_0_0_3_0_0_11_1_1 + 0.666666666666666*G0_0_0_3_0_1_1_0_0 + 0.666666666666665*G0_0_0_3_0_1_3_0_0 + 1.33333333333333*G0_0_0_3_0_1_3_0_1 - 0.666666666666665*G0_0_0_3_0_1_4_0_0 - 0.666666666666666*G0_0_0_3_0_1_5_0_0 - 1.33333333333333*G0_0_0_3_0_1_5_0_1 + 0.666666666666666*G0_0_0_3_0_1_7_1_0 + 0.666666666666665*G0_0_0_3_0_1_9_1_0 + 1.33333333333333*G0_0_0_3_0_1_9_1_1 - 0.666666666666665*G0_0_0_3_0_1_10_1_0 - 0.666666666666666*G0_0_0_3_0_1_11_1_0 - 1.33333333333333*G0_0_0_3_0_1_11_1_1 - 0.666666666666666*G0_0_0_4_0_0_2_0_1 - 1.33333333333333*G0_0_0_4_0_0_3_0_0 - 0.666666666666665*G0_0_0_4_0_0_3_0_1 + 1.33333333333333*G0_0_0_4_0_0_4_0_0 + 0.666666666666666*G0_0_0_4_0_0_4_0_1 + 0.666666666666666*G0_0_0_4_0_0_5_0_1 - 0.666666666666666*G0_0_0_4_0_0_8_1_1 - 1.33333333333333*G0_0_0_4_0_0_9_1_0 - 0.666666666666665*G0_0_0_4_0_0_9_1_1 + 1.33333333333333*G0_0_0_4_0_0_10_1_0 + 0.666666666666666*G0_0_0_4_0_0_10_1_1 + 0.666666666666666*G0_0_0_4_0_0_11_1_1 - 0.666666666666667*G0_0_0_4_0_1_0_0_0 - 0.666666666666667*G0_0_0_4_0_1_0_0_1 - 0.666666666666666*G0_0_0_4_0_1_2_0_1 - 0.666666666666666*G0_0_0_4_0_1_3_0_0 + 0.666666666666666*G0_0_0_4_0_1_4_0_0 + 1.33333333333333*G0_0_0_4_0_1_4_0_1 + 0.666666666666667*G0_0_0_4_0_1_5_0_0 - 0.666666666666667*G0_0_0_4_0_1_6_1_0 - 0.666666666666667*G0_0_0_4_0_1_6_1_1 - 0.666666666666666*G0_0_0_4_0_1_8_1_1 - 0.666666666666666*G0_0_0_4_0_1_9_1_0 + 0.666666666666666*G0_0_0_4_0_1_10_1_0 + 1.33333333333333*G0_0_0_4_0_1_10_1_1 + 0.666666666666667*G0_0_0_4_0_1_11_1_0 - 0.666666666666667*G0_0_0_5_0_0_0_0_0 - 0.666666666666667*G0_0_0_5_0_0_0_0_1 - 0.666666666666666*G0_0_0_5_0_0_1_0_0 - 0.666666666666666*G0_0_0_5_0_0_3_0_1 + 0.666666666666667*G0_0_0_5_0_0_4_0_1 + 1.33333333333333*G0_0_0_5_0_0_5_0_0 + 0.666666666666666*G0_0_0_5_0_0_5_0_1 - 0.666666666666667*G0_0_0_5_0_0_6_1_0 - 0.666666666666667*G0_0_0_5_0_0_6_1_1 - 0.666666666666666*G0_0_0_5_0_0_7_1_0 - 0.666666666666666*G0_0_0_5_0_0_9_1_1 + 0.666666666666667*G0_0_0_5_0_0_10_1_1 + 1.33333333333333*G0_0_0_5_0_0_11_1_0 + 0.666666666666666*G0_0_0_5_0_0_11_1_1 - 0.666666666666666*G0_0_0_5_0_1_1_0_0 - 0.666666666666666*G0_0_0_5_0_1_3_0_0 - 1.33333333333333*G0_0_0_5_0_1_3_0_1 + 0.666666666666666*G0_0_0_5_0_1_4_0_0 + 0.666666666666666*G0_0_0_5_0_1_5_0_0 + 1.33333333333333*G0_0_0_5_0_1_5_0_1 - 0.666666666666666*G0_0_0_5_0_1_7_1_0 - 0.666666666666666*G0_0_0_5_0_1_9_1_0 - 1.33333333333333*G0_0_0_5_0_1_9_1_1 + 0.666666666666666*G0_0_0_5_0_1_10_1_0 + 0.666666666666666*G0_0_0_5_0_1_11_1_0 + 1.33333333333333*G0_0_0_5_0_1_11_1_1 + 0.5*G0_0_0_6_1_0_0_0_0 + 0.5*G0_0_0_6_1_0_0_0_1 + 0.166666666666667*G0_0_0_6_1_0_1_0_0 + 0.166666666666667*G0_0_0_6_1_0_2_0_1 - 0.666666666666667*G0_0_0_6_1_0_4_0_1 - 0.666666666666667*G0_0_0_6_1_0_5_0_0 + 0.5*G0_0_0_6_1_0_6_1_0 + 0.5*G0_0_0_6_1_0_6_1_1 + 0.166666666666667*G0_0_0_6_1_0_7_1_0 + 0.166666666666667*G0_0_0_6_1_0_8_1_1 - 0.666666666666667*G0_0_0_6_1_0_10_1_1 - 0.666666666666667*G0_0_0_6_1_0_11_1_0 + 0.5*G0_0_0_6_1_1_0_0_0 + 0.5*G0_0_0_6_1_1_0_0_1 + 0.166666666666667*G0_0_0_6_1_1_1_0_0 + 0.166666666666667*G0_0_0_6_1_1_2_0_1 - 0.666666666666667*G0_0_0_6_1_1_4_0_1 - 0.666666666666667*G0_0_0_6_1_1_5_0_0 + 0.5*G0_0_0_6_1_1_6_1_0 + 0.5*G0_0_0_6_1_1_6_1_1 + 0.166666666666667*G0_0_0_6_1_1_7_1_0 + 0.166666666666667*G0_0_0_6_1_1_8_1_1 - 0.666666666666667*G0_0_0_6_1_1_10_1_1 - 0.666666666666667*G0_0_0_6_1_1_11_1_0 + 0.166666666666667*G0_0_0_7_1_0_0_0_0 + 0.166666666666667*G0_0_0_7_1_0_0_0_1 + 0.5*G0_0_0_7_1_0_1_0_0 - 0.166666666666667*G0_0_0_7_1_0_2_0_1 + 0.666666666666666*G0_0_0_7_1_0_3_0_1 - 0.666666666666667*G0_0_0_7_1_0_5_0_0 - 0.666666666666666*G0_0_0_7_1_0_5_0_1 + 0.166666666666667*G0_0_0_7_1_0_6_1_0 + 0.166666666666667*G0_0_0_7_1_0_6_1_1 + 0.5*G0_0_0_7_1_0_7_1_0 - 0.166666666666667*G0_0_0_7_1_0_8_1_1 + 0.666666666666666*G0_0_0_7_1_0_9_1_1 - 0.666666666666667*G0_0_0_7_1_0_11_1_0 - 0.666666666666666*G0_0_0_7_1_0_11_1_1 + 0.166666666666667*G0_0_0_8_1_1_0_0_0 + 0.166666666666667*G0_0_0_8_1_1_0_0_1 - 0.166666666666667*G0_0_0_8_1_1_1_0_0 + 0.5*G0_0_0_8_1_1_2_0_1 + 0.666666666666666*G0_0_0_8_1_1_3_0_0 - 0.666666666666666*G0_0_0_8_1_1_4_0_0 - 0.666666666666666*G0_0_0_8_1_1_4_0_1 + 0.166666666666667*G0_0_0_8_1_1_6_1_0 + 0.166666666666667*G0_0_0_8_1_1_6_1_1 - 0.166666666666667*G0_0_0_8_1_1_7_1_0 + 0.5*G0_0_0_8_1_1_8_1_1 + 0.666666666666666*G0_0_0_8_1_1_9_1_0 - 0.666666666666666*G0_0_0_8_1_1_10_1_0 - 0.666666666666666*G0_0_0_8_1_1_10_1_1 + 0.666666666666666*G0_0_0_9_1_0_2_0_1 + 1.33333333333333*G0_0_0_9_1_0_3_0_0 + 0.666666666666665*G0_0_0_9_1_0_3_0_1 - 1.33333333333333*G0_0_0_9_1_0_4_0_0 - 0.666666666666666*G0_0_0_9_1_0_4_0_1 - 0.666666666666666*G0_0_0_9_1_0_5_0_1 + 0.666666666666666*G0_0_0_9_1_0_8_1_1 + 1.33333333333333*G0_0_0_9_1_0_9_1_0 + 0.666666666666665*G0_0_0_9_1_0_9_1_1 - 1.33333333333333*G0_0_0_9_1_0_10_1_0 - 0.666666666666666*G0_0_0_9_1_0_10_1_1 - 0.666666666666666*G0_0_0_9_1_0_11_1_1 + 0.666666666666666*G0_0_0_9_1_1_1_0_0 + 0.666666666666665*G0_0_0_9_1_1_3_0_0 + 1.33333333333333*G0_0_0_9_1_1_3_0_1 - 0.666666666666665*G0_0_0_9_1_1_4_0_0 - 0.666666666666666*G0_0_0_9_1_1_5_0_0 - 1.33333333333333*G0_0_0_9_1_1_5_0_1 + 0.666666666666666*G0_0_0_9_1_1_7_1_0 + 0.666666666666665*G0_0_0_9_1_1_9_1_0 + 1.33333333333333*G0_0_0_9_1_1_9_1_1 - 0.666666666666665*G0_0_0_9_1_1_10_1_0 - 0.666666666666666*G0_0_0_9_1_1_11_1_0 - 1.33333333333333*G0_0_0_9_1_1_11_1_1 - 0.666666666666666*G0_0_0_10_1_0_2_0_1 - 1.33333333333333*G0_0_0_10_1_0_3_0_0 - 0.666666666666665*G0_0_0_10_1_0_3_0_1 + 1.33333333333333*G0_0_0_10_1_0_4_0_0 + 0.666666666666666*G0_0_0_10_1_0_4_0_1 + 0.666666666666666*G0_0_0_10_1_0_5_0_1 - 0.666666666666666*G0_0_0_10_1_0_8_1_1 - 1.33333333333333*G0_0_0_10_1_0_9_1_0 - 0.666666666666665*G0_0_0_10_1_0_9_1_1 + 1.33333333333333*G0_0_0_10_1_0_10_1_0 + 0.666666666666666*G0_0_0_10_1_0_10_1_1 + 0.666666666666666*G0_0_0_10_1_0_11_1_1 - 0.666666666666667*G0_0_0_10_1_1_0_0_0 - 0.666666666666667*G0_0_0_10_1_1_0_0_1 - 0.666666666666666*G0_0_0_10_1_1_2_0_1 - 0.666666666666666*G0_0_0_10_1_1_3_0_0 + 0.666666666666666*G0_0_0_10_1_1_4_0_0 + 1.33333333333333*G0_0_0_10_1_1_4_0_1 + 0.666666666666667*G0_0_0_10_1_1_5_0_0 - 0.666666666666667*G0_0_0_10_1_1_6_1_0 - 0.666666666666667*G0_0_0_10_1_1_6_1_1 - 0.666666666666666*G0_0_0_10_1_1_8_1_1 - 0.666666666666666*G0_0_0_10_1_1_9_1_0 + 0.666666666666666*G0_0_0_10_1_1_10_1_0 + 1.33333333333333*G0_0_0_10_1_1_10_1_1 + 0.666666666666667*G0_0_0_10_1_1_11_1_0 - 0.666666666666667*G0_0_0_11_1_0_0_0_0 - 0.666666666666667*G0_0_0_11_1_0_0_0_1 - 0.666666666666666*G0_0_0_11_1_0_1_0_0 - 0.666666666666666*G0_0_0_11_1_0_3_0_1 + 0.666666666666667*G0_0_0_11_1_0_4_0_1 + 1.33333333333333*G0_0_0_11_1_0_5_0_0 + 0.666666666666666*G0_0_0_11_1_0_5_0_1 - 0.666666666666667*G0_0_0_11_1_0_6_1_0 - 0.666666666666667*G0_0_0_11_1_0_6_1_1 - 0.666666666666666*G0_0_0_11_1_0_7_1_0 - 0.666666666666666*G0_0_0_11_1_0_9_1_1 + 0.666666666666667*G0_0_0_11_1_0_10_1_1 + 1.33333333333333*G0_0_0_11_1_0_11_1_0 + 0.666666666666666*G0_0_0_11_1_0_11_1_1 - 0.666666666666666*G0_0_0_11_1_1_1_0_0 - 0.666666666666666*G0_0_0_11_1_1_3_0_0 - 1.33333333333333*G0_0_0_11_1_1_3_0_1 + 0.666666666666666*G0_0_0_11_1_1_4_0_0 + 0.666666666666666*G0_0_0_11_1_1_5_0_0 + 1.33333333333333*G0_0_0_11_1_1_5_0_1 - 0.666666666666666*G0_0_0_11_1_1_7_1_0 - 0.666666666666666*G0_0_0_11_1_1_9_1_0 - 1.33333333333333*G0_0_0_11_1_1_9_1_1 + 0.666666666666666*G0_0_0_11_1_1_10_1_0 + 0.666666666666666*G0_0_0_11_1_1_11_1_0 + 1.33333333333333*G0_0_0_11_1_1_11_1_1; + A[11] = 0.0; + A[30] = 0.0; + A[4] = 0.0; + A[25] = 0.0; + A[7] = A[28]; + A[34] = 0.5*G0_1_0_0_0_0_0_0_0 + 0.5*G0_1_0_0_0_0_0_0_1 + 0.166666666666667*G0_1_0_0_0_0_1_0_0 + 0.166666666666667*G0_1_0_0_0_0_2_0_1 - 0.666666666666667*G0_1_0_0_0_0_4_0_1 - 0.666666666666667*G0_1_0_0_0_0_5_0_0 + 0.5*G0_1_0_0_0_0_6_1_0 + 0.5*G0_1_0_0_0_0_6_1_1 + 0.166666666666667*G0_1_0_0_0_0_7_1_0 + 0.166666666666667*G0_1_0_0_0_0_8_1_1 - 0.666666666666667*G0_1_0_0_0_0_10_1_1 - 0.666666666666667*G0_1_0_0_0_0_11_1_0 + 0.5*G0_1_0_0_0_1_0_0_0 + 0.5*G0_1_0_0_0_1_0_0_1 + 0.166666666666667*G0_1_0_0_0_1_1_0_0 + 0.166666666666667*G0_1_0_0_0_1_2_0_1 - 0.666666666666667*G0_1_0_0_0_1_4_0_1 - 0.666666666666667*G0_1_0_0_0_1_5_0_0 + 0.5*G0_1_0_0_0_1_6_1_0 + 0.5*G0_1_0_0_0_1_6_1_1 + 0.166666666666667*G0_1_0_0_0_1_7_1_0 + 0.166666666666667*G0_1_0_0_0_1_8_1_1 - 0.666666666666667*G0_1_0_0_0_1_10_1_1 - 0.666666666666667*G0_1_0_0_0_1_11_1_0 + 0.166666666666667*G0_1_0_1_0_0_0_0_0 + 0.166666666666667*G0_1_0_1_0_0_0_0_1 + 0.5*G0_1_0_1_0_0_1_0_0 - 0.166666666666667*G0_1_0_1_0_0_2_0_1 + 0.666666666666666*G0_1_0_1_0_0_3_0_1 - 0.666666666666666*G0_1_0_1_0_0_5_0_0 - 0.666666666666666*G0_1_0_1_0_0_5_0_1 + 0.166666666666667*G0_1_0_1_0_0_6_1_0 + 0.166666666666667*G0_1_0_1_0_0_6_1_1 + 0.5*G0_1_0_1_0_0_7_1_0 - 0.166666666666667*G0_1_0_1_0_0_8_1_1 + 0.666666666666666*G0_1_0_1_0_0_9_1_1 - 0.666666666666666*G0_1_0_1_0_0_11_1_0 - 0.666666666666666*G0_1_0_1_0_0_11_1_1 + 0.166666666666667*G0_1_0_2_0_1_0_0_0 + 0.166666666666667*G0_1_0_2_0_1_0_0_1 - 0.166666666666667*G0_1_0_2_0_1_1_0_0 + 0.5*G0_1_0_2_0_1_2_0_1 + 0.666666666666666*G0_1_0_2_0_1_3_0_0 - 0.666666666666666*G0_1_0_2_0_1_4_0_0 - 0.666666666666666*G0_1_0_2_0_1_4_0_1 + 0.166666666666667*G0_1_0_2_0_1_6_1_0 + 0.166666666666667*G0_1_0_2_0_1_6_1_1 - 0.166666666666667*G0_1_0_2_0_1_7_1_0 + 0.5*G0_1_0_2_0_1_8_1_1 + 0.666666666666666*G0_1_0_2_0_1_9_1_0 - 0.666666666666666*G0_1_0_2_0_1_10_1_0 - 0.666666666666666*G0_1_0_2_0_1_10_1_1 + 0.666666666666666*G0_1_0_3_0_0_2_0_1 + 1.33333333333333*G0_1_0_3_0_0_3_0_0 + 0.666666666666665*G0_1_0_3_0_0_3_0_1 - 1.33333333333333*G0_1_0_3_0_0_4_0_0 - 0.666666666666666*G0_1_0_3_0_0_4_0_1 - 0.666666666666665*G0_1_0_3_0_0_5_0_1 + 0.666666666666666*G0_1_0_3_0_0_8_1_1 + 1.33333333333333*G0_1_0_3_0_0_9_1_0 + 0.666666666666665*G0_1_0_3_0_0_9_1_1 - 1.33333333333333*G0_1_0_3_0_0_10_1_0 - 0.666666666666666*G0_1_0_3_0_0_10_1_1 - 0.666666666666665*G0_1_0_3_0_0_11_1_1 + 0.666666666666666*G0_1_0_3_0_1_1_0_0 + 0.666666666666665*G0_1_0_3_0_1_3_0_0 + 1.33333333333333*G0_1_0_3_0_1_3_0_1 - 0.666666666666665*G0_1_0_3_0_1_4_0_0 - 0.666666666666665*G0_1_0_3_0_1_5_0_0 - 1.33333333333333*G0_1_0_3_0_1_5_0_1 + 0.666666666666666*G0_1_0_3_0_1_7_1_0 + 0.666666666666665*G0_1_0_3_0_1_9_1_0 + 1.33333333333333*G0_1_0_3_0_1_9_1_1 - 0.666666666666665*G0_1_0_3_0_1_10_1_0 - 0.666666666666665*G0_1_0_3_0_1_11_1_0 - 1.33333333333333*G0_1_0_3_0_1_11_1_1 - 0.666666666666666*G0_1_0_4_0_0_2_0_1 - 1.33333333333333*G0_1_0_4_0_0_3_0_0 - 0.666666666666665*G0_1_0_4_0_0_3_0_1 + 1.33333333333333*G0_1_0_4_0_0_4_0_0 + 0.666666666666666*G0_1_0_4_0_0_4_0_1 + 0.666666666666665*G0_1_0_4_0_0_5_0_1 - 0.666666666666666*G0_1_0_4_0_0_8_1_1 - 1.33333333333333*G0_1_0_4_0_0_9_1_0 - 0.666666666666665*G0_1_0_4_0_0_9_1_1 + 1.33333333333333*G0_1_0_4_0_0_10_1_0 + 0.666666666666666*G0_1_0_4_0_0_10_1_1 + 0.666666666666665*G0_1_0_4_0_0_11_1_1 - 0.666666666666667*G0_1_0_4_0_1_0_0_0 - 0.666666666666667*G0_1_0_4_0_1_0_0_1 - 0.666666666666666*G0_1_0_4_0_1_2_0_1 - 0.666666666666666*G0_1_0_4_0_1_3_0_0 + 0.666666666666666*G0_1_0_4_0_1_4_0_0 + 1.33333333333333*G0_1_0_4_0_1_4_0_1 + 0.666666666666667*G0_1_0_4_0_1_5_0_0 - 0.666666666666667*G0_1_0_4_0_1_6_1_0 - 0.666666666666667*G0_1_0_4_0_1_6_1_1 - 0.666666666666666*G0_1_0_4_0_1_8_1_1 - 0.666666666666666*G0_1_0_4_0_1_9_1_0 + 0.666666666666666*G0_1_0_4_0_1_10_1_0 + 1.33333333333333*G0_1_0_4_0_1_10_1_1 + 0.666666666666667*G0_1_0_4_0_1_11_1_0 - 0.666666666666667*G0_1_0_5_0_0_0_0_0 - 0.666666666666667*G0_1_0_5_0_0_0_0_1 - 0.666666666666666*G0_1_0_5_0_0_1_0_0 - 0.666666666666665*G0_1_0_5_0_0_3_0_1 + 0.666666666666667*G0_1_0_5_0_0_4_0_1 + 1.33333333333333*G0_1_0_5_0_0_5_0_0 + 0.666666666666666*G0_1_0_5_0_0_5_0_1 - 0.666666666666667*G0_1_0_5_0_0_6_1_0 - 0.666666666666667*G0_1_0_5_0_0_6_1_1 - 0.666666666666666*G0_1_0_5_0_0_7_1_0 - 0.666666666666665*G0_1_0_5_0_0_9_1_1 + 0.666666666666667*G0_1_0_5_0_0_10_1_1 + 1.33333333333333*G0_1_0_5_0_0_11_1_0 + 0.666666666666666*G0_1_0_5_0_0_11_1_1 - 0.666666666666666*G0_1_0_5_0_1_1_0_0 - 0.666666666666666*G0_1_0_5_0_1_3_0_0 - 1.33333333333333*G0_1_0_5_0_1_3_0_1 + 0.666666666666666*G0_1_0_5_0_1_4_0_0 + 0.666666666666666*G0_1_0_5_0_1_5_0_0 + 1.33333333333333*G0_1_0_5_0_1_5_0_1 - 0.666666666666666*G0_1_0_5_0_1_7_1_0 - 0.666666666666666*G0_1_0_5_0_1_9_1_0 - 1.33333333333333*G0_1_0_5_0_1_9_1_1 + 0.666666666666666*G0_1_0_5_0_1_10_1_0 + 0.666666666666666*G0_1_0_5_0_1_11_1_0 + 1.33333333333333*G0_1_0_5_0_1_11_1_1 + 0.5*G0_1_0_6_1_0_0_0_0 + 0.5*G0_1_0_6_1_0_0_0_1 + 0.166666666666667*G0_1_0_6_1_0_1_0_0 + 0.166666666666667*G0_1_0_6_1_0_2_0_1 - 0.666666666666667*G0_1_0_6_1_0_4_0_1 - 0.666666666666667*G0_1_0_6_1_0_5_0_0 + 0.5*G0_1_0_6_1_0_6_1_0 + 0.5*G0_1_0_6_1_0_6_1_1 + 0.166666666666667*G0_1_0_6_1_0_7_1_0 + 0.166666666666667*G0_1_0_6_1_0_8_1_1 - 0.666666666666667*G0_1_0_6_1_0_10_1_1 - 0.666666666666667*G0_1_0_6_1_0_11_1_0 + 0.5*G0_1_0_6_1_1_0_0_0 + 0.5*G0_1_0_6_1_1_0_0_1 + 0.166666666666667*G0_1_0_6_1_1_1_0_0 + 0.166666666666667*G0_1_0_6_1_1_2_0_1 - 0.666666666666667*G0_1_0_6_1_1_4_0_1 - 0.666666666666667*G0_1_0_6_1_1_5_0_0 + 0.5*G0_1_0_6_1_1_6_1_0 + 0.5*G0_1_0_6_1_1_6_1_1 + 0.166666666666667*G0_1_0_6_1_1_7_1_0 + 0.166666666666667*G0_1_0_6_1_1_8_1_1 - 0.666666666666667*G0_1_0_6_1_1_10_1_1 - 0.666666666666667*G0_1_0_6_1_1_11_1_0 + 0.166666666666667*G0_1_0_7_1_0_0_0_0 + 0.166666666666667*G0_1_0_7_1_0_0_0_1 + 0.5*G0_1_0_7_1_0_1_0_0 - 0.166666666666667*G0_1_0_7_1_0_2_0_1 + 0.666666666666666*G0_1_0_7_1_0_3_0_1 - 0.666666666666666*G0_1_0_7_1_0_5_0_0 - 0.666666666666666*G0_1_0_7_1_0_5_0_1 + 0.166666666666667*G0_1_0_7_1_0_6_1_0 + 0.166666666666667*G0_1_0_7_1_0_6_1_1 + 0.5*G0_1_0_7_1_0_7_1_0 - 0.166666666666667*G0_1_0_7_1_0_8_1_1 + 0.666666666666666*G0_1_0_7_1_0_9_1_1 - 0.666666666666666*G0_1_0_7_1_0_11_1_0 - 0.666666666666666*G0_1_0_7_1_0_11_1_1 + 0.166666666666667*G0_1_0_8_1_1_0_0_0 + 0.166666666666667*G0_1_0_8_1_1_0_0_1 - 0.166666666666667*G0_1_0_8_1_1_1_0_0 + 0.5*G0_1_0_8_1_1_2_0_1 + 0.666666666666666*G0_1_0_8_1_1_3_0_0 - 0.666666666666666*G0_1_0_8_1_1_4_0_0 - 0.666666666666666*G0_1_0_8_1_1_4_0_1 + 0.166666666666667*G0_1_0_8_1_1_6_1_0 + 0.166666666666667*G0_1_0_8_1_1_6_1_1 - 0.166666666666667*G0_1_0_8_1_1_7_1_0 + 0.5*G0_1_0_8_1_1_8_1_1 + 0.666666666666666*G0_1_0_8_1_1_9_1_0 - 0.666666666666666*G0_1_0_8_1_1_10_1_0 - 0.666666666666666*G0_1_0_8_1_1_10_1_1 + 0.666666666666666*G0_1_0_9_1_0_2_0_1 + 1.33333333333333*G0_1_0_9_1_0_3_0_0 + 0.666666666666665*G0_1_0_9_1_0_3_0_1 - 1.33333333333333*G0_1_0_9_1_0_4_0_0 - 0.666666666666666*G0_1_0_9_1_0_4_0_1 - 0.666666666666665*G0_1_0_9_1_0_5_0_1 + 0.666666666666666*G0_1_0_9_1_0_8_1_1 + 1.33333333333333*G0_1_0_9_1_0_9_1_0 + 0.666666666666665*G0_1_0_9_1_0_9_1_1 - 1.33333333333333*G0_1_0_9_1_0_10_1_0 - 0.666666666666666*G0_1_0_9_1_0_10_1_1 - 0.666666666666665*G0_1_0_9_1_0_11_1_1 + 0.666666666666666*G0_1_0_9_1_1_1_0_0 + 0.666666666666665*G0_1_0_9_1_1_3_0_0 + 1.33333333333333*G0_1_0_9_1_1_3_0_1 - 0.666666666666665*G0_1_0_9_1_1_4_0_0 - 0.666666666666665*G0_1_0_9_1_1_5_0_0 - 1.33333333333333*G0_1_0_9_1_1_5_0_1 + 0.666666666666666*G0_1_0_9_1_1_7_1_0 + 0.666666666666665*G0_1_0_9_1_1_9_1_0 + 1.33333333333333*G0_1_0_9_1_1_9_1_1 - 0.666666666666665*G0_1_0_9_1_1_10_1_0 - 0.666666666666665*G0_1_0_9_1_1_11_1_0 - 1.33333333333333*G0_1_0_9_1_1_11_1_1 - 0.666666666666666*G0_1_0_10_1_0_2_0_1 - 1.33333333333333*G0_1_0_10_1_0_3_0_0 - 0.666666666666665*G0_1_0_10_1_0_3_0_1 + 1.33333333333333*G0_1_0_10_1_0_4_0_0 + 0.666666666666666*G0_1_0_10_1_0_4_0_1 + 0.666666666666665*G0_1_0_10_1_0_5_0_1 - 0.666666666666666*G0_1_0_10_1_0_8_1_1 - 1.33333333333333*G0_1_0_10_1_0_9_1_0 - 0.666666666666665*G0_1_0_10_1_0_9_1_1 + 1.33333333333333*G0_1_0_10_1_0_10_1_0 + 0.666666666666666*G0_1_0_10_1_0_10_1_1 + 0.666666666666665*G0_1_0_10_1_0_11_1_1 - 0.666666666666667*G0_1_0_10_1_1_0_0_0 - 0.666666666666667*G0_1_0_10_1_1_0_0_1 - 0.666666666666666*G0_1_0_10_1_1_2_0_1 - 0.666666666666666*G0_1_0_10_1_1_3_0_0 + 0.666666666666666*G0_1_0_10_1_1_4_0_0 + 1.33333333333333*G0_1_0_10_1_1_4_0_1 + 0.666666666666667*G0_1_0_10_1_1_5_0_0 - 0.666666666666667*G0_1_0_10_1_1_6_1_0 - 0.666666666666667*G0_1_0_10_1_1_6_1_1 - 0.666666666666666*G0_1_0_10_1_1_8_1_1 - 0.666666666666666*G0_1_0_10_1_1_9_1_0 + 0.666666666666666*G0_1_0_10_1_1_10_1_0 + 1.33333333333333*G0_1_0_10_1_1_10_1_1 + 0.666666666666667*G0_1_0_10_1_1_11_1_0 - 0.666666666666667*G0_1_0_11_1_0_0_0_0 - 0.666666666666667*G0_1_0_11_1_0_0_0_1 - 0.666666666666666*G0_1_0_11_1_0_1_0_0 - 0.666666666666665*G0_1_0_11_1_0_3_0_1 + 0.666666666666667*G0_1_0_11_1_0_4_0_1 + 1.33333333333333*G0_1_0_11_1_0_5_0_0 + 0.666666666666666*G0_1_0_11_1_0_5_0_1 - 0.666666666666667*G0_1_0_11_1_0_6_1_0 - 0.666666666666667*G0_1_0_11_1_0_6_1_1 - 0.666666666666666*G0_1_0_11_1_0_7_1_0 - 0.666666666666665*G0_1_0_11_1_0_9_1_1 + 0.666666666666667*G0_1_0_11_1_0_10_1_1 + 1.33333333333333*G0_1_0_11_1_0_11_1_0 + 0.666666666666666*G0_1_0_11_1_0_11_1_1 - 0.666666666666666*G0_1_0_11_1_1_1_0_0 - 0.666666666666666*G0_1_0_11_1_1_3_0_0 - 1.33333333333333*G0_1_0_11_1_1_3_0_1 + 0.666666666666666*G0_1_0_11_1_1_4_0_0 + 0.666666666666666*G0_1_0_11_1_1_5_0_0 + 1.33333333333333*G0_1_0_11_1_1_5_0_1 - 0.666666666666666*G0_1_0_11_1_1_7_1_0 - 0.666666666666666*G0_1_0_11_1_1_9_1_0 - 1.33333333333333*G0_1_0_11_1_1_9_1_1 + 0.666666666666666*G0_1_0_11_1_1_10_1_0 + 0.666666666666666*G0_1_0_11_1_1_11_1_0 + 1.33333333333333*G0_1_0_11_1_1_11_1_1; + A[13] = A[34]; + A[33] = -A[34] - 0.5*G0_1_1_0_0_0_0_0_0 - 0.5*G0_1_1_0_0_0_0_0_1 - 0.166666666666667*G0_1_1_0_0_0_1_0_0 - 0.166666666666667*G0_1_1_0_0_0_2_0_1 + 0.666666666666667*G0_1_1_0_0_0_4_0_1 + 0.666666666666667*G0_1_1_0_0_0_5_0_0 - 0.5*G0_1_1_0_0_0_6_1_0 - 0.5*G0_1_1_0_0_0_6_1_1 - 0.166666666666667*G0_1_1_0_0_0_7_1_0 - 0.166666666666667*G0_1_1_0_0_0_8_1_1 + 0.666666666666667*G0_1_1_0_0_0_10_1_1 + 0.666666666666667*G0_1_1_0_0_0_11_1_0 - 0.5*G0_1_1_0_0_1_0_0_0 - 0.5*G0_1_1_0_0_1_0_0_1 - 0.166666666666667*G0_1_1_0_0_1_1_0_0 - 0.166666666666667*G0_1_1_0_0_1_2_0_1 + 0.666666666666667*G0_1_1_0_0_1_4_0_1 + 0.666666666666667*G0_1_1_0_0_1_5_0_0 - 0.5*G0_1_1_0_0_1_6_1_0 - 0.5*G0_1_1_0_0_1_6_1_1 - 0.166666666666667*G0_1_1_0_0_1_7_1_0 - 0.166666666666667*G0_1_1_0_0_1_8_1_1 + 0.666666666666667*G0_1_1_0_0_1_10_1_1 + 0.666666666666667*G0_1_1_0_0_1_11_1_0 - 0.166666666666667*G0_1_1_1_0_0_0_0_0 - 0.166666666666667*G0_1_1_1_0_0_0_0_1 - 0.5*G0_1_1_1_0_0_1_0_0 + 0.166666666666667*G0_1_1_1_0_0_2_0_1 - 0.666666666666666*G0_1_1_1_0_0_3_0_1 + 0.666666666666666*G0_1_1_1_0_0_5_0_0 + 0.666666666666666*G0_1_1_1_0_0_5_0_1 - 0.166666666666667*G0_1_1_1_0_0_6_1_0 - 0.166666666666667*G0_1_1_1_0_0_6_1_1 - 0.5*G0_1_1_1_0_0_7_1_0 + 0.166666666666667*G0_1_1_1_0_0_8_1_1 - 0.666666666666666*G0_1_1_1_0_0_9_1_1 + 0.666666666666666*G0_1_1_1_0_0_11_1_0 + 0.666666666666666*G0_1_1_1_0_0_11_1_1 - 0.166666666666667*G0_1_1_2_0_1_0_0_0 - 0.166666666666667*G0_1_1_2_0_1_0_0_1 + 0.166666666666667*G0_1_1_2_0_1_1_0_0 - 0.5*G0_1_1_2_0_1_2_0_1 - 0.666666666666666*G0_1_1_2_0_1_3_0_0 + 0.666666666666666*G0_1_1_2_0_1_4_0_0 + 0.666666666666666*G0_1_1_2_0_1_4_0_1 - 0.166666666666667*G0_1_1_2_0_1_6_1_0 - 0.166666666666667*G0_1_1_2_0_1_6_1_1 + 0.166666666666667*G0_1_1_2_0_1_7_1_0 - 0.5*G0_1_1_2_0_1_8_1_1 - 0.666666666666666*G0_1_1_2_0_1_9_1_0 + 0.666666666666666*G0_1_1_2_0_1_10_1_0 + 0.666666666666666*G0_1_1_2_0_1_10_1_1 - 0.666666666666666*G0_1_1_3_0_0_2_0_1 - 1.33333333333333*G0_1_1_3_0_0_3_0_0 - 0.666666666666665*G0_1_1_3_0_0_3_0_1 + 1.33333333333333*G0_1_1_3_0_0_4_0_0 + 0.666666666666665*G0_1_1_3_0_0_4_0_1 + 0.666666666666665*G0_1_1_3_0_0_5_0_1 - 0.666666666666666*G0_1_1_3_0_0_8_1_1 - 1.33333333333333*G0_1_1_3_0_0_9_1_0 - 0.666666666666665*G0_1_1_3_0_0_9_1_1 + 1.33333333333333*G0_1_1_3_0_0_10_1_0 + 0.666666666666665*G0_1_1_3_0_0_10_1_1 + 0.666666666666665*G0_1_1_3_0_0_11_1_1 - 0.666666666666666*G0_1_1_3_0_1_1_0_0 - 0.666666666666665*G0_1_1_3_0_1_3_0_0 - 1.33333333333333*G0_1_1_3_0_1_3_0_1 + 0.666666666666665*G0_1_1_3_0_1_4_0_0 + 0.666666666666665*G0_1_1_3_0_1_5_0_0 + 1.33333333333333*G0_1_1_3_0_1_5_0_1 - 0.666666666666666*G0_1_1_3_0_1_7_1_0 - 0.666666666666665*G0_1_1_3_0_1_9_1_0 - 1.33333333333333*G0_1_1_3_0_1_9_1_1 + 0.666666666666665*G0_1_1_3_0_1_10_1_0 + 0.666666666666665*G0_1_1_3_0_1_11_1_0 + 1.33333333333333*G0_1_1_3_0_1_11_1_1 + 0.666666666666666*G0_1_1_4_0_0_2_0_1 + 1.33333333333333*G0_1_1_4_0_0_3_0_0 + 0.666666666666665*G0_1_1_4_0_0_3_0_1 - 1.33333333333333*G0_1_1_4_0_0_4_0_0 - 0.666666666666665*G0_1_1_4_0_0_4_0_1 - 0.666666666666665*G0_1_1_4_0_0_5_0_1 + 0.666666666666666*G0_1_1_4_0_0_8_1_1 + 1.33333333333333*G0_1_1_4_0_0_9_1_0 + 0.666666666666665*G0_1_1_4_0_0_9_1_1 - 1.33333333333333*G0_1_1_4_0_0_10_1_0 - 0.666666666666665*G0_1_1_4_0_0_10_1_1 - 0.666666666666665*G0_1_1_4_0_0_11_1_1 + 0.666666666666667*G0_1_1_4_0_1_0_0_0 + 0.666666666666667*G0_1_1_4_0_1_0_0_1 + 0.666666666666666*G0_1_1_4_0_1_2_0_1 + 0.666666666666665*G0_1_1_4_0_1_3_0_0 - 0.666666666666665*G0_1_1_4_0_1_4_0_0 - 1.33333333333333*G0_1_1_4_0_1_4_0_1 - 0.666666666666667*G0_1_1_4_0_1_5_0_0 + 0.666666666666667*G0_1_1_4_0_1_6_1_0 + 0.666666666666667*G0_1_1_4_0_1_6_1_1 + 0.666666666666666*G0_1_1_4_0_1_8_1_1 + 0.666666666666665*G0_1_1_4_0_1_9_1_0 - 0.666666666666665*G0_1_1_4_0_1_10_1_0 - 1.33333333333333*G0_1_1_4_0_1_10_1_1 - 0.666666666666667*G0_1_1_4_0_1_11_1_0 + 0.666666666666667*G0_1_1_5_0_0_0_0_0 + 0.666666666666667*G0_1_1_5_0_0_0_0_1 + 0.666666666666666*G0_1_1_5_0_0_1_0_0 + 0.666666666666665*G0_1_1_5_0_0_3_0_1 - 0.666666666666667*G0_1_1_5_0_0_4_0_1 - 1.33333333333333*G0_1_1_5_0_0_5_0_0 - 0.666666666666665*G0_1_1_5_0_0_5_0_1 + 0.666666666666667*G0_1_1_5_0_0_6_1_0 + 0.666666666666667*G0_1_1_5_0_0_6_1_1 + 0.666666666666666*G0_1_1_5_0_0_7_1_0 + 0.666666666666665*G0_1_1_5_0_0_9_1_1 - 0.666666666666667*G0_1_1_5_0_0_10_1_1 - 1.33333333333333*G0_1_1_5_0_0_11_1_0 - 0.666666666666665*G0_1_1_5_0_0_11_1_1 + 0.666666666666666*G0_1_1_5_0_1_1_0_0 + 0.666666666666665*G0_1_1_5_0_1_3_0_0 + 1.33333333333333*G0_1_1_5_0_1_3_0_1 - 0.666666666666665*G0_1_1_5_0_1_4_0_0 - 0.666666666666665*G0_1_1_5_0_1_5_0_0 - 1.33333333333333*G0_1_1_5_0_1_5_0_1 + 0.666666666666666*G0_1_1_5_0_1_7_1_0 + 0.666666666666665*G0_1_1_5_0_1_9_1_0 + 1.33333333333333*G0_1_1_5_0_1_9_1_1 - 0.666666666666665*G0_1_1_5_0_1_10_1_0 - 0.666666666666665*G0_1_1_5_0_1_11_1_0 - 1.33333333333333*G0_1_1_5_0_1_11_1_1 - 0.5*G0_1_1_6_1_0_0_0_0 - 0.5*G0_1_1_6_1_0_0_0_1 - 0.166666666666667*G0_1_1_6_1_0_1_0_0 - 0.166666666666667*G0_1_1_6_1_0_2_0_1 + 0.666666666666667*G0_1_1_6_1_0_4_0_1 + 0.666666666666667*G0_1_1_6_1_0_5_0_0 - 0.5*G0_1_1_6_1_0_6_1_0 - 0.5*G0_1_1_6_1_0_6_1_1 - 0.166666666666667*G0_1_1_6_1_0_7_1_0 - 0.166666666666667*G0_1_1_6_1_0_8_1_1 + 0.666666666666667*G0_1_1_6_1_0_10_1_1 + 0.666666666666667*G0_1_1_6_1_0_11_1_0 - 0.5*G0_1_1_6_1_1_0_0_0 - 0.5*G0_1_1_6_1_1_0_0_1 - 0.166666666666667*G0_1_1_6_1_1_1_0_0 - 0.166666666666667*G0_1_1_6_1_1_2_0_1 + 0.666666666666667*G0_1_1_6_1_1_4_0_1 + 0.666666666666667*G0_1_1_6_1_1_5_0_0 - 0.5*G0_1_1_6_1_1_6_1_0 - 0.5*G0_1_1_6_1_1_6_1_1 - 0.166666666666667*G0_1_1_6_1_1_7_1_0 - 0.166666666666667*G0_1_1_6_1_1_8_1_1 + 0.666666666666667*G0_1_1_6_1_1_10_1_1 + 0.666666666666667*G0_1_1_6_1_1_11_1_0 - 0.166666666666667*G0_1_1_7_1_0_0_0_0 - 0.166666666666667*G0_1_1_7_1_0_0_0_1 - 0.5*G0_1_1_7_1_0_1_0_0 + 0.166666666666667*G0_1_1_7_1_0_2_0_1 - 0.666666666666666*G0_1_1_7_1_0_3_0_1 + 0.666666666666666*G0_1_1_7_1_0_5_0_0 + 0.666666666666666*G0_1_1_7_1_0_5_0_1 - 0.166666666666667*G0_1_1_7_1_0_6_1_0 - 0.166666666666667*G0_1_1_7_1_0_6_1_1 - 0.5*G0_1_1_7_1_0_7_1_0 + 0.166666666666667*G0_1_1_7_1_0_8_1_1 - 0.666666666666666*G0_1_1_7_1_0_9_1_1 + 0.666666666666666*G0_1_1_7_1_0_11_1_0 + 0.666666666666666*G0_1_1_7_1_0_11_1_1 - 0.166666666666667*G0_1_1_8_1_1_0_0_0 - 0.166666666666667*G0_1_1_8_1_1_0_0_1 + 0.166666666666667*G0_1_1_8_1_1_1_0_0 - 0.5*G0_1_1_8_1_1_2_0_1 - 0.666666666666666*G0_1_1_8_1_1_3_0_0 + 0.666666666666666*G0_1_1_8_1_1_4_0_0 + 0.666666666666666*G0_1_1_8_1_1_4_0_1 - 0.166666666666667*G0_1_1_8_1_1_6_1_0 - 0.166666666666667*G0_1_1_8_1_1_6_1_1 + 0.166666666666667*G0_1_1_8_1_1_7_1_0 - 0.5*G0_1_1_8_1_1_8_1_1 - 0.666666666666666*G0_1_1_8_1_1_9_1_0 + 0.666666666666666*G0_1_1_8_1_1_10_1_0 + 0.666666666666666*G0_1_1_8_1_1_10_1_1 - 0.666666666666666*G0_1_1_9_1_0_2_0_1 - 1.33333333333333*G0_1_1_9_1_0_3_0_0 - 0.666666666666665*G0_1_1_9_1_0_3_0_1 + 1.33333333333333*G0_1_1_9_1_0_4_0_0 + 0.666666666666665*G0_1_1_9_1_0_4_0_1 + 0.666666666666665*G0_1_1_9_1_0_5_0_1 - 0.666666666666666*G0_1_1_9_1_0_8_1_1 - 1.33333333333333*G0_1_1_9_1_0_9_1_0 - 0.666666666666665*G0_1_1_9_1_0_9_1_1 + 1.33333333333333*G0_1_1_9_1_0_10_1_0 + 0.666666666666665*G0_1_1_9_1_0_10_1_1 + 0.666666666666665*G0_1_1_9_1_0_11_1_1 - 0.666666666666666*G0_1_1_9_1_1_1_0_0 - 0.666666666666665*G0_1_1_9_1_1_3_0_0 - 1.33333333333333*G0_1_1_9_1_1_3_0_1 + 0.666666666666665*G0_1_1_9_1_1_4_0_0 + 0.666666666666665*G0_1_1_9_1_1_5_0_0 + 1.33333333333333*G0_1_1_9_1_1_5_0_1 - 0.666666666666666*G0_1_1_9_1_1_7_1_0 - 0.666666666666665*G0_1_1_9_1_1_9_1_0 - 1.33333333333333*G0_1_1_9_1_1_9_1_1 + 0.666666666666665*G0_1_1_9_1_1_10_1_0 + 0.666666666666665*G0_1_1_9_1_1_11_1_0 + 1.33333333333333*G0_1_1_9_1_1_11_1_1 + 0.666666666666666*G0_1_1_10_1_0_2_0_1 + 1.33333333333333*G0_1_1_10_1_0_3_0_0 + 0.666666666666665*G0_1_1_10_1_0_3_0_1 - 1.33333333333333*G0_1_1_10_1_0_4_0_0 - 0.666666666666665*G0_1_1_10_1_0_4_0_1 - 0.666666666666665*G0_1_1_10_1_0_5_0_1 + 0.666666666666666*G0_1_1_10_1_0_8_1_1 + 1.33333333333333*G0_1_1_10_1_0_9_1_0 + 0.666666666666665*G0_1_1_10_1_0_9_1_1 - 1.33333333333333*G0_1_1_10_1_0_10_1_0 - 0.666666666666665*G0_1_1_10_1_0_10_1_1 - 0.666666666666665*G0_1_1_10_1_0_11_1_1 + 0.666666666666667*G0_1_1_10_1_1_0_0_0 + 0.666666666666667*G0_1_1_10_1_1_0_0_1 + 0.666666666666666*G0_1_1_10_1_1_2_0_1 + 0.666666666666665*G0_1_1_10_1_1_3_0_0 - 0.666666666666665*G0_1_1_10_1_1_4_0_0 - 1.33333333333333*G0_1_1_10_1_1_4_0_1 - 0.666666666666667*G0_1_1_10_1_1_5_0_0 + 0.666666666666667*G0_1_1_10_1_1_6_1_0 + 0.666666666666667*G0_1_1_10_1_1_6_1_1 + 0.666666666666666*G0_1_1_10_1_1_8_1_1 + 0.666666666666665*G0_1_1_10_1_1_9_1_0 - 0.666666666666665*G0_1_1_10_1_1_10_1_0 - 1.33333333333333*G0_1_1_10_1_1_10_1_1 - 0.666666666666667*G0_1_1_10_1_1_11_1_0 + 0.666666666666667*G0_1_1_11_1_0_0_0_0 + 0.666666666666667*G0_1_1_11_1_0_0_0_1 + 0.666666666666666*G0_1_1_11_1_0_1_0_0 + 0.666666666666665*G0_1_1_11_1_0_3_0_1 - 0.666666666666667*G0_1_1_11_1_0_4_0_1 - 1.33333333333333*G0_1_1_11_1_0_5_0_0 - 0.666666666666665*G0_1_1_11_1_0_5_0_1 + 0.666666666666667*G0_1_1_11_1_0_6_1_0 + 0.666666666666667*G0_1_1_11_1_0_6_1_1 + 0.666666666666666*G0_1_1_11_1_0_7_1_0 + 0.666666666666665*G0_1_1_11_1_0_9_1_1 - 0.666666666666667*G0_1_1_11_1_0_10_1_1 - 1.33333333333333*G0_1_1_11_1_0_11_1_0 - 0.666666666666665*G0_1_1_11_1_0_11_1_1 + 0.666666666666666*G0_1_1_11_1_1_1_0_0 + 0.666666666666665*G0_1_1_11_1_1_3_0_0 + 1.33333333333333*G0_1_1_11_1_1_3_0_1 - 0.666666666666665*G0_1_1_11_1_1_4_0_0 - 0.666666666666665*G0_1_1_11_1_1_5_0_0 - 1.33333333333333*G0_1_1_11_1_1_5_0_1 + 0.666666666666666*G0_1_1_11_1_1_7_1_0 + 0.666666666666665*G0_1_1_11_1_1_9_1_0 + 1.33333333333333*G0_1_1_11_1_1_9_1_1 - 0.666666666666665*G0_1_1_11_1_1_10_1_0 - 0.666666666666665*G0_1_1_11_1_1_11_1_0 - 1.33333333333333*G0_1_1_11_1_1_11_1_1; + A[1] = -A[34] - 0.5*G0_0_0_0_0_0_0_0_0 - 0.5*G0_0_0_0_0_0_0_0_1 - 0.166666666666667*G0_0_0_0_0_0_1_0_0 - 0.166666666666667*G0_0_0_0_0_0_2_0_1 + 0.666666666666667*G0_0_0_0_0_0_4_0_1 + 0.666666666666667*G0_0_0_0_0_0_5_0_0 - 0.5*G0_0_0_0_0_0_6_1_0 - 0.5*G0_0_0_0_0_0_6_1_1 - 0.166666666666667*G0_0_0_0_0_0_7_1_0 - 0.166666666666667*G0_0_0_0_0_0_8_1_1 + 0.666666666666667*G0_0_0_0_0_0_10_1_1 + 0.666666666666667*G0_0_0_0_0_0_11_1_0 - 0.5*G0_0_0_0_0_1_0_0_0 - 0.5*G0_0_0_0_0_1_0_0_1 - 0.166666666666667*G0_0_0_0_0_1_1_0_0 - 0.166666666666667*G0_0_0_0_0_1_2_0_1 + 0.666666666666667*G0_0_0_0_0_1_4_0_1 + 0.666666666666667*G0_0_0_0_0_1_5_0_0 - 0.5*G0_0_0_0_0_1_6_1_0 - 0.5*G0_0_0_0_0_1_6_1_1 - 0.166666666666667*G0_0_0_0_0_1_7_1_0 - 0.166666666666667*G0_0_0_0_0_1_8_1_1 + 0.666666666666667*G0_0_0_0_0_1_10_1_1 + 0.666666666666667*G0_0_0_0_0_1_11_1_0 - 0.166666666666667*G0_0_0_1_0_0_0_0_0 - 0.166666666666667*G0_0_0_1_0_0_0_0_1 - 0.5*G0_0_0_1_0_0_1_0_0 + 0.166666666666667*G0_0_0_1_0_0_2_0_1 - 0.666666666666666*G0_0_0_1_0_0_3_0_1 + 0.666666666666667*G0_0_0_1_0_0_5_0_0 + 0.666666666666666*G0_0_0_1_0_0_5_0_1 - 0.166666666666667*G0_0_0_1_0_0_6_1_0 - 0.166666666666667*G0_0_0_1_0_0_6_1_1 - 0.5*G0_0_0_1_0_0_7_1_0 + 0.166666666666667*G0_0_0_1_0_0_8_1_1 - 0.666666666666666*G0_0_0_1_0_0_9_1_1 + 0.666666666666667*G0_0_0_1_0_0_11_1_0 + 0.666666666666666*G0_0_0_1_0_0_11_1_1 - 0.166666666666667*G0_0_0_2_0_1_0_0_0 - 0.166666666666667*G0_0_0_2_0_1_0_0_1 + 0.166666666666667*G0_0_0_2_0_1_1_0_0 - 0.5*G0_0_0_2_0_1_2_0_1 - 0.666666666666666*G0_0_0_2_0_1_3_0_0 + 0.666666666666666*G0_0_0_2_0_1_4_0_0 + 0.666666666666666*G0_0_0_2_0_1_4_0_1 - 0.166666666666667*G0_0_0_2_0_1_6_1_0 - 0.166666666666667*G0_0_0_2_0_1_6_1_1 + 0.166666666666667*G0_0_0_2_0_1_7_1_0 - 0.5*G0_0_0_2_0_1_8_1_1 - 0.666666666666666*G0_0_0_2_0_1_9_1_0 + 0.666666666666666*G0_0_0_2_0_1_10_1_0 + 0.666666666666666*G0_0_0_2_0_1_10_1_1 - 0.666666666666666*G0_0_0_3_0_0_2_0_1 - 1.33333333333333*G0_0_0_3_0_0_3_0_0 - 0.666666666666665*G0_0_0_3_0_0_3_0_1 + 1.33333333333333*G0_0_0_3_0_0_4_0_0 + 0.666666666666666*G0_0_0_3_0_0_4_0_1 + 0.666666666666666*G0_0_0_3_0_0_5_0_1 - 0.666666666666666*G0_0_0_3_0_0_8_1_1 - 1.33333333333333*G0_0_0_3_0_0_9_1_0 - 0.666666666666665*G0_0_0_3_0_0_9_1_1 + 1.33333333333333*G0_0_0_3_0_0_10_1_0 + 0.666666666666666*G0_0_0_3_0_0_10_1_1 + 0.666666666666666*G0_0_0_3_0_0_11_1_1 - 0.666666666666666*G0_0_0_3_0_1_1_0_0 - 0.666666666666665*G0_0_0_3_0_1_3_0_0 - 1.33333333333333*G0_0_0_3_0_1_3_0_1 + 0.666666666666665*G0_0_0_3_0_1_4_0_0 + 0.666666666666666*G0_0_0_3_0_1_5_0_0 + 1.33333333333333*G0_0_0_3_0_1_5_0_1 - 0.666666666666666*G0_0_0_3_0_1_7_1_0 - 0.666666666666665*G0_0_0_3_0_1_9_1_0 - 1.33333333333333*G0_0_0_3_0_1_9_1_1 + 0.666666666666665*G0_0_0_3_0_1_10_1_0 + 0.666666666666666*G0_0_0_3_0_1_11_1_0 + 1.33333333333333*G0_0_0_3_0_1_11_1_1 + 0.666666666666666*G0_0_0_4_0_0_2_0_1 + 1.33333333333333*G0_0_0_4_0_0_3_0_0 + 0.666666666666665*G0_0_0_4_0_0_3_0_1 - 1.33333333333333*G0_0_0_4_0_0_4_0_0 - 0.666666666666666*G0_0_0_4_0_0_4_0_1 - 0.666666666666666*G0_0_0_4_0_0_5_0_1 + 0.666666666666666*G0_0_0_4_0_0_8_1_1 + 1.33333333333333*G0_0_0_4_0_0_9_1_0 + 0.666666666666665*G0_0_0_4_0_0_9_1_1 - 1.33333333333333*G0_0_0_4_0_0_10_1_0 - 0.666666666666666*G0_0_0_4_0_0_10_1_1 - 0.666666666666666*G0_0_0_4_0_0_11_1_1 + 0.666666666666667*G0_0_0_4_0_1_0_0_0 + 0.666666666666667*G0_0_0_4_0_1_0_0_1 + 0.666666666666666*G0_0_0_4_0_1_2_0_1 + 0.666666666666666*G0_0_0_4_0_1_3_0_0 - 0.666666666666666*G0_0_0_4_0_1_4_0_0 - 1.33333333333333*G0_0_0_4_0_1_4_0_1 - 0.666666666666667*G0_0_0_4_0_1_5_0_0 + 0.666666666666667*G0_0_0_4_0_1_6_1_0 + 0.666666666666667*G0_0_0_4_0_1_6_1_1 + 0.666666666666666*G0_0_0_4_0_1_8_1_1 + 0.666666666666666*G0_0_0_4_0_1_9_1_0 - 0.666666666666666*G0_0_0_4_0_1_10_1_0 - 1.33333333333333*G0_0_0_4_0_1_10_1_1 - 0.666666666666667*G0_0_0_4_0_1_11_1_0 + 0.666666666666667*G0_0_0_5_0_0_0_0_0 + 0.666666666666667*G0_0_0_5_0_0_0_0_1 + 0.666666666666666*G0_0_0_5_0_0_1_0_0 + 0.666666666666666*G0_0_0_5_0_0_3_0_1 - 0.666666666666667*G0_0_0_5_0_0_4_0_1 - 1.33333333333333*G0_0_0_5_0_0_5_0_0 - 0.666666666666666*G0_0_0_5_0_0_5_0_1 + 0.666666666666667*G0_0_0_5_0_0_6_1_0 + 0.666666666666667*G0_0_0_5_0_0_6_1_1 + 0.666666666666666*G0_0_0_5_0_0_7_1_0 + 0.666666666666666*G0_0_0_5_0_0_9_1_1 - 0.666666666666667*G0_0_0_5_0_0_10_1_1 - 1.33333333333333*G0_0_0_5_0_0_11_1_0 - 0.666666666666666*G0_0_0_5_0_0_11_1_1 + 0.666666666666666*G0_0_0_5_0_1_1_0_0 + 0.666666666666666*G0_0_0_5_0_1_3_0_0 + 1.33333333333333*G0_0_0_5_0_1_3_0_1 - 0.666666666666666*G0_0_0_5_0_1_4_0_0 - 0.666666666666666*G0_0_0_5_0_1_5_0_0 - 1.33333333333333*G0_0_0_5_0_1_5_0_1 + 0.666666666666666*G0_0_0_5_0_1_7_1_0 + 0.666666666666666*G0_0_0_5_0_1_9_1_0 + 1.33333333333333*G0_0_0_5_0_1_9_1_1 - 0.666666666666666*G0_0_0_5_0_1_10_1_0 - 0.666666666666666*G0_0_0_5_0_1_11_1_0 - 1.33333333333333*G0_0_0_5_0_1_11_1_1 - 0.5*G0_0_0_6_1_0_0_0_0 - 0.5*G0_0_0_6_1_0_0_0_1 - 0.166666666666667*G0_0_0_6_1_0_1_0_0 - 0.166666666666667*G0_0_0_6_1_0_2_0_1 + 0.666666666666667*G0_0_0_6_1_0_4_0_1 + 0.666666666666667*G0_0_0_6_1_0_5_0_0 - 0.5*G0_0_0_6_1_0_6_1_0 - 0.5*G0_0_0_6_1_0_6_1_1 - 0.166666666666667*G0_0_0_6_1_0_7_1_0 - 0.166666666666667*G0_0_0_6_1_0_8_1_1 + 0.666666666666667*G0_0_0_6_1_0_10_1_1 + 0.666666666666667*G0_0_0_6_1_0_11_1_0 - 0.5*G0_0_0_6_1_1_0_0_0 - 0.5*G0_0_0_6_1_1_0_0_1 - 0.166666666666667*G0_0_0_6_1_1_1_0_0 - 0.166666666666667*G0_0_0_6_1_1_2_0_1 + 0.666666666666667*G0_0_0_6_1_1_4_0_1 + 0.666666666666667*G0_0_0_6_1_1_5_0_0 - 0.5*G0_0_0_6_1_1_6_1_0 - 0.5*G0_0_0_6_1_1_6_1_1 - 0.166666666666667*G0_0_0_6_1_1_7_1_0 - 0.166666666666667*G0_0_0_6_1_1_8_1_1 + 0.666666666666667*G0_0_0_6_1_1_10_1_1 + 0.666666666666667*G0_0_0_6_1_1_11_1_0 - 0.166666666666667*G0_0_0_7_1_0_0_0_0 - 0.166666666666667*G0_0_0_7_1_0_0_0_1 - 0.5*G0_0_0_7_1_0_1_0_0 + 0.166666666666667*G0_0_0_7_1_0_2_0_1 - 0.666666666666666*G0_0_0_7_1_0_3_0_1 + 0.666666666666667*G0_0_0_7_1_0_5_0_0 + 0.666666666666666*G0_0_0_7_1_0_5_0_1 - 0.166666666666667*G0_0_0_7_1_0_6_1_0 - 0.166666666666667*G0_0_0_7_1_0_6_1_1 - 0.5*G0_0_0_7_1_0_7_1_0 + 0.166666666666667*G0_0_0_7_1_0_8_1_1 - 0.666666666666666*G0_0_0_7_1_0_9_1_1 + 0.666666666666667*G0_0_0_7_1_0_11_1_0 + 0.666666666666666*G0_0_0_7_1_0_11_1_1 - 0.166666666666667*G0_0_0_8_1_1_0_0_0 - 0.166666666666667*G0_0_0_8_1_1_0_0_1 + 0.166666666666667*G0_0_0_8_1_1_1_0_0 - 0.5*G0_0_0_8_1_1_2_0_1 - 0.666666666666666*G0_0_0_8_1_1_3_0_0 + 0.666666666666666*G0_0_0_8_1_1_4_0_0 + 0.666666666666666*G0_0_0_8_1_1_4_0_1 - 0.166666666666667*G0_0_0_8_1_1_6_1_0 - 0.166666666666667*G0_0_0_8_1_1_6_1_1 + 0.166666666666667*G0_0_0_8_1_1_7_1_0 - 0.5*G0_0_0_8_1_1_8_1_1 - 0.666666666666666*G0_0_0_8_1_1_9_1_0 + 0.666666666666666*G0_0_0_8_1_1_10_1_0 + 0.666666666666666*G0_0_0_8_1_1_10_1_1 - 0.666666666666666*G0_0_0_9_1_0_2_0_1 - 1.33333333333333*G0_0_0_9_1_0_3_0_0 - 0.666666666666665*G0_0_0_9_1_0_3_0_1 + 1.33333333333333*G0_0_0_9_1_0_4_0_0 + 0.666666666666666*G0_0_0_9_1_0_4_0_1 + 0.666666666666666*G0_0_0_9_1_0_5_0_1 - 0.666666666666666*G0_0_0_9_1_0_8_1_1 - 1.33333333333333*G0_0_0_9_1_0_9_1_0 - 0.666666666666665*G0_0_0_9_1_0_9_1_1 + 1.33333333333333*G0_0_0_9_1_0_10_1_0 + 0.666666666666666*G0_0_0_9_1_0_10_1_1 + 0.666666666666666*G0_0_0_9_1_0_11_1_1 - 0.666666666666666*G0_0_0_9_1_1_1_0_0 - 0.666666666666665*G0_0_0_9_1_1_3_0_0 - 1.33333333333333*G0_0_0_9_1_1_3_0_1 + 0.666666666666665*G0_0_0_9_1_1_4_0_0 + 0.666666666666666*G0_0_0_9_1_1_5_0_0 + 1.33333333333333*G0_0_0_9_1_1_5_0_1 - 0.666666666666666*G0_0_0_9_1_1_7_1_0 - 0.666666666666665*G0_0_0_9_1_1_9_1_0 - 1.33333333333333*G0_0_0_9_1_1_9_1_1 + 0.666666666666665*G0_0_0_9_1_1_10_1_0 + 0.666666666666666*G0_0_0_9_1_1_11_1_0 + 1.33333333333333*G0_0_0_9_1_1_11_1_1 + 0.666666666666666*G0_0_0_10_1_0_2_0_1 + 1.33333333333333*G0_0_0_10_1_0_3_0_0 + 0.666666666666665*G0_0_0_10_1_0_3_0_1 - 1.33333333333333*G0_0_0_10_1_0_4_0_0 - 0.666666666666666*G0_0_0_10_1_0_4_0_1 - 0.666666666666666*G0_0_0_10_1_0_5_0_1 + 0.666666666666666*G0_0_0_10_1_0_8_1_1 + 1.33333333333333*G0_0_0_10_1_0_9_1_0 + 0.666666666666665*G0_0_0_10_1_0_9_1_1 - 1.33333333333333*G0_0_0_10_1_0_10_1_0 - 0.666666666666666*G0_0_0_10_1_0_10_1_1 - 0.666666666666666*G0_0_0_10_1_0_11_1_1 + 0.666666666666667*G0_0_0_10_1_1_0_0_0 + 0.666666666666667*G0_0_0_10_1_1_0_0_1 + 0.666666666666666*G0_0_0_10_1_1_2_0_1 + 0.666666666666666*G0_0_0_10_1_1_3_0_0 - 0.666666666666666*G0_0_0_10_1_1_4_0_0 - 1.33333333333333*G0_0_0_10_1_1_4_0_1 - 0.666666666666667*G0_0_0_10_1_1_5_0_0 + 0.666666666666667*G0_0_0_10_1_1_6_1_0 + 0.666666666666667*G0_0_0_10_1_1_6_1_1 + 0.666666666666666*G0_0_0_10_1_1_8_1_1 + 0.666666666666666*G0_0_0_10_1_1_9_1_0 - 0.666666666666666*G0_0_0_10_1_1_10_1_0 - 1.33333333333333*G0_0_0_10_1_1_10_1_1 - 0.666666666666667*G0_0_0_10_1_1_11_1_0 + 0.666666666666667*G0_0_0_11_1_0_0_0_0 + 0.666666666666667*G0_0_0_11_1_0_0_0_1 + 0.666666666666666*G0_0_0_11_1_0_1_0_0 + 0.666666666666666*G0_0_0_11_1_0_3_0_1 - 0.666666666666667*G0_0_0_11_1_0_4_0_1 - 1.33333333333333*G0_0_0_11_1_0_5_0_0 - 0.666666666666666*G0_0_0_11_1_0_5_0_1 + 0.666666666666667*G0_0_0_11_1_0_6_1_0 + 0.666666666666667*G0_0_0_11_1_0_6_1_1 + 0.666666666666666*G0_0_0_11_1_0_7_1_0 + 0.666666666666666*G0_0_0_11_1_0_9_1_1 - 0.666666666666667*G0_0_0_11_1_0_10_1_1 - 1.33333333333333*G0_0_0_11_1_0_11_1_0 - 0.666666666666666*G0_0_0_11_1_0_11_1_1 + 0.666666666666666*G0_0_0_11_1_1_1_0_0 + 0.666666666666666*G0_0_0_11_1_1_3_0_0 + 1.33333333333333*G0_0_0_11_1_1_3_0_1 - 0.666666666666666*G0_0_0_11_1_1_4_0_0 - 0.666666666666666*G0_0_0_11_1_1_5_0_0 - 1.33333333333333*G0_0_0_11_1_1_5_0_1 + 0.666666666666666*G0_0_0_11_1_1_7_1_0 + 0.666666666666666*G0_0_0_11_1_1_9_1_0 + 1.33333333333333*G0_0_0_11_1_1_9_1_1 - 0.666666666666666*G0_0_0_11_1_1_10_1_0 - 0.666666666666666*G0_0_0_11_1_1_11_1_0 - 1.33333333333333*G0_0_0_11_1_1_11_1_1; + A[29] = A[8]; + A[14] = 0.5*G0_1_1_0_0_0_0_0_0 + 0.5*G0_1_1_0_0_0_0_0_1 + 0.166666666666667*G0_1_1_0_0_0_1_0_0 + 0.166666666666667*G0_1_1_0_0_0_2_0_1 - 0.666666666666667*G0_1_1_0_0_0_4_0_1 - 0.666666666666667*G0_1_1_0_0_0_5_0_0 + 0.5*G0_1_1_0_0_0_6_1_0 + 0.5*G0_1_1_0_0_0_6_1_1 + 0.166666666666667*G0_1_1_0_0_0_7_1_0 + 0.166666666666667*G0_1_1_0_0_0_8_1_1 - 0.666666666666667*G0_1_1_0_0_0_10_1_1 - 0.666666666666667*G0_1_1_0_0_0_11_1_0 + 0.5*G0_1_1_0_0_1_0_0_0 + 0.5*G0_1_1_0_0_1_0_0_1 + 0.166666666666667*G0_1_1_0_0_1_1_0_0 + 0.166666666666667*G0_1_1_0_0_1_2_0_1 - 0.666666666666667*G0_1_1_0_0_1_4_0_1 - 0.666666666666667*G0_1_1_0_0_1_5_0_0 + 0.5*G0_1_1_0_0_1_6_1_0 + 0.5*G0_1_1_0_0_1_6_1_1 + 0.166666666666667*G0_1_1_0_0_1_7_1_0 + 0.166666666666667*G0_1_1_0_0_1_8_1_1 - 0.666666666666667*G0_1_1_0_0_1_10_1_1 - 0.666666666666667*G0_1_1_0_0_1_11_1_0 + 0.166666666666667*G0_1_1_1_0_0_0_0_0 + 0.166666666666667*G0_1_1_1_0_0_0_0_1 + 0.5*G0_1_1_1_0_0_1_0_0 - 0.166666666666667*G0_1_1_1_0_0_2_0_1 + 0.666666666666666*G0_1_1_1_0_0_3_0_1 - 0.666666666666666*G0_1_1_1_0_0_5_0_0 - 0.666666666666666*G0_1_1_1_0_0_5_0_1 + 0.166666666666667*G0_1_1_1_0_0_6_1_0 + 0.166666666666667*G0_1_1_1_0_0_6_1_1 + 0.5*G0_1_1_1_0_0_7_1_0 - 0.166666666666667*G0_1_1_1_0_0_8_1_1 + 0.666666666666666*G0_1_1_1_0_0_9_1_1 - 0.666666666666666*G0_1_1_1_0_0_11_1_0 - 0.666666666666666*G0_1_1_1_0_0_11_1_1 + 0.166666666666667*G0_1_1_2_0_1_0_0_0 + 0.166666666666667*G0_1_1_2_0_1_0_0_1 - 0.166666666666667*G0_1_1_2_0_1_1_0_0 + 0.5*G0_1_1_2_0_1_2_0_1 + 0.666666666666666*G0_1_1_2_0_1_3_0_0 - 0.666666666666666*G0_1_1_2_0_1_4_0_0 - 0.666666666666666*G0_1_1_2_0_1_4_0_1 + 0.166666666666667*G0_1_1_2_0_1_6_1_0 + 0.166666666666667*G0_1_1_2_0_1_6_1_1 - 0.166666666666667*G0_1_1_2_0_1_7_1_0 + 0.5*G0_1_1_2_0_1_8_1_1 + 0.666666666666666*G0_1_1_2_0_1_9_1_0 - 0.666666666666666*G0_1_1_2_0_1_10_1_0 - 0.666666666666666*G0_1_1_2_0_1_10_1_1 + 0.666666666666666*G0_1_1_3_0_0_2_0_1 + 1.33333333333333*G0_1_1_3_0_0_3_0_0 + 0.666666666666665*G0_1_1_3_0_0_3_0_1 - 1.33333333333333*G0_1_1_3_0_0_4_0_0 - 0.666666666666666*G0_1_1_3_0_0_4_0_1 - 0.666666666666665*G0_1_1_3_0_0_5_0_1 + 0.666666666666666*G0_1_1_3_0_0_8_1_1 + 1.33333333333333*G0_1_1_3_0_0_9_1_0 + 0.666666666666665*G0_1_1_3_0_0_9_1_1 - 1.33333333333333*G0_1_1_3_0_0_10_1_0 - 0.666666666666666*G0_1_1_3_0_0_10_1_1 - 0.666666666666665*G0_1_1_3_0_0_11_1_1 + 0.666666666666666*G0_1_1_3_0_1_1_0_0 + 0.666666666666665*G0_1_1_3_0_1_3_0_0 + 1.33333333333333*G0_1_1_3_0_1_3_0_1 - 0.666666666666665*G0_1_1_3_0_1_4_0_0 - 0.666666666666665*G0_1_1_3_0_1_5_0_0 - 1.33333333333333*G0_1_1_3_0_1_5_0_1 + 0.666666666666666*G0_1_1_3_0_1_7_1_0 + 0.666666666666665*G0_1_1_3_0_1_9_1_0 + 1.33333333333333*G0_1_1_3_0_1_9_1_1 - 0.666666666666665*G0_1_1_3_0_1_10_1_0 - 0.666666666666665*G0_1_1_3_0_1_11_1_0 - 1.33333333333333*G0_1_1_3_0_1_11_1_1 - 0.666666666666666*G0_1_1_4_0_0_2_0_1 - 1.33333333333333*G0_1_1_4_0_0_3_0_0 - 0.666666666666665*G0_1_1_4_0_0_3_0_1 + 1.33333333333333*G0_1_1_4_0_0_4_0_0 + 0.666666666666666*G0_1_1_4_0_0_4_0_1 + 0.666666666666665*G0_1_1_4_0_0_5_0_1 - 0.666666666666666*G0_1_1_4_0_0_8_1_1 - 1.33333333333333*G0_1_1_4_0_0_9_1_0 - 0.666666666666665*G0_1_1_4_0_0_9_1_1 + 1.33333333333333*G0_1_1_4_0_0_10_1_0 + 0.666666666666666*G0_1_1_4_0_0_10_1_1 + 0.666666666666665*G0_1_1_4_0_0_11_1_1 - 0.666666666666667*G0_1_1_4_0_1_0_0_0 - 0.666666666666667*G0_1_1_4_0_1_0_0_1 - 0.666666666666666*G0_1_1_4_0_1_2_0_1 - 0.666666666666666*G0_1_1_4_0_1_3_0_0 + 0.666666666666666*G0_1_1_4_0_1_4_0_0 + 1.33333333333333*G0_1_1_4_0_1_4_0_1 + 0.666666666666667*G0_1_1_4_0_1_5_0_0 - 0.666666666666667*G0_1_1_4_0_1_6_1_0 - 0.666666666666667*G0_1_1_4_0_1_6_1_1 - 0.666666666666666*G0_1_1_4_0_1_8_1_1 - 0.666666666666666*G0_1_1_4_0_1_9_1_0 + 0.666666666666666*G0_1_1_4_0_1_10_1_0 + 1.33333333333333*G0_1_1_4_0_1_10_1_1 + 0.666666666666667*G0_1_1_4_0_1_11_1_0 - 0.666666666666667*G0_1_1_5_0_0_0_0_0 - 0.666666666666667*G0_1_1_5_0_0_0_0_1 - 0.666666666666666*G0_1_1_5_0_0_1_0_0 - 0.666666666666665*G0_1_1_5_0_0_3_0_1 + 0.666666666666667*G0_1_1_5_0_0_4_0_1 + 1.33333333333333*G0_1_1_5_0_0_5_0_0 + 0.666666666666665*G0_1_1_5_0_0_5_0_1 - 0.666666666666667*G0_1_1_5_0_0_6_1_0 - 0.666666666666667*G0_1_1_5_0_0_6_1_1 - 0.666666666666666*G0_1_1_5_0_0_7_1_0 - 0.666666666666665*G0_1_1_5_0_0_9_1_1 + 0.666666666666667*G0_1_1_5_0_0_10_1_1 + 1.33333333333333*G0_1_1_5_0_0_11_1_0 + 0.666666666666665*G0_1_1_5_0_0_11_1_1 - 0.666666666666666*G0_1_1_5_0_1_1_0_0 - 0.666666666666665*G0_1_1_5_0_1_3_0_0 - 1.33333333333333*G0_1_1_5_0_1_3_0_1 + 0.666666666666665*G0_1_1_5_0_1_4_0_0 + 0.666666666666665*G0_1_1_5_0_1_5_0_0 + 1.33333333333333*G0_1_1_5_0_1_5_0_1 - 0.666666666666666*G0_1_1_5_0_1_7_1_0 - 0.666666666666665*G0_1_1_5_0_1_9_1_0 - 1.33333333333333*G0_1_1_5_0_1_9_1_1 + 0.666666666666665*G0_1_1_5_0_1_10_1_0 + 0.666666666666665*G0_1_1_5_0_1_11_1_0 + 1.33333333333333*G0_1_1_5_0_1_11_1_1 + 0.5*G0_1_1_6_1_0_0_0_0 + 0.5*G0_1_1_6_1_0_0_0_1 + 0.166666666666667*G0_1_1_6_1_0_1_0_0 + 0.166666666666667*G0_1_1_6_1_0_2_0_1 - 0.666666666666667*G0_1_1_6_1_0_4_0_1 - 0.666666666666667*G0_1_1_6_1_0_5_0_0 + 0.5*G0_1_1_6_1_0_6_1_0 + 0.5*G0_1_1_6_1_0_6_1_1 + 0.166666666666667*G0_1_1_6_1_0_7_1_0 + 0.166666666666667*G0_1_1_6_1_0_8_1_1 - 0.666666666666667*G0_1_1_6_1_0_10_1_1 - 0.666666666666667*G0_1_1_6_1_0_11_1_0 + 0.5*G0_1_1_6_1_1_0_0_0 + 0.5*G0_1_1_6_1_1_0_0_1 + 0.166666666666667*G0_1_1_6_1_1_1_0_0 + 0.166666666666667*G0_1_1_6_1_1_2_0_1 - 0.666666666666667*G0_1_1_6_1_1_4_0_1 - 0.666666666666667*G0_1_1_6_1_1_5_0_0 + 0.5*G0_1_1_6_1_1_6_1_0 + 0.5*G0_1_1_6_1_1_6_1_1 + 0.166666666666667*G0_1_1_6_1_1_7_1_0 + 0.166666666666667*G0_1_1_6_1_1_8_1_1 - 0.666666666666667*G0_1_1_6_1_1_10_1_1 - 0.666666666666667*G0_1_1_6_1_1_11_1_0 + 0.166666666666667*G0_1_1_7_1_0_0_0_0 + 0.166666666666667*G0_1_1_7_1_0_0_0_1 + 0.5*G0_1_1_7_1_0_1_0_0 - 0.166666666666667*G0_1_1_7_1_0_2_0_1 + 0.666666666666666*G0_1_1_7_1_0_3_0_1 - 0.666666666666666*G0_1_1_7_1_0_5_0_0 - 0.666666666666666*G0_1_1_7_1_0_5_0_1 + 0.166666666666667*G0_1_1_7_1_0_6_1_0 + 0.166666666666667*G0_1_1_7_1_0_6_1_1 + 0.5*G0_1_1_7_1_0_7_1_0 - 0.166666666666667*G0_1_1_7_1_0_8_1_1 + 0.666666666666666*G0_1_1_7_1_0_9_1_1 - 0.666666666666666*G0_1_1_7_1_0_11_1_0 - 0.666666666666666*G0_1_1_7_1_0_11_1_1 + 0.166666666666667*G0_1_1_8_1_1_0_0_0 + 0.166666666666667*G0_1_1_8_1_1_0_0_1 - 0.166666666666667*G0_1_1_8_1_1_1_0_0 + 0.5*G0_1_1_8_1_1_2_0_1 + 0.666666666666666*G0_1_1_8_1_1_3_0_0 - 0.666666666666666*G0_1_1_8_1_1_4_0_0 - 0.666666666666666*G0_1_1_8_1_1_4_0_1 + 0.166666666666667*G0_1_1_8_1_1_6_1_0 + 0.166666666666667*G0_1_1_8_1_1_6_1_1 - 0.166666666666667*G0_1_1_8_1_1_7_1_0 + 0.5*G0_1_1_8_1_1_8_1_1 + 0.666666666666666*G0_1_1_8_1_1_9_1_0 - 0.666666666666666*G0_1_1_8_1_1_10_1_0 - 0.666666666666666*G0_1_1_8_1_1_10_1_1 + 0.666666666666666*G0_1_1_9_1_0_2_0_1 + 1.33333333333333*G0_1_1_9_1_0_3_0_0 + 0.666666666666665*G0_1_1_9_1_0_3_0_1 - 1.33333333333333*G0_1_1_9_1_0_4_0_0 - 0.666666666666666*G0_1_1_9_1_0_4_0_1 - 0.666666666666665*G0_1_1_9_1_0_5_0_1 + 0.666666666666666*G0_1_1_9_1_0_8_1_1 + 1.33333333333333*G0_1_1_9_1_0_9_1_0 + 0.666666666666665*G0_1_1_9_1_0_9_1_1 - 1.33333333333333*G0_1_1_9_1_0_10_1_0 - 0.666666666666666*G0_1_1_9_1_0_10_1_1 - 0.666666666666665*G0_1_1_9_1_0_11_1_1 + 0.666666666666666*G0_1_1_9_1_1_1_0_0 + 0.666666666666665*G0_1_1_9_1_1_3_0_0 + 1.33333333333333*G0_1_1_9_1_1_3_0_1 - 0.666666666666665*G0_1_1_9_1_1_4_0_0 - 0.666666666666665*G0_1_1_9_1_1_5_0_0 - 1.33333333333333*G0_1_1_9_1_1_5_0_1 + 0.666666666666666*G0_1_1_9_1_1_7_1_0 + 0.666666666666665*G0_1_1_9_1_1_9_1_0 + 1.33333333333333*G0_1_1_9_1_1_9_1_1 - 0.666666666666665*G0_1_1_9_1_1_10_1_0 - 0.666666666666665*G0_1_1_9_1_1_11_1_0 - 1.33333333333333*G0_1_1_9_1_1_11_1_1 - 0.666666666666666*G0_1_1_10_1_0_2_0_1 - 1.33333333333333*G0_1_1_10_1_0_3_0_0 - 0.666666666666665*G0_1_1_10_1_0_3_0_1 + 1.33333333333333*G0_1_1_10_1_0_4_0_0 + 0.666666666666666*G0_1_1_10_1_0_4_0_1 + 0.666666666666665*G0_1_1_10_1_0_5_0_1 - 0.666666666666666*G0_1_1_10_1_0_8_1_1 - 1.33333333333333*G0_1_1_10_1_0_9_1_0 - 0.666666666666665*G0_1_1_10_1_0_9_1_1 + 1.33333333333333*G0_1_1_10_1_0_10_1_0 + 0.666666666666666*G0_1_1_10_1_0_10_1_1 + 0.666666666666665*G0_1_1_10_1_0_11_1_1 - 0.666666666666667*G0_1_1_10_1_1_0_0_0 - 0.666666666666667*G0_1_1_10_1_1_0_0_1 - 0.666666666666666*G0_1_1_10_1_1_2_0_1 - 0.666666666666666*G0_1_1_10_1_1_3_0_0 + 0.666666666666666*G0_1_1_10_1_1_4_0_0 + 1.33333333333333*G0_1_1_10_1_1_4_0_1 + 0.666666666666667*G0_1_1_10_1_1_5_0_0 - 0.666666666666667*G0_1_1_10_1_1_6_1_0 - 0.666666666666667*G0_1_1_10_1_1_6_1_1 - 0.666666666666666*G0_1_1_10_1_1_8_1_1 - 0.666666666666666*G0_1_1_10_1_1_9_1_0 + 0.666666666666666*G0_1_1_10_1_1_10_1_0 + 1.33333333333333*G0_1_1_10_1_1_10_1_1 + 0.666666666666667*G0_1_1_10_1_1_11_1_0 - 0.666666666666667*G0_1_1_11_1_0_0_0_0 - 0.666666666666667*G0_1_1_11_1_0_0_0_1 - 0.666666666666666*G0_1_1_11_1_0_1_0_0 - 0.666666666666665*G0_1_1_11_1_0_3_0_1 + 0.666666666666667*G0_1_1_11_1_0_4_0_1 + 1.33333333333333*G0_1_1_11_1_0_5_0_0 + 0.666666666666665*G0_1_1_11_1_0_5_0_1 - 0.666666666666667*G0_1_1_11_1_0_6_1_0 - 0.666666666666667*G0_1_1_11_1_0_6_1_1 - 0.666666666666666*G0_1_1_11_1_0_7_1_0 - 0.666666666666665*G0_1_1_11_1_0_9_1_1 + 0.666666666666667*G0_1_1_11_1_0_10_1_1 + 1.33333333333333*G0_1_1_11_1_0_11_1_0 + 0.666666666666665*G0_1_1_11_1_0_11_1_1 - 0.666666666666666*G0_1_1_11_1_1_1_0_0 - 0.666666666666665*G0_1_1_11_1_1_3_0_0 - 1.33333333333333*G0_1_1_11_1_1_3_0_1 + 0.666666666666665*G0_1_1_11_1_1_4_0_0 + 0.666666666666665*G0_1_1_11_1_1_5_0_0 + 1.33333333333333*G0_1_1_11_1_1_5_0_1 - 0.666666666666666*G0_1_1_11_1_1_7_1_0 - 0.666666666666665*G0_1_1_11_1_1_9_1_0 - 1.33333333333333*G0_1_1_11_1_1_9_1_1 + 0.666666666666665*G0_1_1_11_1_1_10_1_0 + 0.666666666666665*G0_1_1_11_1_1_11_1_0 + 1.33333333333333*G0_1_1_11_1_1_11_1_1; + A[10] = 0.0; + A[5] = 0.0; + A[26] = 0.0; + A[6] = -A[8] - 0.5*G0_0_0_0_0_0_0_0_0 - 0.5*G0_0_0_0_0_0_0_0_1 - 0.166666666666667*G0_0_0_0_0_0_1_0_0 - 0.166666666666667*G0_0_0_0_0_0_2_0_1 + 0.666666666666667*G0_0_0_0_0_0_4_0_1 + 0.666666666666667*G0_0_0_0_0_0_5_0_0 - 0.5*G0_0_0_0_0_0_6_1_0 - 0.5*G0_0_0_0_0_0_6_1_1 - 0.166666666666667*G0_0_0_0_0_0_7_1_0 - 0.166666666666667*G0_0_0_0_0_0_8_1_1 + 0.666666666666667*G0_0_0_0_0_0_10_1_1 + 0.666666666666667*G0_0_0_0_0_0_11_1_0 - 0.5*G0_0_0_0_0_1_0_0_0 - 0.5*G0_0_0_0_0_1_0_0_1 - 0.166666666666667*G0_0_0_0_0_1_1_0_0 - 0.166666666666667*G0_0_0_0_0_1_2_0_1 + 0.666666666666667*G0_0_0_0_0_1_4_0_1 + 0.666666666666667*G0_0_0_0_0_1_5_0_0 - 0.5*G0_0_0_0_0_1_6_1_0 - 0.5*G0_0_0_0_0_1_6_1_1 - 0.166666666666667*G0_0_0_0_0_1_7_1_0 - 0.166666666666667*G0_0_0_0_0_1_8_1_1 + 0.666666666666667*G0_0_0_0_0_1_10_1_1 + 0.666666666666667*G0_0_0_0_0_1_11_1_0 - 0.166666666666667*G0_0_0_1_0_0_0_0_0 - 0.166666666666667*G0_0_0_1_0_0_0_0_1 - 0.5*G0_0_0_1_0_0_1_0_0 + 0.166666666666667*G0_0_0_1_0_0_2_0_1 - 0.666666666666666*G0_0_0_1_0_0_3_0_1 + 0.666666666666667*G0_0_0_1_0_0_5_0_0 + 0.666666666666666*G0_0_0_1_0_0_5_0_1 - 0.166666666666667*G0_0_0_1_0_0_6_1_0 - 0.166666666666667*G0_0_0_1_0_0_6_1_1 - 0.5*G0_0_0_1_0_0_7_1_0 + 0.166666666666667*G0_0_0_1_0_0_8_1_1 - 0.666666666666666*G0_0_0_1_0_0_9_1_1 + 0.666666666666667*G0_0_0_1_0_0_11_1_0 + 0.666666666666666*G0_0_0_1_0_0_11_1_1 - 0.166666666666667*G0_0_0_2_0_1_0_0_0 - 0.166666666666667*G0_0_0_2_0_1_0_0_1 + 0.166666666666667*G0_0_0_2_0_1_1_0_0 - 0.5*G0_0_0_2_0_1_2_0_1 - 0.666666666666666*G0_0_0_2_0_1_3_0_0 + 0.666666666666666*G0_0_0_2_0_1_4_0_0 + 0.666666666666666*G0_0_0_2_0_1_4_0_1 - 0.166666666666667*G0_0_0_2_0_1_6_1_0 - 0.166666666666667*G0_0_0_2_0_1_6_1_1 + 0.166666666666667*G0_0_0_2_0_1_7_1_0 - 0.5*G0_0_0_2_0_1_8_1_1 - 0.666666666666666*G0_0_0_2_0_1_9_1_0 + 0.666666666666666*G0_0_0_2_0_1_10_1_0 + 0.666666666666666*G0_0_0_2_0_1_10_1_1 - 0.666666666666666*G0_0_0_3_0_0_2_0_1 - 1.33333333333333*G0_0_0_3_0_0_3_0_0 - 0.666666666666665*G0_0_0_3_0_0_3_0_1 + 1.33333333333333*G0_0_0_3_0_0_4_0_0 + 0.666666666666666*G0_0_0_3_0_0_4_0_1 + 0.666666666666666*G0_0_0_3_0_0_5_0_1 - 0.666666666666666*G0_0_0_3_0_0_8_1_1 - 1.33333333333333*G0_0_0_3_0_0_9_1_0 - 0.666666666666665*G0_0_0_3_0_0_9_1_1 + 1.33333333333333*G0_0_0_3_0_0_10_1_0 + 0.666666666666666*G0_0_0_3_0_0_10_1_1 + 0.666666666666666*G0_0_0_3_0_0_11_1_1 - 0.666666666666666*G0_0_0_3_0_1_1_0_0 - 0.666666666666665*G0_0_0_3_0_1_3_0_0 - 1.33333333333333*G0_0_0_3_0_1_3_0_1 + 0.666666666666665*G0_0_0_3_0_1_4_0_0 + 0.666666666666666*G0_0_0_3_0_1_5_0_0 + 1.33333333333333*G0_0_0_3_0_1_5_0_1 - 0.666666666666666*G0_0_0_3_0_1_7_1_0 - 0.666666666666665*G0_0_0_3_0_1_9_1_0 - 1.33333333333333*G0_0_0_3_0_1_9_1_1 + 0.666666666666665*G0_0_0_3_0_1_10_1_0 + 0.666666666666666*G0_0_0_3_0_1_11_1_0 + 1.33333333333333*G0_0_0_3_0_1_11_1_1 + 0.666666666666666*G0_0_0_4_0_0_2_0_1 + 1.33333333333333*G0_0_0_4_0_0_3_0_0 + 0.666666666666665*G0_0_0_4_0_0_3_0_1 - 1.33333333333333*G0_0_0_4_0_0_4_0_0 - 0.666666666666666*G0_0_0_4_0_0_4_0_1 - 0.666666666666666*G0_0_0_4_0_0_5_0_1 + 0.666666666666666*G0_0_0_4_0_0_8_1_1 + 1.33333333333333*G0_0_0_4_0_0_9_1_0 + 0.666666666666665*G0_0_0_4_0_0_9_1_1 - 1.33333333333333*G0_0_0_4_0_0_10_1_0 - 0.666666666666666*G0_0_0_4_0_0_10_1_1 - 0.666666666666666*G0_0_0_4_0_0_11_1_1 + 0.666666666666667*G0_0_0_4_0_1_0_0_0 + 0.666666666666667*G0_0_0_4_0_1_0_0_1 + 0.666666666666666*G0_0_0_4_0_1_2_0_1 + 0.666666666666666*G0_0_0_4_0_1_3_0_0 - 0.666666666666666*G0_0_0_4_0_1_4_0_0 - 1.33333333333333*G0_0_0_4_0_1_4_0_1 - 0.666666666666667*G0_0_0_4_0_1_5_0_0 + 0.666666666666667*G0_0_0_4_0_1_6_1_0 + 0.666666666666667*G0_0_0_4_0_1_6_1_1 + 0.666666666666666*G0_0_0_4_0_1_8_1_1 + 0.666666666666666*G0_0_0_4_0_1_9_1_0 - 0.666666666666666*G0_0_0_4_0_1_10_1_0 - 1.33333333333333*G0_0_0_4_0_1_10_1_1 - 0.666666666666667*G0_0_0_4_0_1_11_1_0 + 0.666666666666667*G0_0_0_5_0_0_0_0_0 + 0.666666666666667*G0_0_0_5_0_0_0_0_1 + 0.666666666666666*G0_0_0_5_0_0_1_0_0 + 0.666666666666666*G0_0_0_5_0_0_3_0_1 - 0.666666666666667*G0_0_0_5_0_0_4_0_1 - 1.33333333333333*G0_0_0_5_0_0_5_0_0 - 0.666666666666666*G0_0_0_5_0_0_5_0_1 + 0.666666666666667*G0_0_0_5_0_0_6_1_0 + 0.666666666666667*G0_0_0_5_0_0_6_1_1 + 0.666666666666666*G0_0_0_5_0_0_7_1_0 + 0.666666666666666*G0_0_0_5_0_0_9_1_1 - 0.666666666666667*G0_0_0_5_0_0_10_1_1 - 1.33333333333333*G0_0_0_5_0_0_11_1_0 - 0.666666666666666*G0_0_0_5_0_0_11_1_1 + 0.666666666666666*G0_0_0_5_0_1_1_0_0 + 0.666666666666666*G0_0_0_5_0_1_3_0_0 + 1.33333333333333*G0_0_0_5_0_1_3_0_1 - 0.666666666666666*G0_0_0_5_0_1_4_0_0 - 0.666666666666666*G0_0_0_5_0_1_5_0_0 - 1.33333333333333*G0_0_0_5_0_1_5_0_1 + 0.666666666666666*G0_0_0_5_0_1_7_1_0 + 0.666666666666666*G0_0_0_5_0_1_9_1_0 + 1.33333333333333*G0_0_0_5_0_1_9_1_1 - 0.666666666666666*G0_0_0_5_0_1_10_1_0 - 0.666666666666666*G0_0_0_5_0_1_11_1_0 - 1.33333333333333*G0_0_0_5_0_1_11_1_1 - 0.5*G0_0_0_6_1_0_0_0_0 - 0.5*G0_0_0_6_1_0_0_0_1 - 0.166666666666667*G0_0_0_6_1_0_1_0_0 - 0.166666666666667*G0_0_0_6_1_0_2_0_1 + 0.666666666666667*G0_0_0_6_1_0_4_0_1 + 0.666666666666667*G0_0_0_6_1_0_5_0_0 - 0.5*G0_0_0_6_1_0_6_1_0 - 0.5*G0_0_0_6_1_0_6_1_1 - 0.166666666666667*G0_0_0_6_1_0_7_1_0 - 0.166666666666667*G0_0_0_6_1_0_8_1_1 + 0.666666666666667*G0_0_0_6_1_0_10_1_1 + 0.666666666666667*G0_0_0_6_1_0_11_1_0 - 0.5*G0_0_0_6_1_1_0_0_0 - 0.5*G0_0_0_6_1_1_0_0_1 - 0.166666666666667*G0_0_0_6_1_1_1_0_0 - 0.166666666666667*G0_0_0_6_1_1_2_0_1 + 0.666666666666667*G0_0_0_6_1_1_4_0_1 + 0.666666666666667*G0_0_0_6_1_1_5_0_0 - 0.5*G0_0_0_6_1_1_6_1_0 - 0.5*G0_0_0_6_1_1_6_1_1 - 0.166666666666667*G0_0_0_6_1_1_7_1_0 - 0.166666666666667*G0_0_0_6_1_1_8_1_1 + 0.666666666666667*G0_0_0_6_1_1_10_1_1 + 0.666666666666667*G0_0_0_6_1_1_11_1_0 - 0.166666666666667*G0_0_0_7_1_0_0_0_0 - 0.166666666666667*G0_0_0_7_1_0_0_0_1 - 0.5*G0_0_0_7_1_0_1_0_0 + 0.166666666666667*G0_0_0_7_1_0_2_0_1 - 0.666666666666666*G0_0_0_7_1_0_3_0_1 + 0.666666666666667*G0_0_0_7_1_0_5_0_0 + 0.666666666666666*G0_0_0_7_1_0_5_0_1 - 0.166666666666667*G0_0_0_7_1_0_6_1_0 - 0.166666666666667*G0_0_0_7_1_0_6_1_1 - 0.5*G0_0_0_7_1_0_7_1_0 + 0.166666666666667*G0_0_0_7_1_0_8_1_1 - 0.666666666666666*G0_0_0_7_1_0_9_1_1 + 0.666666666666667*G0_0_0_7_1_0_11_1_0 + 0.666666666666666*G0_0_0_7_1_0_11_1_1 - 0.166666666666667*G0_0_0_8_1_1_0_0_0 - 0.166666666666667*G0_0_0_8_1_1_0_0_1 + 0.166666666666667*G0_0_0_8_1_1_1_0_0 - 0.5*G0_0_0_8_1_1_2_0_1 - 0.666666666666666*G0_0_0_8_1_1_3_0_0 + 0.666666666666666*G0_0_0_8_1_1_4_0_0 + 0.666666666666666*G0_0_0_8_1_1_4_0_1 - 0.166666666666667*G0_0_0_8_1_1_6_1_0 - 0.166666666666667*G0_0_0_8_1_1_6_1_1 + 0.166666666666667*G0_0_0_8_1_1_7_1_0 - 0.5*G0_0_0_8_1_1_8_1_1 - 0.666666666666666*G0_0_0_8_1_1_9_1_0 + 0.666666666666666*G0_0_0_8_1_1_10_1_0 + 0.666666666666666*G0_0_0_8_1_1_10_1_1 - 0.666666666666666*G0_0_0_9_1_0_2_0_1 - 1.33333333333333*G0_0_0_9_1_0_3_0_0 - 0.666666666666665*G0_0_0_9_1_0_3_0_1 + 1.33333333333333*G0_0_0_9_1_0_4_0_0 + 0.666666666666666*G0_0_0_9_1_0_4_0_1 + 0.666666666666666*G0_0_0_9_1_0_5_0_1 - 0.666666666666666*G0_0_0_9_1_0_8_1_1 - 1.33333333333333*G0_0_0_9_1_0_9_1_0 - 0.666666666666665*G0_0_0_9_1_0_9_1_1 + 1.33333333333333*G0_0_0_9_1_0_10_1_0 + 0.666666666666666*G0_0_0_9_1_0_10_1_1 + 0.666666666666666*G0_0_0_9_1_0_11_1_1 - 0.666666666666666*G0_0_0_9_1_1_1_0_0 - 0.666666666666665*G0_0_0_9_1_1_3_0_0 - 1.33333333333333*G0_0_0_9_1_1_3_0_1 + 0.666666666666665*G0_0_0_9_1_1_4_0_0 + 0.666666666666666*G0_0_0_9_1_1_5_0_0 + 1.33333333333333*G0_0_0_9_1_1_5_0_1 - 0.666666666666666*G0_0_0_9_1_1_7_1_0 - 0.666666666666665*G0_0_0_9_1_1_9_1_0 - 1.33333333333333*G0_0_0_9_1_1_9_1_1 + 0.666666666666665*G0_0_0_9_1_1_10_1_0 + 0.666666666666666*G0_0_0_9_1_1_11_1_0 + 1.33333333333333*G0_0_0_9_1_1_11_1_1 + 0.666666666666666*G0_0_0_10_1_0_2_0_1 + 1.33333333333333*G0_0_0_10_1_0_3_0_0 + 0.666666666666665*G0_0_0_10_1_0_3_0_1 - 1.33333333333333*G0_0_0_10_1_0_4_0_0 - 0.666666666666666*G0_0_0_10_1_0_4_0_1 - 0.666666666666666*G0_0_0_10_1_0_5_0_1 + 0.666666666666666*G0_0_0_10_1_0_8_1_1 + 1.33333333333333*G0_0_0_10_1_0_9_1_0 + 0.666666666666665*G0_0_0_10_1_0_9_1_1 - 1.33333333333333*G0_0_0_10_1_0_10_1_0 - 0.666666666666666*G0_0_0_10_1_0_10_1_1 - 0.666666666666666*G0_0_0_10_1_0_11_1_1 + 0.666666666666667*G0_0_0_10_1_1_0_0_0 + 0.666666666666667*G0_0_0_10_1_1_0_0_1 + 0.666666666666666*G0_0_0_10_1_1_2_0_1 + 0.666666666666666*G0_0_0_10_1_1_3_0_0 - 0.666666666666666*G0_0_0_10_1_1_4_0_0 - 1.33333333333333*G0_0_0_10_1_1_4_0_1 - 0.666666666666667*G0_0_0_10_1_1_5_0_0 + 0.666666666666667*G0_0_0_10_1_1_6_1_0 + 0.666666666666667*G0_0_0_10_1_1_6_1_1 + 0.666666666666666*G0_0_0_10_1_1_8_1_1 + 0.666666666666666*G0_0_0_10_1_1_9_1_0 - 0.666666666666666*G0_0_0_10_1_1_10_1_0 - 1.33333333333333*G0_0_0_10_1_1_10_1_1 - 0.666666666666667*G0_0_0_10_1_1_11_1_0 + 0.666666666666667*G0_0_0_11_1_0_0_0_0 + 0.666666666666667*G0_0_0_11_1_0_0_0_1 + 0.666666666666666*G0_0_0_11_1_0_1_0_0 + 0.666666666666666*G0_0_0_11_1_0_3_0_1 - 0.666666666666667*G0_0_0_11_1_0_4_0_1 - 1.33333333333333*G0_0_0_11_1_0_5_0_0 - 0.666666666666666*G0_0_0_11_1_0_5_0_1 + 0.666666666666667*G0_0_0_11_1_0_6_1_0 + 0.666666666666667*G0_0_0_11_1_0_6_1_1 + 0.666666666666666*G0_0_0_11_1_0_7_1_0 + 0.666666666666666*G0_0_0_11_1_0_9_1_1 - 0.666666666666667*G0_0_0_11_1_0_10_1_1 - 1.33333333333333*G0_0_0_11_1_0_11_1_0 - 0.666666666666666*G0_0_0_11_1_0_11_1_1 + 0.666666666666666*G0_0_0_11_1_1_1_0_0 + 0.666666666666666*G0_0_0_11_1_1_3_0_0 + 1.33333333333333*G0_0_0_11_1_1_3_0_1 - 0.666666666666666*G0_0_0_11_1_1_4_0_0 - 0.666666666666666*G0_0_0_11_1_1_5_0_0 - 1.33333333333333*G0_0_0_11_1_1_5_0_1 + 0.666666666666666*G0_0_0_11_1_1_7_1_0 + 0.666666666666666*G0_0_0_11_1_1_9_1_0 + 1.33333333333333*G0_0_0_11_1_1_9_1_1 - 0.666666666666666*G0_0_0_11_1_1_10_1_0 - 0.666666666666666*G0_0_0_11_1_1_11_1_0 - 1.33333333333333*G0_0_0_11_1_1_11_1_1; + A[35] = A[14]; + A[23] = -A[8] - 0.5*G0_1_1_0_0_0_0_0_0 - 0.5*G0_1_1_0_0_0_0_0_1 - 0.166666666666667*G0_1_1_0_0_0_1_0_0 - 0.166666666666667*G0_1_1_0_0_0_2_0_1 + 0.666666666666667*G0_1_1_0_0_0_4_0_1 + 0.666666666666667*G0_1_1_0_0_0_5_0_0 - 0.5*G0_1_1_0_0_0_6_1_0 - 0.5*G0_1_1_0_0_0_6_1_1 - 0.166666666666667*G0_1_1_0_0_0_7_1_0 - 0.166666666666667*G0_1_1_0_0_0_8_1_1 + 0.666666666666667*G0_1_1_0_0_0_10_1_1 + 0.666666666666667*G0_1_1_0_0_0_11_1_0 - 0.5*G0_1_1_0_0_1_0_0_0 - 0.5*G0_1_1_0_0_1_0_0_1 - 0.166666666666667*G0_1_1_0_0_1_1_0_0 - 0.166666666666667*G0_1_1_0_0_1_2_0_1 + 0.666666666666667*G0_1_1_0_0_1_4_0_1 + 0.666666666666667*G0_1_1_0_0_1_5_0_0 - 0.5*G0_1_1_0_0_1_6_1_0 - 0.5*G0_1_1_0_0_1_6_1_1 - 0.166666666666667*G0_1_1_0_0_1_7_1_0 - 0.166666666666667*G0_1_1_0_0_1_8_1_1 + 0.666666666666667*G0_1_1_0_0_1_10_1_1 + 0.666666666666667*G0_1_1_0_0_1_11_1_0 - 0.166666666666667*G0_1_1_1_0_0_0_0_0 - 0.166666666666667*G0_1_1_1_0_0_0_0_1 - 0.5*G0_1_1_1_0_0_1_0_0 + 0.166666666666667*G0_1_1_1_0_0_2_0_1 - 0.666666666666666*G0_1_1_1_0_0_3_0_1 + 0.666666666666666*G0_1_1_1_0_0_5_0_0 + 0.666666666666666*G0_1_1_1_0_0_5_0_1 - 0.166666666666667*G0_1_1_1_0_0_6_1_0 - 0.166666666666667*G0_1_1_1_0_0_6_1_1 - 0.5*G0_1_1_1_0_0_7_1_0 + 0.166666666666667*G0_1_1_1_0_0_8_1_1 - 0.666666666666666*G0_1_1_1_0_0_9_1_1 + 0.666666666666666*G0_1_1_1_0_0_11_1_0 + 0.666666666666666*G0_1_1_1_0_0_11_1_1 - 0.166666666666667*G0_1_1_2_0_1_0_0_0 - 0.166666666666667*G0_1_1_2_0_1_0_0_1 + 0.166666666666667*G0_1_1_2_0_1_1_0_0 - 0.5*G0_1_1_2_0_1_2_0_1 - 0.666666666666666*G0_1_1_2_0_1_3_0_0 + 0.666666666666666*G0_1_1_2_0_1_4_0_0 + 0.666666666666666*G0_1_1_2_0_1_4_0_1 - 0.166666666666667*G0_1_1_2_0_1_6_1_0 - 0.166666666666667*G0_1_1_2_0_1_6_1_1 + 0.166666666666667*G0_1_1_2_0_1_7_1_0 - 0.5*G0_1_1_2_0_1_8_1_1 - 0.666666666666666*G0_1_1_2_0_1_9_1_0 + 0.666666666666666*G0_1_1_2_0_1_10_1_0 + 0.666666666666666*G0_1_1_2_0_1_10_1_1 - 0.666666666666666*G0_1_1_3_0_0_2_0_1 - 1.33333333333333*G0_1_1_3_0_0_3_0_0 - 0.666666666666665*G0_1_1_3_0_0_3_0_1 + 1.33333333333333*G0_1_1_3_0_0_4_0_0 + 0.666666666666665*G0_1_1_3_0_0_4_0_1 + 0.666666666666665*G0_1_1_3_0_0_5_0_1 - 0.666666666666666*G0_1_1_3_0_0_8_1_1 - 1.33333333333333*G0_1_1_3_0_0_9_1_0 - 0.666666666666665*G0_1_1_3_0_0_9_1_1 + 1.33333333333333*G0_1_1_3_0_0_10_1_0 + 0.666666666666665*G0_1_1_3_0_0_10_1_1 + 0.666666666666665*G0_1_1_3_0_0_11_1_1 - 0.666666666666666*G0_1_1_3_0_1_1_0_0 - 0.666666666666665*G0_1_1_3_0_1_3_0_0 - 1.33333333333333*G0_1_1_3_0_1_3_0_1 + 0.666666666666665*G0_1_1_3_0_1_4_0_0 + 0.666666666666665*G0_1_1_3_0_1_5_0_0 + 1.33333333333333*G0_1_1_3_0_1_5_0_1 - 0.666666666666666*G0_1_1_3_0_1_7_1_0 - 0.666666666666665*G0_1_1_3_0_1_9_1_0 - 1.33333333333333*G0_1_1_3_0_1_9_1_1 + 0.666666666666665*G0_1_1_3_0_1_10_1_0 + 0.666666666666665*G0_1_1_3_0_1_11_1_0 + 1.33333333333333*G0_1_1_3_0_1_11_1_1 + 0.666666666666666*G0_1_1_4_0_0_2_0_1 + 1.33333333333333*G0_1_1_4_0_0_3_0_0 + 0.666666666666665*G0_1_1_4_0_0_3_0_1 - 1.33333333333333*G0_1_1_4_0_0_4_0_0 - 0.666666666666665*G0_1_1_4_0_0_4_0_1 - 0.666666666666665*G0_1_1_4_0_0_5_0_1 + 0.666666666666666*G0_1_1_4_0_0_8_1_1 + 1.33333333333333*G0_1_1_4_0_0_9_1_0 + 0.666666666666665*G0_1_1_4_0_0_9_1_1 - 1.33333333333333*G0_1_1_4_0_0_10_1_0 - 0.666666666666665*G0_1_1_4_0_0_10_1_1 - 0.666666666666665*G0_1_1_4_0_0_11_1_1 + 0.666666666666667*G0_1_1_4_0_1_0_0_0 + 0.666666666666667*G0_1_1_4_0_1_0_0_1 + 0.666666666666666*G0_1_1_4_0_1_2_0_1 + 0.666666666666665*G0_1_1_4_0_1_3_0_0 - 0.666666666666665*G0_1_1_4_0_1_4_0_0 - 1.33333333333333*G0_1_1_4_0_1_4_0_1 - 0.666666666666667*G0_1_1_4_0_1_5_0_0 + 0.666666666666667*G0_1_1_4_0_1_6_1_0 + 0.666666666666667*G0_1_1_4_0_1_6_1_1 + 0.666666666666666*G0_1_1_4_0_1_8_1_1 + 0.666666666666665*G0_1_1_4_0_1_9_1_0 - 0.666666666666665*G0_1_1_4_0_1_10_1_0 - 1.33333333333333*G0_1_1_4_0_1_10_1_1 - 0.666666666666667*G0_1_1_4_0_1_11_1_0 + 0.666666666666667*G0_1_1_5_0_0_0_0_0 + 0.666666666666667*G0_1_1_5_0_0_0_0_1 + 0.666666666666666*G0_1_1_5_0_0_1_0_0 + 0.666666666666665*G0_1_1_5_0_0_3_0_1 - 0.666666666666667*G0_1_1_5_0_0_4_0_1 - 1.33333333333333*G0_1_1_5_0_0_5_0_0 - 0.666666666666665*G0_1_1_5_0_0_5_0_1 + 0.666666666666667*G0_1_1_5_0_0_6_1_0 + 0.666666666666667*G0_1_1_5_0_0_6_1_1 + 0.666666666666666*G0_1_1_5_0_0_7_1_0 + 0.666666666666665*G0_1_1_5_0_0_9_1_1 - 0.666666666666667*G0_1_1_5_0_0_10_1_1 - 1.33333333333333*G0_1_1_5_0_0_11_1_0 - 0.666666666666665*G0_1_1_5_0_0_11_1_1 + 0.666666666666666*G0_1_1_5_0_1_1_0_0 + 0.666666666666665*G0_1_1_5_0_1_3_0_0 + 1.33333333333333*G0_1_1_5_0_1_3_0_1 - 0.666666666666665*G0_1_1_5_0_1_4_0_0 - 0.666666666666665*G0_1_1_5_0_1_5_0_0 - 1.33333333333333*G0_1_1_5_0_1_5_0_1 + 0.666666666666666*G0_1_1_5_0_1_7_1_0 + 0.666666666666665*G0_1_1_5_0_1_9_1_0 + 1.33333333333333*G0_1_1_5_0_1_9_1_1 - 0.666666666666665*G0_1_1_5_0_1_10_1_0 - 0.666666666666665*G0_1_1_5_0_1_11_1_0 - 1.33333333333333*G0_1_1_5_0_1_11_1_1 - 0.5*G0_1_1_6_1_0_0_0_0 - 0.5*G0_1_1_6_1_0_0_0_1 - 0.166666666666667*G0_1_1_6_1_0_1_0_0 - 0.166666666666667*G0_1_1_6_1_0_2_0_1 + 0.666666666666667*G0_1_1_6_1_0_4_0_1 + 0.666666666666667*G0_1_1_6_1_0_5_0_0 - 0.5*G0_1_1_6_1_0_6_1_0 - 0.5*G0_1_1_6_1_0_6_1_1 - 0.166666666666667*G0_1_1_6_1_0_7_1_0 - 0.166666666666667*G0_1_1_6_1_0_8_1_1 + 0.666666666666667*G0_1_1_6_1_0_10_1_1 + 0.666666666666667*G0_1_1_6_1_0_11_1_0 - 0.5*G0_1_1_6_1_1_0_0_0 - 0.5*G0_1_1_6_1_1_0_0_1 - 0.166666666666667*G0_1_1_6_1_1_1_0_0 - 0.166666666666667*G0_1_1_6_1_1_2_0_1 + 0.666666666666667*G0_1_1_6_1_1_4_0_1 + 0.666666666666667*G0_1_1_6_1_1_5_0_0 - 0.5*G0_1_1_6_1_1_6_1_0 - 0.5*G0_1_1_6_1_1_6_1_1 - 0.166666666666667*G0_1_1_6_1_1_7_1_0 - 0.166666666666667*G0_1_1_6_1_1_8_1_1 + 0.666666666666667*G0_1_1_6_1_1_10_1_1 + 0.666666666666667*G0_1_1_6_1_1_11_1_0 - 0.166666666666667*G0_1_1_7_1_0_0_0_0 - 0.166666666666667*G0_1_1_7_1_0_0_0_1 - 0.5*G0_1_1_7_1_0_1_0_0 + 0.166666666666667*G0_1_1_7_1_0_2_0_1 - 0.666666666666666*G0_1_1_7_1_0_3_0_1 + 0.666666666666666*G0_1_1_7_1_0_5_0_0 + 0.666666666666666*G0_1_1_7_1_0_5_0_1 - 0.166666666666667*G0_1_1_7_1_0_6_1_0 - 0.166666666666667*G0_1_1_7_1_0_6_1_1 - 0.5*G0_1_1_7_1_0_7_1_0 + 0.166666666666667*G0_1_1_7_1_0_8_1_1 - 0.666666666666666*G0_1_1_7_1_0_9_1_1 + 0.666666666666666*G0_1_1_7_1_0_11_1_0 + 0.666666666666666*G0_1_1_7_1_0_11_1_1 - 0.166666666666667*G0_1_1_8_1_1_0_0_0 - 0.166666666666667*G0_1_1_8_1_1_0_0_1 + 0.166666666666667*G0_1_1_8_1_1_1_0_0 - 0.5*G0_1_1_8_1_1_2_0_1 - 0.666666666666666*G0_1_1_8_1_1_3_0_0 + 0.666666666666666*G0_1_1_8_1_1_4_0_0 + 0.666666666666666*G0_1_1_8_1_1_4_0_1 - 0.166666666666667*G0_1_1_8_1_1_6_1_0 - 0.166666666666667*G0_1_1_8_1_1_6_1_1 + 0.166666666666667*G0_1_1_8_1_1_7_1_0 - 0.5*G0_1_1_8_1_1_8_1_1 - 0.666666666666666*G0_1_1_8_1_1_9_1_0 + 0.666666666666666*G0_1_1_8_1_1_10_1_0 + 0.666666666666666*G0_1_1_8_1_1_10_1_1 - 0.666666666666666*G0_1_1_9_1_0_2_0_1 - 1.33333333333333*G0_1_1_9_1_0_3_0_0 - 0.666666666666665*G0_1_1_9_1_0_3_0_1 + 1.33333333333333*G0_1_1_9_1_0_4_0_0 + 0.666666666666665*G0_1_1_9_1_0_4_0_1 + 0.666666666666665*G0_1_1_9_1_0_5_0_1 - 0.666666666666666*G0_1_1_9_1_0_8_1_1 - 1.33333333333333*G0_1_1_9_1_0_9_1_0 - 0.666666666666665*G0_1_1_9_1_0_9_1_1 + 1.33333333333333*G0_1_1_9_1_0_10_1_0 + 0.666666666666665*G0_1_1_9_1_0_10_1_1 + 0.666666666666665*G0_1_1_9_1_0_11_1_1 - 0.666666666666666*G0_1_1_9_1_1_1_0_0 - 0.666666666666665*G0_1_1_9_1_1_3_0_0 - 1.33333333333333*G0_1_1_9_1_1_3_0_1 + 0.666666666666665*G0_1_1_9_1_1_4_0_0 + 0.666666666666665*G0_1_1_9_1_1_5_0_0 + 1.33333333333333*G0_1_1_9_1_1_5_0_1 - 0.666666666666666*G0_1_1_9_1_1_7_1_0 - 0.666666666666665*G0_1_1_9_1_1_9_1_0 - 1.33333333333333*G0_1_1_9_1_1_9_1_1 + 0.666666666666665*G0_1_1_9_1_1_10_1_0 + 0.666666666666665*G0_1_1_9_1_1_11_1_0 + 1.33333333333333*G0_1_1_9_1_1_11_1_1 + 0.666666666666666*G0_1_1_10_1_0_2_0_1 + 1.33333333333333*G0_1_1_10_1_0_3_0_0 + 0.666666666666665*G0_1_1_10_1_0_3_0_1 - 1.33333333333333*G0_1_1_10_1_0_4_0_0 - 0.666666666666665*G0_1_1_10_1_0_4_0_1 - 0.666666666666665*G0_1_1_10_1_0_5_0_1 + 0.666666666666666*G0_1_1_10_1_0_8_1_1 + 1.33333333333333*G0_1_1_10_1_0_9_1_0 + 0.666666666666665*G0_1_1_10_1_0_9_1_1 - 1.33333333333333*G0_1_1_10_1_0_10_1_0 - 0.666666666666665*G0_1_1_10_1_0_10_1_1 - 0.666666666666665*G0_1_1_10_1_0_11_1_1 + 0.666666666666667*G0_1_1_10_1_1_0_0_0 + 0.666666666666667*G0_1_1_10_1_1_0_0_1 + 0.666666666666666*G0_1_1_10_1_1_2_0_1 + 0.666666666666665*G0_1_1_10_1_1_3_0_0 - 0.666666666666665*G0_1_1_10_1_1_4_0_0 - 1.33333333333333*G0_1_1_10_1_1_4_0_1 - 0.666666666666667*G0_1_1_10_1_1_5_0_0 + 0.666666666666667*G0_1_1_10_1_1_6_1_0 + 0.666666666666667*G0_1_1_10_1_1_6_1_1 + 0.666666666666666*G0_1_1_10_1_1_8_1_1 + 0.666666666666665*G0_1_1_10_1_1_9_1_0 - 0.666666666666665*G0_1_1_10_1_1_10_1_0 - 1.33333333333333*G0_1_1_10_1_1_10_1_1 - 0.666666666666667*G0_1_1_10_1_1_11_1_0 + 0.666666666666667*G0_1_1_11_1_0_0_0_0 + 0.666666666666667*G0_1_1_11_1_0_0_0_1 + 0.666666666666666*G0_1_1_11_1_0_1_0_0 + 0.666666666666665*G0_1_1_11_1_0_3_0_1 - 0.666666666666667*G0_1_1_11_1_0_4_0_1 - 1.33333333333333*G0_1_1_11_1_0_5_0_0 - 0.666666666666665*G0_1_1_11_1_0_5_0_1 + 0.666666666666667*G0_1_1_11_1_0_6_1_0 + 0.666666666666667*G0_1_1_11_1_0_6_1_1 + 0.666666666666666*G0_1_1_11_1_0_7_1_0 + 0.666666666666665*G0_1_1_11_1_0_9_1_1 - 0.666666666666667*G0_1_1_11_1_0_10_1_1 - 1.33333333333333*G0_1_1_11_1_0_11_1_0 - 0.666666666666665*G0_1_1_11_1_0_11_1_1 + 0.666666666666666*G0_1_1_11_1_1_1_0_0 + 0.666666666666665*G0_1_1_11_1_1_3_0_0 + 1.33333333333333*G0_1_1_11_1_1_3_0_1 - 0.666666666666665*G0_1_1_11_1_1_4_0_0 - 0.666666666666665*G0_1_1_11_1_1_5_0_0 - 1.33333333333333*G0_1_1_11_1_1_5_0_1 + 0.666666666666666*G0_1_1_11_1_1_7_1_0 + 0.666666666666665*G0_1_1_11_1_1_9_1_0 + 1.33333333333333*G0_1_1_11_1_1_9_1_1 - 0.666666666666665*G0_1_1_11_1_1_10_1_0 - 0.666666666666665*G0_1_1_11_1_1_11_1_0 - 1.33333333333333*G0_1_1_11_1_1_11_1_1; + A[21] = -A[23] + 0.5*G0_0_0_0_0_0_0_0_0 + 0.5*G0_0_0_0_0_0_0_0_1 + 0.166666666666667*G0_0_0_0_0_0_1_0_0 + 0.166666666666667*G0_0_0_0_0_0_2_0_1 - 0.666666666666667*G0_0_0_0_0_0_4_0_1 - 0.666666666666667*G0_0_0_0_0_0_5_0_0 + 0.5*G0_0_0_0_0_0_6_1_0 + 0.5*G0_0_0_0_0_0_6_1_1 + 0.166666666666667*G0_0_0_0_0_0_7_1_0 + 0.166666666666667*G0_0_0_0_0_0_8_1_1 - 0.666666666666667*G0_0_0_0_0_0_10_1_1 - 0.666666666666667*G0_0_0_0_0_0_11_1_0 + 0.5*G0_0_0_0_0_1_0_0_0 + 0.5*G0_0_0_0_0_1_0_0_1 + 0.166666666666667*G0_0_0_0_0_1_1_0_0 + 0.166666666666667*G0_0_0_0_0_1_2_0_1 - 0.666666666666667*G0_0_0_0_0_1_4_0_1 - 0.666666666666667*G0_0_0_0_0_1_5_0_0 + 0.5*G0_0_0_0_0_1_6_1_0 + 0.5*G0_0_0_0_0_1_6_1_1 + 0.166666666666667*G0_0_0_0_0_1_7_1_0 + 0.166666666666667*G0_0_0_0_0_1_8_1_1 - 0.666666666666667*G0_0_0_0_0_1_10_1_1 - 0.666666666666667*G0_0_0_0_0_1_11_1_0 + 0.166666666666667*G0_0_0_1_0_0_0_0_0 + 0.166666666666667*G0_0_0_1_0_0_0_0_1 + 0.5*G0_0_0_1_0_0_1_0_0 - 0.166666666666667*G0_0_0_1_0_0_2_0_1 + 0.666666666666666*G0_0_0_1_0_0_3_0_1 - 0.666666666666667*G0_0_0_1_0_0_5_0_0 - 0.666666666666666*G0_0_0_1_0_0_5_0_1 + 0.166666666666667*G0_0_0_1_0_0_6_1_0 + 0.166666666666667*G0_0_0_1_0_0_6_1_1 + 0.5*G0_0_0_1_0_0_7_1_0 - 0.166666666666667*G0_0_0_1_0_0_8_1_1 + 0.666666666666666*G0_0_0_1_0_0_9_1_1 - 0.666666666666667*G0_0_0_1_0_0_11_1_0 - 0.666666666666666*G0_0_0_1_0_0_11_1_1 + 0.166666666666667*G0_0_0_2_0_1_0_0_0 + 0.166666666666667*G0_0_0_2_0_1_0_0_1 - 0.166666666666667*G0_0_0_2_0_1_1_0_0 + 0.5*G0_0_0_2_0_1_2_0_1 + 0.666666666666666*G0_0_0_2_0_1_3_0_0 - 0.666666666666666*G0_0_0_2_0_1_4_0_0 - 0.666666666666666*G0_0_0_2_0_1_4_0_1 + 0.166666666666667*G0_0_0_2_0_1_6_1_0 + 0.166666666666667*G0_0_0_2_0_1_6_1_1 - 0.166666666666667*G0_0_0_2_0_1_7_1_0 + 0.5*G0_0_0_2_0_1_8_1_1 + 0.666666666666666*G0_0_0_2_0_1_9_1_0 - 0.666666666666666*G0_0_0_2_0_1_10_1_0 - 0.666666666666666*G0_0_0_2_0_1_10_1_1 + 0.666666666666666*G0_0_0_3_0_0_2_0_1 + 1.33333333333333*G0_0_0_3_0_0_3_0_0 + 0.666666666666665*G0_0_0_3_0_0_3_0_1 - 1.33333333333333*G0_0_0_3_0_0_4_0_0 - 0.666666666666666*G0_0_0_3_0_0_4_0_1 - 0.666666666666666*G0_0_0_3_0_0_5_0_1 + 0.666666666666666*G0_0_0_3_0_0_8_1_1 + 1.33333333333333*G0_0_0_3_0_0_9_1_0 + 0.666666666666665*G0_0_0_3_0_0_9_1_1 - 1.33333333333333*G0_0_0_3_0_0_10_1_0 - 0.666666666666666*G0_0_0_3_0_0_10_1_1 - 0.666666666666666*G0_0_0_3_0_0_11_1_1 + 0.666666666666666*G0_0_0_3_0_1_1_0_0 + 0.666666666666665*G0_0_0_3_0_1_3_0_0 + 1.33333333333333*G0_0_0_3_0_1_3_0_1 - 0.666666666666665*G0_0_0_3_0_1_4_0_0 - 0.666666666666666*G0_0_0_3_0_1_5_0_0 - 1.33333333333333*G0_0_0_3_0_1_5_0_1 + 0.666666666666666*G0_0_0_3_0_1_7_1_0 + 0.666666666666665*G0_0_0_3_0_1_9_1_0 + 1.33333333333333*G0_0_0_3_0_1_9_1_1 - 0.666666666666665*G0_0_0_3_0_1_10_1_0 - 0.666666666666666*G0_0_0_3_0_1_11_1_0 - 1.33333333333333*G0_0_0_3_0_1_11_1_1 - 0.666666666666666*G0_0_0_4_0_0_2_0_1 - 1.33333333333333*G0_0_0_4_0_0_3_0_0 - 0.666666666666665*G0_0_0_4_0_0_3_0_1 + 1.33333333333333*G0_0_0_4_0_0_4_0_0 + 0.666666666666666*G0_0_0_4_0_0_4_0_1 + 0.666666666666666*G0_0_0_4_0_0_5_0_1 - 0.666666666666666*G0_0_0_4_0_0_8_1_1 - 1.33333333333333*G0_0_0_4_0_0_9_1_0 - 0.666666666666665*G0_0_0_4_0_0_9_1_1 + 1.33333333333333*G0_0_0_4_0_0_10_1_0 + 0.666666666666666*G0_0_0_4_0_0_10_1_1 + 0.666666666666666*G0_0_0_4_0_0_11_1_1 - 0.666666666666667*G0_0_0_4_0_1_0_0_0 - 0.666666666666667*G0_0_0_4_0_1_0_0_1 - 0.666666666666666*G0_0_0_4_0_1_2_0_1 - 0.666666666666666*G0_0_0_4_0_1_3_0_0 + 0.666666666666666*G0_0_0_4_0_1_4_0_0 + 1.33333333333333*G0_0_0_4_0_1_4_0_1 + 0.666666666666667*G0_0_0_4_0_1_5_0_0 - 0.666666666666667*G0_0_0_4_0_1_6_1_0 - 0.666666666666667*G0_0_0_4_0_1_6_1_1 - 0.666666666666666*G0_0_0_4_0_1_8_1_1 - 0.666666666666666*G0_0_0_4_0_1_9_1_0 + 0.666666666666666*G0_0_0_4_0_1_10_1_0 + 1.33333333333333*G0_0_0_4_0_1_10_1_1 + 0.666666666666667*G0_0_0_4_0_1_11_1_0 - 0.666666666666667*G0_0_0_5_0_0_0_0_0 - 0.666666666666667*G0_0_0_5_0_0_0_0_1 - 0.666666666666666*G0_0_0_5_0_0_1_0_0 - 0.666666666666666*G0_0_0_5_0_0_3_0_1 + 0.666666666666667*G0_0_0_5_0_0_4_0_1 + 1.33333333333333*G0_0_0_5_0_0_5_0_0 + 0.666666666666666*G0_0_0_5_0_0_5_0_1 - 0.666666666666667*G0_0_0_5_0_0_6_1_0 - 0.666666666666667*G0_0_0_5_0_0_6_1_1 - 0.666666666666666*G0_0_0_5_0_0_7_1_0 - 0.666666666666666*G0_0_0_5_0_0_9_1_1 + 0.666666666666667*G0_0_0_5_0_0_10_1_1 + 1.33333333333333*G0_0_0_5_0_0_11_1_0 + 0.666666666666666*G0_0_0_5_0_0_11_1_1 - 0.666666666666666*G0_0_0_5_0_1_1_0_0 - 0.666666666666666*G0_0_0_5_0_1_3_0_0 - 1.33333333333333*G0_0_0_5_0_1_3_0_1 + 0.666666666666666*G0_0_0_5_0_1_4_0_0 + 0.666666666666666*G0_0_0_5_0_1_5_0_0 + 1.33333333333333*G0_0_0_5_0_1_5_0_1 - 0.666666666666666*G0_0_0_5_0_1_7_1_0 - 0.666666666666666*G0_0_0_5_0_1_9_1_0 - 1.33333333333333*G0_0_0_5_0_1_9_1_1 + 0.666666666666666*G0_0_0_5_0_1_10_1_0 + 0.666666666666666*G0_0_0_5_0_1_11_1_0 + 1.33333333333333*G0_0_0_5_0_1_11_1_1 + 0.5*G0_0_0_6_1_0_0_0_0 + 0.5*G0_0_0_6_1_0_0_0_1 + 0.166666666666667*G0_0_0_6_1_0_1_0_0 + 0.166666666666667*G0_0_0_6_1_0_2_0_1 - 0.666666666666667*G0_0_0_6_1_0_4_0_1 - 0.666666666666667*G0_0_0_6_1_0_5_0_0 + 0.5*G0_0_0_6_1_0_6_1_0 + 0.5*G0_0_0_6_1_0_6_1_1 + 0.166666666666667*G0_0_0_6_1_0_7_1_0 + 0.166666666666667*G0_0_0_6_1_0_8_1_1 - 0.666666666666667*G0_0_0_6_1_0_10_1_1 - 0.666666666666667*G0_0_0_6_1_0_11_1_0 + 0.5*G0_0_0_6_1_1_0_0_0 + 0.5*G0_0_0_6_1_1_0_0_1 + 0.166666666666667*G0_0_0_6_1_1_1_0_0 + 0.166666666666667*G0_0_0_6_1_1_2_0_1 - 0.666666666666667*G0_0_0_6_1_1_4_0_1 - 0.666666666666667*G0_0_0_6_1_1_5_0_0 + 0.5*G0_0_0_6_1_1_6_1_0 + 0.5*G0_0_0_6_1_1_6_1_1 + 0.166666666666667*G0_0_0_6_1_1_7_1_0 + 0.166666666666667*G0_0_0_6_1_1_8_1_1 - 0.666666666666667*G0_0_0_6_1_1_10_1_1 - 0.666666666666667*G0_0_0_6_1_1_11_1_0 + 0.166666666666667*G0_0_0_7_1_0_0_0_0 + 0.166666666666667*G0_0_0_7_1_0_0_0_1 + 0.5*G0_0_0_7_1_0_1_0_0 - 0.166666666666667*G0_0_0_7_1_0_2_0_1 + 0.666666666666666*G0_0_0_7_1_0_3_0_1 - 0.666666666666667*G0_0_0_7_1_0_5_0_0 - 0.666666666666666*G0_0_0_7_1_0_5_0_1 + 0.166666666666667*G0_0_0_7_1_0_6_1_0 + 0.166666666666667*G0_0_0_7_1_0_6_1_1 + 0.5*G0_0_0_7_1_0_7_1_0 - 0.166666666666667*G0_0_0_7_1_0_8_1_1 + 0.666666666666666*G0_0_0_7_1_0_9_1_1 - 0.666666666666667*G0_0_0_7_1_0_11_1_0 - 0.666666666666666*G0_0_0_7_1_0_11_1_1 + 0.166666666666667*G0_0_0_8_1_1_0_0_0 + 0.166666666666667*G0_0_0_8_1_1_0_0_1 - 0.166666666666667*G0_0_0_8_1_1_1_0_0 + 0.5*G0_0_0_8_1_1_2_0_1 + 0.666666666666666*G0_0_0_8_1_1_3_0_0 - 0.666666666666666*G0_0_0_8_1_1_4_0_0 - 0.666666666666666*G0_0_0_8_1_1_4_0_1 + 0.166666666666667*G0_0_0_8_1_1_6_1_0 + 0.166666666666667*G0_0_0_8_1_1_6_1_1 - 0.166666666666667*G0_0_0_8_1_1_7_1_0 + 0.5*G0_0_0_8_1_1_8_1_1 + 0.666666666666666*G0_0_0_8_1_1_9_1_0 - 0.666666666666666*G0_0_0_8_1_1_10_1_0 - 0.666666666666666*G0_0_0_8_1_1_10_1_1 + 0.666666666666666*G0_0_0_9_1_0_2_0_1 + 1.33333333333333*G0_0_0_9_1_0_3_0_0 + 0.666666666666665*G0_0_0_9_1_0_3_0_1 - 1.33333333333333*G0_0_0_9_1_0_4_0_0 - 0.666666666666666*G0_0_0_9_1_0_4_0_1 - 0.666666666666666*G0_0_0_9_1_0_5_0_1 + 0.666666666666666*G0_0_0_9_1_0_8_1_1 + 1.33333333333333*G0_0_0_9_1_0_9_1_0 + 0.666666666666665*G0_0_0_9_1_0_9_1_1 - 1.33333333333333*G0_0_0_9_1_0_10_1_0 - 0.666666666666666*G0_0_0_9_1_0_10_1_1 - 0.666666666666666*G0_0_0_9_1_0_11_1_1 + 0.666666666666666*G0_0_0_9_1_1_1_0_0 + 0.666666666666665*G0_0_0_9_1_1_3_0_0 + 1.33333333333333*G0_0_0_9_1_1_3_0_1 - 0.666666666666665*G0_0_0_9_1_1_4_0_0 - 0.666666666666666*G0_0_0_9_1_1_5_0_0 - 1.33333333333333*G0_0_0_9_1_1_5_0_1 + 0.666666666666666*G0_0_0_9_1_1_7_1_0 + 0.666666666666665*G0_0_0_9_1_1_9_1_0 + 1.33333333333333*G0_0_0_9_1_1_9_1_1 - 0.666666666666665*G0_0_0_9_1_1_10_1_0 - 0.666666666666666*G0_0_0_9_1_1_11_1_0 - 1.33333333333333*G0_0_0_9_1_1_11_1_1 - 0.666666666666666*G0_0_0_10_1_0_2_0_1 - 1.33333333333333*G0_0_0_10_1_0_3_0_0 - 0.666666666666665*G0_0_0_10_1_0_3_0_1 + 1.33333333333333*G0_0_0_10_1_0_4_0_0 + 0.666666666666666*G0_0_0_10_1_0_4_0_1 + 0.666666666666666*G0_0_0_10_1_0_5_0_1 - 0.666666666666666*G0_0_0_10_1_0_8_1_1 - 1.33333333333333*G0_0_0_10_1_0_9_1_0 - 0.666666666666665*G0_0_0_10_1_0_9_1_1 + 1.33333333333333*G0_0_0_10_1_0_10_1_0 + 0.666666666666666*G0_0_0_10_1_0_10_1_1 + 0.666666666666666*G0_0_0_10_1_0_11_1_1 - 0.666666666666667*G0_0_0_10_1_1_0_0_0 - 0.666666666666667*G0_0_0_10_1_1_0_0_1 - 0.666666666666666*G0_0_0_10_1_1_2_0_1 - 0.666666666666666*G0_0_0_10_1_1_3_0_0 + 0.666666666666666*G0_0_0_10_1_1_4_0_0 + 1.33333333333333*G0_0_0_10_1_1_4_0_1 + 0.666666666666667*G0_0_0_10_1_1_5_0_0 - 0.666666666666667*G0_0_0_10_1_1_6_1_0 - 0.666666666666667*G0_0_0_10_1_1_6_1_1 - 0.666666666666666*G0_0_0_10_1_1_8_1_1 - 0.666666666666666*G0_0_0_10_1_1_9_1_0 + 0.666666666666666*G0_0_0_10_1_1_10_1_0 + 1.33333333333333*G0_0_0_10_1_1_10_1_1 + 0.666666666666667*G0_0_0_10_1_1_11_1_0 - 0.666666666666667*G0_0_0_11_1_0_0_0_0 - 0.666666666666667*G0_0_0_11_1_0_0_0_1 - 0.666666666666666*G0_0_0_11_1_0_1_0_0 - 0.666666666666666*G0_0_0_11_1_0_3_0_1 + 0.666666666666667*G0_0_0_11_1_0_4_0_1 + 1.33333333333333*G0_0_0_11_1_0_5_0_0 + 0.666666666666666*G0_0_0_11_1_0_5_0_1 - 0.666666666666667*G0_0_0_11_1_0_6_1_0 - 0.666666666666667*G0_0_0_11_1_0_6_1_1 - 0.666666666666666*G0_0_0_11_1_0_7_1_0 - 0.666666666666666*G0_0_0_11_1_0_9_1_1 + 0.666666666666667*G0_0_0_11_1_0_10_1_1 + 1.33333333333333*G0_0_0_11_1_0_11_1_0 + 0.666666666666666*G0_0_0_11_1_0_11_1_1 - 0.666666666666666*G0_0_0_11_1_1_1_0_0 - 0.666666666666666*G0_0_0_11_1_1_3_0_0 - 1.33333333333333*G0_0_0_11_1_1_3_0_1 + 0.666666666666666*G0_0_0_11_1_1_4_0_0 + 0.666666666666666*G0_0_0_11_1_1_5_0_0 + 1.33333333333333*G0_0_0_11_1_1_5_0_1 - 0.666666666666666*G0_0_0_11_1_1_7_1_0 - 0.666666666666666*G0_0_0_11_1_1_9_1_0 - 1.33333333333333*G0_0_0_11_1_1_9_1_1 + 0.666666666666666*G0_0_0_11_1_1_10_1_0 + 0.666666666666666*G0_0_0_11_1_1_11_1_0 + 1.33333333333333*G0_0_0_11_1_1_11_1_1 + 0.5*G0_1_0_0_0_0_0_0_0 + 0.5*G0_1_0_0_0_0_0_0_1 + 0.166666666666667*G0_1_0_0_0_0_1_0_0 + 0.166666666666667*G0_1_0_0_0_0_2_0_1 - 0.666666666666667*G0_1_0_0_0_0_4_0_1 - 0.666666666666667*G0_1_0_0_0_0_5_0_0 + 0.5*G0_1_0_0_0_0_6_1_0 + 0.5*G0_1_0_0_0_0_6_1_1 + 0.166666666666667*G0_1_0_0_0_0_7_1_0 + 0.166666666666667*G0_1_0_0_0_0_8_1_1 - 0.666666666666667*G0_1_0_0_0_0_10_1_1 - 0.666666666666667*G0_1_0_0_0_0_11_1_0 + 0.5*G0_1_0_0_0_1_0_0_0 + 0.5*G0_1_0_0_0_1_0_0_1 + 0.166666666666667*G0_1_0_0_0_1_1_0_0 + 0.166666666666667*G0_1_0_0_0_1_2_0_1 - 0.666666666666667*G0_1_0_0_0_1_4_0_1 - 0.666666666666667*G0_1_0_0_0_1_5_0_0 + 0.5*G0_1_0_0_0_1_6_1_0 + 0.5*G0_1_0_0_0_1_6_1_1 + 0.166666666666667*G0_1_0_0_0_1_7_1_0 + 0.166666666666667*G0_1_0_0_0_1_8_1_1 - 0.666666666666667*G0_1_0_0_0_1_10_1_1 - 0.666666666666667*G0_1_0_0_0_1_11_1_0 + 0.166666666666667*G0_1_0_1_0_0_0_0_0 + 0.166666666666667*G0_1_0_1_0_0_0_0_1 + 0.5*G0_1_0_1_0_0_1_0_0 - 0.166666666666667*G0_1_0_1_0_0_2_0_1 + 0.666666666666666*G0_1_0_1_0_0_3_0_1 - 0.666666666666666*G0_1_0_1_0_0_5_0_0 - 0.666666666666666*G0_1_0_1_0_0_5_0_1 + 0.166666666666667*G0_1_0_1_0_0_6_1_0 + 0.166666666666667*G0_1_0_1_0_0_6_1_1 + 0.5*G0_1_0_1_0_0_7_1_0 - 0.166666666666667*G0_1_0_1_0_0_8_1_1 + 0.666666666666666*G0_1_0_1_0_0_9_1_1 - 0.666666666666666*G0_1_0_1_0_0_11_1_0 - 0.666666666666666*G0_1_0_1_0_0_11_1_1 + 0.166666666666667*G0_1_0_2_0_1_0_0_0 + 0.166666666666667*G0_1_0_2_0_1_0_0_1 - 0.166666666666667*G0_1_0_2_0_1_1_0_0 + 0.5*G0_1_0_2_0_1_2_0_1 + 0.666666666666666*G0_1_0_2_0_1_3_0_0 - 0.666666666666666*G0_1_0_2_0_1_4_0_0 - 0.666666666666666*G0_1_0_2_0_1_4_0_1 + 0.166666666666667*G0_1_0_2_0_1_6_1_0 + 0.166666666666667*G0_1_0_2_0_1_6_1_1 - 0.166666666666667*G0_1_0_2_0_1_7_1_0 + 0.5*G0_1_0_2_0_1_8_1_1 + 0.666666666666666*G0_1_0_2_0_1_9_1_0 - 0.666666666666666*G0_1_0_2_0_1_10_1_0 - 0.666666666666666*G0_1_0_2_0_1_10_1_1 + 0.666666666666666*G0_1_0_3_0_0_2_0_1 + 1.33333333333333*G0_1_0_3_0_0_3_0_0 + 0.666666666666665*G0_1_0_3_0_0_3_0_1 - 1.33333333333333*G0_1_0_3_0_0_4_0_0 - 0.666666666666666*G0_1_0_3_0_0_4_0_1 - 0.666666666666665*G0_1_0_3_0_0_5_0_1 + 0.666666666666666*G0_1_0_3_0_0_8_1_1 + 1.33333333333333*G0_1_0_3_0_0_9_1_0 + 0.666666666666665*G0_1_0_3_0_0_9_1_1 - 1.33333333333333*G0_1_0_3_0_0_10_1_0 - 0.666666666666666*G0_1_0_3_0_0_10_1_1 - 0.666666666666665*G0_1_0_3_0_0_11_1_1 + 0.666666666666666*G0_1_0_3_0_1_1_0_0 + 0.666666666666665*G0_1_0_3_0_1_3_0_0 + 1.33333333333333*G0_1_0_3_0_1_3_0_1 - 0.666666666666665*G0_1_0_3_0_1_4_0_0 - 0.666666666666665*G0_1_0_3_0_1_5_0_0 - 1.33333333333333*G0_1_0_3_0_1_5_0_1 + 0.666666666666666*G0_1_0_3_0_1_7_1_0 + 0.666666666666665*G0_1_0_3_0_1_9_1_0 + 1.33333333333333*G0_1_0_3_0_1_9_1_1 - 0.666666666666665*G0_1_0_3_0_1_10_1_0 - 0.666666666666665*G0_1_0_3_0_1_11_1_0 - 1.33333333333333*G0_1_0_3_0_1_11_1_1 - 0.666666666666666*G0_1_0_4_0_0_2_0_1 - 1.33333333333333*G0_1_0_4_0_0_3_0_0 - 0.666666666666665*G0_1_0_4_0_0_3_0_1 + 1.33333333333333*G0_1_0_4_0_0_4_0_0 + 0.666666666666666*G0_1_0_4_0_0_4_0_1 + 0.666666666666665*G0_1_0_4_0_0_5_0_1 - 0.666666666666666*G0_1_0_4_0_0_8_1_1 - 1.33333333333333*G0_1_0_4_0_0_9_1_0 - 0.666666666666665*G0_1_0_4_0_0_9_1_1 + 1.33333333333333*G0_1_0_4_0_0_10_1_0 + 0.666666666666666*G0_1_0_4_0_0_10_1_1 + 0.666666666666665*G0_1_0_4_0_0_11_1_1 - 0.666666666666667*G0_1_0_4_0_1_0_0_0 - 0.666666666666667*G0_1_0_4_0_1_0_0_1 - 0.666666666666666*G0_1_0_4_0_1_2_0_1 - 0.666666666666666*G0_1_0_4_0_1_3_0_0 + 0.666666666666666*G0_1_0_4_0_1_4_0_0 + 1.33333333333333*G0_1_0_4_0_1_4_0_1 + 0.666666666666667*G0_1_0_4_0_1_5_0_0 - 0.666666666666667*G0_1_0_4_0_1_6_1_0 - 0.666666666666667*G0_1_0_4_0_1_6_1_1 - 0.666666666666666*G0_1_0_4_0_1_8_1_1 - 0.666666666666666*G0_1_0_4_0_1_9_1_0 + 0.666666666666666*G0_1_0_4_0_1_10_1_0 + 1.33333333333333*G0_1_0_4_0_1_10_1_1 + 0.666666666666667*G0_1_0_4_0_1_11_1_0 - 0.666666666666667*G0_1_0_5_0_0_0_0_0 - 0.666666666666667*G0_1_0_5_0_0_0_0_1 - 0.666666666666666*G0_1_0_5_0_0_1_0_0 - 0.666666666666665*G0_1_0_5_0_0_3_0_1 + 0.666666666666667*G0_1_0_5_0_0_4_0_1 + 1.33333333333333*G0_1_0_5_0_0_5_0_0 + 0.666666666666666*G0_1_0_5_0_0_5_0_1 - 0.666666666666667*G0_1_0_5_0_0_6_1_0 - 0.666666666666667*G0_1_0_5_0_0_6_1_1 - 0.666666666666666*G0_1_0_5_0_0_7_1_0 - 0.666666666666665*G0_1_0_5_0_0_9_1_1 + 0.666666666666667*G0_1_0_5_0_0_10_1_1 + 1.33333333333333*G0_1_0_5_0_0_11_1_0 + 0.666666666666666*G0_1_0_5_0_0_11_1_1 - 0.666666666666666*G0_1_0_5_0_1_1_0_0 - 0.666666666666666*G0_1_0_5_0_1_3_0_0 - 1.33333333333333*G0_1_0_5_0_1_3_0_1 + 0.666666666666666*G0_1_0_5_0_1_4_0_0 + 0.666666666666666*G0_1_0_5_0_1_5_0_0 + 1.33333333333333*G0_1_0_5_0_1_5_0_1 - 0.666666666666666*G0_1_0_5_0_1_7_1_0 - 0.666666666666666*G0_1_0_5_0_1_9_1_0 - 1.33333333333333*G0_1_0_5_0_1_9_1_1 + 0.666666666666666*G0_1_0_5_0_1_10_1_0 + 0.666666666666666*G0_1_0_5_0_1_11_1_0 + 1.33333333333333*G0_1_0_5_0_1_11_1_1 + 0.5*G0_1_0_6_1_0_0_0_0 + 0.5*G0_1_0_6_1_0_0_0_1 + 0.166666666666667*G0_1_0_6_1_0_1_0_0 + 0.166666666666667*G0_1_0_6_1_0_2_0_1 - 0.666666666666667*G0_1_0_6_1_0_4_0_1 - 0.666666666666667*G0_1_0_6_1_0_5_0_0 + 0.5*G0_1_0_6_1_0_6_1_0 + 0.5*G0_1_0_6_1_0_6_1_1 + 0.166666666666667*G0_1_0_6_1_0_7_1_0 + 0.166666666666667*G0_1_0_6_1_0_8_1_1 - 0.666666666666667*G0_1_0_6_1_0_10_1_1 - 0.666666666666667*G0_1_0_6_1_0_11_1_0 + 0.5*G0_1_0_6_1_1_0_0_0 + 0.5*G0_1_0_6_1_1_0_0_1 + 0.166666666666667*G0_1_0_6_1_1_1_0_0 + 0.166666666666667*G0_1_0_6_1_1_2_0_1 - 0.666666666666667*G0_1_0_6_1_1_4_0_1 - 0.666666666666667*G0_1_0_6_1_1_5_0_0 + 0.5*G0_1_0_6_1_1_6_1_0 + 0.5*G0_1_0_6_1_1_6_1_1 + 0.166666666666667*G0_1_0_6_1_1_7_1_0 + 0.166666666666667*G0_1_0_6_1_1_8_1_1 - 0.666666666666667*G0_1_0_6_1_1_10_1_1 - 0.666666666666667*G0_1_0_6_1_1_11_1_0 + 0.166666666666667*G0_1_0_7_1_0_0_0_0 + 0.166666666666667*G0_1_0_7_1_0_0_0_1 + 0.5*G0_1_0_7_1_0_1_0_0 - 0.166666666666667*G0_1_0_7_1_0_2_0_1 + 0.666666666666666*G0_1_0_7_1_0_3_0_1 - 0.666666666666666*G0_1_0_7_1_0_5_0_0 - 0.666666666666666*G0_1_0_7_1_0_5_0_1 + 0.166666666666667*G0_1_0_7_1_0_6_1_0 + 0.166666666666667*G0_1_0_7_1_0_6_1_1 + 0.5*G0_1_0_7_1_0_7_1_0 - 0.166666666666667*G0_1_0_7_1_0_8_1_1 + 0.666666666666666*G0_1_0_7_1_0_9_1_1 - 0.666666666666666*G0_1_0_7_1_0_11_1_0 - 0.666666666666666*G0_1_0_7_1_0_11_1_1 + 0.166666666666667*G0_1_0_8_1_1_0_0_0 + 0.166666666666667*G0_1_0_8_1_1_0_0_1 - 0.166666666666667*G0_1_0_8_1_1_1_0_0 + 0.5*G0_1_0_8_1_1_2_0_1 + 0.666666666666666*G0_1_0_8_1_1_3_0_0 - 0.666666666666666*G0_1_0_8_1_1_4_0_0 - 0.666666666666666*G0_1_0_8_1_1_4_0_1 + 0.166666666666667*G0_1_0_8_1_1_6_1_0 + 0.166666666666667*G0_1_0_8_1_1_6_1_1 - 0.166666666666667*G0_1_0_8_1_1_7_1_0 + 0.5*G0_1_0_8_1_1_8_1_1 + 0.666666666666666*G0_1_0_8_1_1_9_1_0 - 0.666666666666666*G0_1_0_8_1_1_10_1_0 - 0.666666666666666*G0_1_0_8_1_1_10_1_1 + 0.666666666666666*G0_1_0_9_1_0_2_0_1 + 1.33333333333333*G0_1_0_9_1_0_3_0_0 + 0.666666666666665*G0_1_0_9_1_0_3_0_1 - 1.33333333333333*G0_1_0_9_1_0_4_0_0 - 0.666666666666666*G0_1_0_9_1_0_4_0_1 - 0.666666666666665*G0_1_0_9_1_0_5_0_1 + 0.666666666666666*G0_1_0_9_1_0_8_1_1 + 1.33333333333333*G0_1_0_9_1_0_9_1_0 + 0.666666666666665*G0_1_0_9_1_0_9_1_1 - 1.33333333333333*G0_1_0_9_1_0_10_1_0 - 0.666666666666666*G0_1_0_9_1_0_10_1_1 - 0.666666666666665*G0_1_0_9_1_0_11_1_1 + 0.666666666666666*G0_1_0_9_1_1_1_0_0 + 0.666666666666665*G0_1_0_9_1_1_3_0_0 + 1.33333333333333*G0_1_0_9_1_1_3_0_1 - 0.666666666666665*G0_1_0_9_1_1_4_0_0 - 0.666666666666665*G0_1_0_9_1_1_5_0_0 - 1.33333333333333*G0_1_0_9_1_1_5_0_1 + 0.666666666666666*G0_1_0_9_1_1_7_1_0 + 0.666666666666665*G0_1_0_9_1_1_9_1_0 + 1.33333333333333*G0_1_0_9_1_1_9_1_1 - 0.666666666666665*G0_1_0_9_1_1_10_1_0 - 0.666666666666665*G0_1_0_9_1_1_11_1_0 - 1.33333333333333*G0_1_0_9_1_1_11_1_1 - 0.666666666666666*G0_1_0_10_1_0_2_0_1 - 1.33333333333333*G0_1_0_10_1_0_3_0_0 - 0.666666666666665*G0_1_0_10_1_0_3_0_1 + 1.33333333333333*G0_1_0_10_1_0_4_0_0 + 0.666666666666666*G0_1_0_10_1_0_4_0_1 + 0.666666666666665*G0_1_0_10_1_0_5_0_1 - 0.666666666666666*G0_1_0_10_1_0_8_1_1 - 1.33333333333333*G0_1_0_10_1_0_9_1_0 - 0.666666666666665*G0_1_0_10_1_0_9_1_1 + 1.33333333333333*G0_1_0_10_1_0_10_1_0 + 0.666666666666666*G0_1_0_10_1_0_10_1_1 + 0.666666666666665*G0_1_0_10_1_0_11_1_1 - 0.666666666666667*G0_1_0_10_1_1_0_0_0 - 0.666666666666667*G0_1_0_10_1_1_0_0_1 - 0.666666666666666*G0_1_0_10_1_1_2_0_1 - 0.666666666666666*G0_1_0_10_1_1_3_0_0 + 0.666666666666666*G0_1_0_10_1_1_4_0_0 + 1.33333333333333*G0_1_0_10_1_1_4_0_1 + 0.666666666666667*G0_1_0_10_1_1_5_0_0 - 0.666666666666667*G0_1_0_10_1_1_6_1_0 - 0.666666666666667*G0_1_0_10_1_1_6_1_1 - 0.666666666666666*G0_1_0_10_1_1_8_1_1 - 0.666666666666666*G0_1_0_10_1_1_9_1_0 + 0.666666666666666*G0_1_0_10_1_1_10_1_0 + 1.33333333333333*G0_1_0_10_1_1_10_1_1 + 0.666666666666667*G0_1_0_10_1_1_11_1_0 - 0.666666666666667*G0_1_0_11_1_0_0_0_0 - 0.666666666666667*G0_1_0_11_1_0_0_0_1 - 0.666666666666666*G0_1_0_11_1_0_1_0_0 - 0.666666666666665*G0_1_0_11_1_0_3_0_1 + 0.666666666666667*G0_1_0_11_1_0_4_0_1 + 1.33333333333333*G0_1_0_11_1_0_5_0_0 + 0.666666666666666*G0_1_0_11_1_0_5_0_1 - 0.666666666666667*G0_1_0_11_1_0_6_1_0 - 0.666666666666667*G0_1_0_11_1_0_6_1_1 - 0.666666666666666*G0_1_0_11_1_0_7_1_0 - 0.666666666666665*G0_1_0_11_1_0_9_1_1 + 0.666666666666667*G0_1_0_11_1_0_10_1_1 + 1.33333333333333*G0_1_0_11_1_0_11_1_0 + 0.666666666666666*G0_1_0_11_1_0_11_1_1 - 0.666666666666666*G0_1_0_11_1_1_1_0_0 - 0.666666666666666*G0_1_0_11_1_1_3_0_0 - 1.33333333333333*G0_1_0_11_1_1_3_0_1 + 0.666666666666666*G0_1_0_11_1_1_4_0_0 + 0.666666666666666*G0_1_0_11_1_1_5_0_0 + 1.33333333333333*G0_1_0_11_1_1_5_0_1 - 0.666666666666666*G0_1_0_11_1_1_7_1_0 - 0.666666666666666*G0_1_0_11_1_1_9_1_0 - 1.33333333333333*G0_1_0_11_1_1_9_1_1 + 0.666666666666666*G0_1_0_11_1_1_10_1_0 + 0.666666666666666*G0_1_0_11_1_1_11_1_0 + 1.33333333333333*G0_1_0_11_1_1_11_1_1; + A[0] = A[21]; + A[22] = A[1]; + A[19] = 0.0; + A[16] = 0.0; + A[12] = A[33]; + A[27] = A[6]; + A[15] = 0.0; + A[32] = 0.0; + A[2] = A[23]; + } + + /// Tabulate the tensor for the contribution from a local cell + /// using the specified reference cell quadrature points/weights + virtual void tabulate_tensor(double* A, + const double * const * w, + const ufc::cell& c, + unsigned int num_quadrature_points, + const double * const * quadrature_points, + const double* quadrature_weights) const + { + throw std::runtime_error("Quadrature version of tabulate_tensor not available when using the FFC tensor representation."); + } + +}; + +/// This class defines the interface for the assembly of the global +/// tensor corresponding to a form with r + n arguments, that is, a +/// mapping +/// +/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R +/// +/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r +/// global tensor A is defined by +/// +/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn), +/// +/// where each argument Vj represents the application to the +/// sequence of basis functions of Vj and w1, w2, ..., wn are given +/// fixed functions (coefficients). + +class vector_laplacian_f2_p2_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + vector_laplacian_f2_p2_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~vector_laplacian_f2_p2_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(IndexSum(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1), Index(0)), {Index(0): 2, Index(1): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Argument(VectorElement('Lagrange', Cell('triangle', Space(2)), 1, 2, None), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(5), Index(4)), {Index(4): 2, Index(5): 2})), MultiIndex((Index(2), Index(3)), {Index(2): 2, Index(3): 2}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(3),), {Index(3): 2})), Product(IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 0), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), IndexSum(Indexed(SpatialDerivative(Coefficient(VectorElement('Lagrange', Cell('triangle', Space(2)), 2, 2, None), 1), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})), MultiIndex((Index(7),), {Index(7): 2})))), Measure('cell', 0, None))])"; + } + + /// Return the rank of the global tensor (r) + virtual unsigned int rank() const + { + return 2; + } + + /// Return the number of coefficients (n) + virtual unsigned int num_coefficients() const + { + return 2; + } + + /// Return the number of cell domains + virtual unsigned int num_cell_domains() const + { + return 1; + } + + /// Return the number of exterior facet domains + virtual unsigned int num_exterior_facet_domains() const + { + return 0; + } + + /// Return the number of interior facet domains + virtual unsigned int num_interior_facet_domains() const + { + return 0; + } + + /// Create a new finite element for argument function i + virtual ufc::finite_element* create_finite_element(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p2_q1_tensor_finite_element_1(); + break; + } + } + + return 0; + } + + /// Create a new dofmap for argument function i + virtual ufc::dofmap* create_dofmap(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_3(); + break; + } + case 1: + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_3(); + break; + } + case 2: + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_1(); + break; + } + case 3: + { + return new vector_laplacian_f2_p2_q1_tensor_dofmap_1(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new vector_laplacian_f2_p2_q1_tensor_cell_integral_0_0(); + break; + } + } + + return 0; + } + + /// Create a new exterior facet integral on sub domain i + virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const + { + return 0; + } + + /// Create a new interior facet integral on sub domain i + virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const + { + return 0; + } + +}; + +#endif -- 2.47.3